From patchwork Mon Oct 2 15:17:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefano Babic X-Patchwork-Id: 820557 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=googlegroups.com (client-ip=2a00:1450:400c:c0c::23d; helo=mail-wr0-x23d.google.com; envelope-from=swupdate+bncbaabbknrzhhakgqeopogalq@googlegroups.com; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=googlegroups.com header.i=@googlegroups.com header.b="nN64D/yx"; dkim-atps=neutral Received: from mail-wr0-x23d.google.com (mail-wr0-x23d.google.com [IPv6:2a00:1450:400c:c0c::23d]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3y5Qld2mcfz9t6x for ; Tue, 3 Oct 2017 02:18:04 +1100 (AEDT) Received: by mail-wr0-x23d.google.com with SMTP id n4sf1597148wrb.8 for ; Mon, 02 Oct 2017 08:18:04 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1506957482; cv=pass; d=google.com; s=arc-20160816; b=O3mhOjN+5VOO9sxwK3Yq0MHzaPJkjQZIiArIlIR84MgBc3uZHSPFJUvW7V6nU71cuU ICCm4224G6kdBZIHH2zU0XE21Nai9J8EuXdW98hAOoCcgln3TeQlo0MS08g3BF2zvWjb ctM8kIIJPC6+JvhiIY/qucppX+mVd7zwiy5nKqtTYR3Xi8VNsTnaphbOOFIsOyew7okt TNkFev/b4oPqRqan90oCV4zFbKSuC9twpkDtz8IVvQtZdLxqixccY76QT9k23Q/x6+YU 7sO44ZSRpmMrR8nkmum+YzZ7YJtStFykGL4w+Duu/tdVge0CsXWZYiVBzrNQglRmPEgz dLmw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:message-id:date:subject:cc:to:from :arc-authentication-results:arc-message-signature:mime-version :sender:dkim-signature:arc-authentication-results; bh=iG685kdrOyQyKGvvwhh6LXhe19D3KhVGhZuhmhLaO5w=; b=bmvYRXdKdmobcusxFHVwCBlPqbdSvlewwopMm9AFcxgRYHWfKIcyfggKoWmUt/ZJ6M AhcN5MqFA8ObIQn4tDPRBJOjn5rEMrguE38AftyiAIo5TYUohFcV7o5x51R2I+aN2Vnc CTySqUv4PjTPJ35oQOzYRd1xNb2zjPZXxgBx1HsjZXGzXHJeR9H+HNMvwdZbeJuMBC/j nZDvedeK4+WpBkYvY+tMXyMn0XHNJiztLkN1ik/AcvDY0fLYmISLL043Kg2e2w+YfTxb VPHOqNczwMr7NUH3GYP9AUODqOQp7DqenKSsIodp/eS3SC+k2xoSgaifI+op+OrW3zcn NtTg== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by best guess record for domain of sbabic@denx.de) smtp.mailfrom=sbabic@denx.de DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20161025; h=sender:mime-version:from:to:cc:subject:date:message-id :x-original-sender:x-original-authentication-results:precedence :mailing-list:list-id:list-post:list-help:list-archive :list-subscribe:list-unsubscribe; bh=iG685kdrOyQyKGvvwhh6LXhe19D3KhVGhZuhmhLaO5w=; b=nN64D/yx76pcPIAJry2Av4a1zmG+zr2E2biazKeUusQ+l/gGRGikzrPLy72Hysucl3 mdJ8R6LUcaLYoKDj3UGglxgHMyfkhdfzkDBvBVXd+Gf3NUa5cZlfGVCmxPlCWyIIHJXK FHt6TpzbCAzPl2U01Z5/httCtWTkGopo9UyrqVesbLmoOrx7Uw9MSIrts4Z/LCb8uulG FM5eG0Ti99UN1+T3beO7rrdTWccLKG4pNgnMeg+WCGCM/Mh2hWSoKIDpamGvbrNNUo43 6R5kCJAbJd/it/iwqcAN4iw39D9FMyrLxx/F7idA1iKu4GjL2UQ11n/S2B7twq5PIOJz qXjw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=sender:x-gm-message-state:mime-version:from:to:cc:subject:date :message-id:x-original-sender:x-original-authentication-results :precedence:mailing-list:list-id:x-spam-checked-in-group:list-post :list-help:list-archive:list-subscribe:list-unsubscribe; bh=iG685kdrOyQyKGvvwhh6LXhe19D3KhVGhZuhmhLaO5w=; b=pFmUUlZSlj6RnCo7jpLAL6gddLQ5c4lM0sAVUsHdea9vTLVMyz1XWJP6b1Z0/74AAR K0tvlwiEI59u5M7cDAqSqNhFQaDzOW+EQkFAeloTLFIaSwf8sj0CXlhObDA8W+EJFTY0 6m2dNbJhYFNIbRcds9s+/Ef0jejWc/WnGFBn+3MFhPRNh01p79Hw0/VL/ZOriWKW/Q1F x/GuParaVAbdpK98EIrMj3aquPVHQw9LPuYnXkzOmcLaiMfT+s0vpBBbEv6lWOLXy88e rO8dPgUrxnXL70WwZ1uAFnssVhP2eKoQgQt6l2zndyc7snaN0WX5NRUTymjTct8mNpH+ OFtA== Sender: swupdate@googlegroups.com X-Gm-Message-State: AHPjjUglhOPLnTUXYoAtiT5WPtyoH6neZXvqJAp3j20cApIZp9KEB4Pp F+39MeqlmnNRJ+1zNnCsBT0= X-Google-Smtp-Source: AOwi7QD8NKVNPTcjU2ealD2BF7jJPSDTV8UtcCXpx8gz947j4sk+UrbKzZ6iGRNbwCq+V9Ac86vz7w== X-Received: by 10.28.230.198 with SMTP id e67mr38918wmi.3.1506957481879; Mon, 02 Oct 2017 08:18:01 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: swupdate@googlegroups.com Received: by 10.223.188.18 with SMTP id s18ls3458736wrg.9.gmail; Mon, 02 Oct 2017 08:18:01 -0700 (PDT) X-Received: by 10.28.184.78 with SMTP id i75mr1984590wmf.30.1506957481485; Mon, 02 Oct 2017 08:18:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506957481; cv=none; d=google.com; s=arc-20160816; b=kFMOOvLMlEuO28cmNfDMC2Pwoa6ybCua/VnDWDEVzpbhu/Ekzq34jzJsRB6u36LAUF 7Jh/RYHGuAD6kcXbyJVhgjKNpZtNTXcBXCVkAjJDfIz4FfJ5aBTrp4f09s3Z+VveTA4w X0HetmGLkS8od6PCISUKS8iF7LezCX4XIR1bzItcOb7sijl06MyyF6FORUbMQjUenyGI qq3nteTiF6pAuGBAzFaaiHWFtUcdUB7vBNWCIyKvOk3dPquLJPQK9mG4HS9egmRDObEm Q99aHb0yrOYmxcQwQaOMuuESeOzep1zHQYD5ZC8s3yB6nmd1tRSzv5c9E2aVhX0jmeoR 0DZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:arc-authentication-results; bh=M5Hx66DUj5Y23R+kKWUjdsxE1Q1J5A0QjH87ehWnmT4=; b=fuDi8kY1SISzaMP2eAAvMoM47SECjq5UZtfCs9rLVm+h8I7RQ9CIOGR6qQLZ9RBtn+ uCYwveLrdIwPAtgVMDpVjuOIb3wWO8f64kd+kqbqBkVIeA/gQGOaq7sxyj+2aYzrWofU 55KRkcF03tERflfam1l6e9MboKc2eAnNUD9C71xyygEucL4sSKI0+OUd8aVEgppfXN+C SlxN4jmGpzHdv806xP1guUc+e15hsRydYp44Qfz8OguVl3T06TivWhfeYD0r8xrlvQui LlfONEm3g5+0Xv9nrEGf9RqbO1ojg+TBxVnht6q8iw9zgHqSFLA4F47HGEgy4rdDM7PE KSKQ== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by best guess record for domain of sbabic@denx.de) smtp.mailfrom=sbabic@denx.de Received: from mail-out.m-online.net (mail-out.m-online.net. [2001:a60:0:28:0:1:25:1]) by gmr-mx.google.com with ESMTPS id 196si475119wmk.4.2017.10.02.08.18.01 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Oct 2017 08:18:01 -0700 (PDT) Received-SPF: neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by best guess record for domain of sbabic@denx.de) client-ip=2001:a60:0:28:0:1:25:1; Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 3y5QlY1x1Wz1r16R; Mon, 2 Oct 2017 17:18:01 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 3y5QlY1j9Sz1qrlj; Mon, 2 Oct 2017 17:18:01 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id Jp6FrCNlilSQ; Mon, 2 Oct 2017 17:18:00 +0200 (CEST) Received: from babic.homelinux.org (host-88-217-136-221.customer.m-online.net [88.217.136.221]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPS; Mon, 2 Oct 2017 17:18:00 +0200 (CEST) Received: from localhost (mail.babic.homelinux.org [127.0.0.1]) by babic.homelinux.org (Postfix) with ESMTP id 9686145405F9; Mon, 2 Oct 2017 17:17:59 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at babic.homelinux.org Received: from babic.homelinux.org ([127.0.0.1]) by localhost (mail.babic.homelinux.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EyO_1zL_-7_Z; Mon, 2 Oct 2017 17:17:56 +0200 (CEST) Received: from papero.fritz.box (papero.fritz.box [192.168.178.132]) by babic.homelinux.org (Postfix) with ESMTP id E15DD45405AB; Mon, 2 Oct 2017 17:17:55 +0200 (CEST) From: Stefano Babic To: swupdate@googlegroups.com Cc: Stefano Babic Subject: [swupdate] [PATCH] handlers: associate each handler with a mask Date: Mon, 2 Oct 2017 17:17:53 +0200 Message-Id: <1506957473-1645-1-git-send-email-sbabic@denx.de> X-Mailer: git-send-email 2.7.4 X-Original-Sender: sbabic@denx.de X-Original-Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 2001:a60:0:28:0:1:25:1 is neither permitted nor denied by best guess record for domain of sbabic@denx.de) smtp.mailfrom=sbabic@denx.de Precedence: list Mailing-list: list swupdate@googlegroups.com; contact swupdate+owners@googlegroups.com List-ID: X-Spam-Checked-In-Group: swupdate@googlegroups.com X-Google-Group-Id: 605343134186 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Do not allow that handlers thought for a section can be defined in another section of sw-description. Scripts must be defined inside the "scripts" section and cannot be overridden. Up now, scripts could be defined even in the "files" and "images" by overriding the "type" argument. Signed-off-by: Stefano Babic --- core/handler.c | 3 +- core/parser.c | 83 ++++++++++++++++++++++++++------------- corelib/lua_interface.c | 3 +- handlers/archive_handler.c | 6 ++- handlers/boot_handler.c | 6 ++- handlers/flash_hamming1_handler.c | 3 +- handlers/flash_handler.c | 3 +- handlers/lua_scripthandler.c | 2 +- handlers/raw_handler.c | 6 ++- handlers/remote_handler.c | 3 +- handlers/shell_scripthandler.c | 9 +++-- handlers/ubivol_handler.c | 6 ++- include/handler.h | 18 ++++++++- 13 files changed, 106 insertions(+), 45 deletions(-) diff --git a/core/handler.c b/core/handler.c index 168dd80..7e9f3ed 100644 --- a/core/handler.c +++ b/core/handler.c @@ -33,7 +33,7 @@ struct installer_handler supported_types[MAX_INSTALLER_HANDLER]; static unsigned long nr_installers = 0; int register_handler(const char *desc, - handler installer, void *data) + handler installer, HANDLER_MASK mask, void *data) { if (nr_installers > MAX_INSTALLER_HANDLER - 1) @@ -43,6 +43,7 @@ int register_handler(const char *desc, sizeof(supported_types[nr_installers].desc)); supported_types[nr_installers].installer = installer; supported_types[nr_installers].data = data; + supported_types[nr_installers].mask = mask; nr_installers++; return 0; diff --git a/core/parser.c b/core/parser.c index d31d322..ce00bec 100644 --- a/core/parser.c +++ b/core/parser.c @@ -63,6 +63,48 @@ static int check_missing_hash(struct imglist *list) } #endif +static int check_handler(struct img_type *item, unsigned int mask, const char *desc) +{ + struct installer_handler *hnd; + + hnd = find_handler(item); + if (!hnd) { + ERROR("feature '%s' required for " + "'%s' in %s is absent!", + item->type, item->fname, + SW_DESCRIPTION_FILENAME); + return -EINVAL; + } + + if (!(hnd->mask & mask)) { + ERROR("feature '%s' is not allowed for " + "'%s' in %s is absent!", + item->type, desc, + SW_DESCRIPTION_FILENAME); + return -EINVAL; + } + + return 0; +} + +static int check_handler_list(struct imglist *list, unsigned int allowedmask, + const char *desc) +{ + struct img_type *item; + int ret; + if (!LIST_EMPTY(list)) { + LIST_FOREACH(item, list, next) + { + ret = check_handler(item, allowedmask, desc); + + if (ret < 0) + return ret; + } + } + + return 0; +} + int parse(struct swupdate_cfg *sw, const char *descfile) { int ret = -1; @@ -85,39 +127,26 @@ int parse(struct swupdate_cfg *sw, const char *descfile) return ret; } - struct img_type *item; - if (!LIST_EMPTY(&sw->scripts)) { - LIST_FOREACH(item, &sw->scripts, next) - { - if (!find_handler(item)) { - ERROR("feature '%s' required for script " - "'%s' in %s is absent!", - item->type, item->fname, - SW_DESCRIPTION_FILENAME); - return -1; - } - } - } - if (!LIST_EMPTY(&sw->images)) { - LIST_FOREACH(item, &sw->images, next) - { - if (!find_handler(item)) { - ERROR("feature '%s' required for image " - "'%s' in %s is absent!", - item->type, item->fname, - SW_DESCRIPTION_FILENAME); - return -1; - } - } - } + ret = check_handler_list(&sw->scripts, SCRIPT_HANDLER, "scripts"); + ret |= check_handler_list(&sw->images, IMAGE_HANDLER | FILE_HANDLER, + "images / files"); + ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER, + "partitions"); + if (ret) + return -EINVAL; + + /* + * Bootloader is slightly different, it has no image + * but a list of variables + */ struct img_type item_uboot = {.type = "uboot"}; struct img_type item_bootloader = {.type = "bootenv"}; if (!LIST_EMPTY(&sw->bootloader) && - (!find_handler(&item_uboot) && + (!find_handler(&item_uboot) && !find_handler(&item_bootloader))) { ERROR("bootloader support absent but %s has bootloader section!", SW_DESCRIPTION_FILENAME); - return -1; + return -EINVAL; } #ifdef CONFIG_SIGNED_IMAGES diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c index 0553c1d..73458ba 100644 --- a/corelib/lua_interface.c +++ b/corelib/lua_interface.c @@ -463,7 +463,8 @@ static int l_register_handler( lua_State *L ) { *l_func_ref = luaL_ref (L, LUA_REGISTRYINDEX); /* pop the arguments from the stack */ lua_pop (L, 2); - register_handler(handler_desc,l_handler_wrapper,l_func_ref); + register_handler(handler_desc, l_handler_wrapper, + ANY_HANDLER, l_func_ref); return 0; } } diff --git a/handlers/archive_handler.c b/handlers/archive_handler.c index f86d1f2..ceb60a3 100644 --- a/handlers/archive_handler.c +++ b/handlers/archive_handler.c @@ -253,12 +253,14 @@ static int install_archive_image(struct img_type *img, __attribute__((constructor)) void archive_handler(void) { - register_handler("archive", install_archive_image, NULL); + register_handler("archive", install_archive_image, + IMAGE_HANDLER | FILE_HANDLER, NULL); } /* This is an alias for the parsers */ __attribute__((constructor)) void untar_handler(void) { - register_handler("tar", install_archive_image, NULL); + register_handler("tar", install_archive_image, + IMAGE_HANDLER | FILE_HANDLER, NULL); } diff --git a/handlers/boot_handler.c b/handlers/boot_handler.c index 86c55d0..8cda3f6 100644 --- a/handlers/boot_handler.c +++ b/handlers/boot_handler.c @@ -75,10 +75,12 @@ static int install_boot_environment(struct img_type *img, __attribute__((constructor)) static void uboot_handler(void) { - register_handler("uboot", install_boot_environment, NULL); + register_handler("uboot", install_boot_environment, + BOOTLOADER_HANDLER, NULL); } __attribute__((constructor)) static void boot_handler(void) { - register_handler("bootloader", install_boot_environment, NULL); + register_handler("bootloader", install_boot_environment, + BOOTLOADER_HANDLER, NULL); } diff --git a/handlers/flash_hamming1_handler.c b/handlers/flash_hamming1_handler.c index 8b54d3a..511155e 100644 --- a/handlers/flash_hamming1_handler.c +++ b/handlers/flash_hamming1_handler.c @@ -331,5 +331,6 @@ static int install_flash_hamming_image(struct img_type *img, __attribute__((constructor)) void flash_1bit_hamming_handler(void) { - register_handler("flash-hamming1", install_flash_hamming_image, (void *)1); + register_handler("flash-hamming1", install_flash_hamming_image, + IMAGE_HANDLER | FILE_HANDLER, (void *)1); } diff --git a/handlers/flash_handler.c b/handlers/flash_handler.c index ff27aa7..a244b37 100644 --- a/handlers/flash_handler.c +++ b/handlers/flash_handler.c @@ -349,5 +349,6 @@ static int install_flash_image(struct img_type *img, __attribute__((constructor)) void flash_handler(void) { - register_handler("flash", install_flash_image, NULL); + register_handler("flash", install_flash_image, + IMAGE_HANDLER | FILE_HANDLER, NULL); } diff --git a/handlers/lua_scripthandler.c b/handlers/lua_scripthandler.c index 1793878..e9cfd46 100644 --- a/handlers/lua_scripthandler.c +++ b/handlers/lua_scripthandler.c @@ -123,5 +123,5 @@ static int start_lua_script(struct img_type *img, void *data) __attribute__((constructor)) static void lua_handler(void) { - register_handler("lua", start_lua_script, NULL); + register_handler("lua", start_lua_script, SCRIPT_HANDLER, NULL); } diff --git a/handlers/raw_handler.c b/handlers/raw_handler.c index 91e9bb7..0893ecc 100644 --- a/handlers/raw_handler.c +++ b/handlers/raw_handler.c @@ -106,11 +106,13 @@ static int install_raw_file(struct img_type *img, __attribute__((constructor)) void raw_handler(void) { - register_handler("raw", install_raw_image, NULL); + register_handler("raw", install_raw_image, + IMAGE_HANDLER, NULL); } __attribute__((constructor)) void raw_filecopy_handler(void) { - register_handler("rawfile", install_raw_file, NULL); + register_handler("rawfile", install_raw_file, + FILE_HANDLER, NULL); } diff --git a/handlers/remote_handler.c b/handlers/remote_handler.c index 59661c0..47535da 100644 --- a/handlers/remote_handler.c +++ b/handlers/remote_handler.c @@ -211,5 +211,6 @@ cleanup: __attribute__((constructor)) void remote_handler(void) { - register_handler("remote", install_remote_image, NULL); + register_handler("remote", install_remote_image, + IMAGE_HANDLER, NULL); } diff --git a/handlers/shell_scripthandler.c b/handlers/shell_scripthandler.c index 9095a5f..016c246 100644 --- a/handlers/shell_scripthandler.c +++ b/handlers/shell_scripthandler.c @@ -130,17 +130,20 @@ static int start_postinstall_script(struct img_type *img, void *data) __attribute__((constructor)) static void shell_handler(void) { - register_handler("shellscript", start_shell_script, NULL); + register_handler("shellscript", start_shell_script, + SCRIPT_HANDLER, NULL); } __attribute__((constructor)) static void shell_preinstall_handler(void) { - register_handler("preinstall", start_preinstall_script, NULL); + register_handler("preinstall", start_preinstall_script, + SCRIPT_HANDLER, NULL); } __attribute__((constructor)) static void shell_postinstall_handler(void) { - register_handler("postinstall", start_postinstall_script, NULL); + register_handler("postinstall", start_postinstall_script, + SCRIPT_HANDLER, NULL); } diff --git a/handlers/ubivol_handler.c b/handlers/ubivol_handler.c index 0e262b6..3018b5b 100644 --- a/handlers/ubivol_handler.c +++ b/handlers/ubivol_handler.c @@ -251,6 +251,8 @@ static int adjust_volume(struct img_type *cfg, __attribute__((constructor)) void ubi_handler(void) { - register_handler("ubivol", install_ubivol_image, NULL); - register_handler("ubipartition", adjust_volume, NULL); + register_handler("ubivol", install_ubivol_image, + IMAGE_HANDLER, NULL); + register_handler("ubipartition", adjust_volume, + PARTITION_HANDLER, NULL); } diff --git a/include/handler.h b/include/handler.h index 359be71..0659ff6 100644 --- a/include/handler.h +++ b/include/handler.h @@ -29,15 +29,31 @@ typedef enum { POSTINSTALL } script_fn ; +/* + * Use enum for mask to easy transfer to LUA + * scripts + */ +typedef enum { + IMAGE_HANDLER = 1, + FILE_HANDLER = 2, + SCRIPT_HANDLER = 4, + BOOTLOADER_HANDLER = 8, + PARTITION_HANDLER = 16 +} HANDLER_MASK; + +#define ANY_HANDLER (IMAGE_HANDLER | FILE_HANDLER | SCRIPT_HANDLER | \ + BOOTLOADER_HANDLER | PARTITION_HANDLER) + typedef int (*handler)(struct img_type *img, void *data); struct installer_handler{ char desc[64]; handler installer; void *data; + unsigned int mask; }; int register_handler(const char *desc, - handler installer, void *data); + handler installer, HANDLER_MASK mask, void *data); struct installer_handler *find_handler(struct img_type *img); void print_registered_handlers(void);