[1/2] Allow again bootloader scripts

Message ID 1515775206-9174-1-git-send-email-sbabic@denx.de
State Changes Requested
Headers show
Series
  • [1/2] Allow again bootloader scripts
Related show

Commit Message

Stefano Babic Jan. 12, 2018, 4:40 p.m.
commit ff12cd69445c0f49d44ad0b75dea6f6ec1b0e449 forbids to use a bootloader
script in the "images" section of sw-description. This avoids to set bootloader's
variables in the middle of an installation that can brick the device.
However, having a script is often much more comfortable as a list of couple
<name, value> inside sw-description. This allows again to have bootloader scripts,
but they must be inserted in the "bootenv" section of sw-description.

Signed-off-by: Stefano Babic <sbabic@denx.de>
---
 core/parser.c              |   2 +
 corelib/installer.c        | 108 +++++++++++++++++++++++++++++----------------
 corelib/stream_interface.c |  24 ++++++++--
 include/installer.h        |   1 -
 include/swupdate.h         |   1 +
 parser/parser.c            |  44 +++++++++++++-----
 6 files changed, 126 insertions(+), 54 deletions(-)

Comments

Stefan Herbrechtsmeier Jan. 12, 2018, 7:34 p.m. | #1
Hi Stefano,

Am 12.01.2018 um 17:40 schrieb Stefano Babic:
> commit ff12cd69445c0f49d44ad0b75dea6f6ec1b0e449 forbids to use a bootloader
> script in the "images" section of sw-description. This avoids to set bootloader's
> variables in the middle of an installation that can brick the device.
> However, having a script is often much more comfortable as a list of couple
> <name, value> inside sw-description. This allows again to have bootloader scripts,
> but they must be inserted in the "bootenv" section of sw-description.

What is the different between a script and a bootloader script?

> Signed-off-by: Stefano Babic <sbabic@denx.de>
> ---
>   core/parser.c              |   2 +
>   corelib/installer.c        | 108 +++++++++++++++++++++++++++++----------------
>   corelib/stream_interface.c |  24 ++++++++--
>   include/installer.h        |   1 -
>   include/swupdate.h         |   1 +
>   parser/parser.c            |  44 +++++++++++++-----
>   6 files changed, 126 insertions(+), 54 deletions(-)
>
> diff --git a/core/parser.c b/core/parser.c
> index a1232bd..cdfbea8 100644
> --- a/core/parser.c
> +++ b/core/parser.c
> @@ -147,6 +147,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile)
>   					"images / files");
>   	ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER,
>   					"partitions");
> +	ret |= check_handler_list(&sw->bootscripts, BOOTLOADER_HANDLER,
> +					"bootloader");
>   	if (ret)
>   		return -EINVAL;
>   
> diff --git a/corelib/installer.c b/corelib/installer.c
> index fc3011e..9a67399 100644
> --- a/corelib/installer.c
> +++ b/corelib/installer.c
> @@ -233,6 +233,27 @@ static int prepare_boot_script(struct swupdate_cfg *cfg, const char *script)
>   	return ret;
>   }
>   
> +static int run_prepost_scripts(struct imglist *list, script_fn type)
> +{
> +	int ret;
> +	struct img_type *img;
> +	struct installer_handler *hnd;
> +
> +	/* Scripts must be run before installing images */
> +	LIST_FOREACH(img, list, next) {
> +		if (!img->is_script)
> +			continue;
> +		hnd = find_handler(img);
> +		if (hnd) {
> +			ret = hnd->installer(img, &type);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
>   static int update_bootloader_env(void)
>   {
>   	int ret = 0;
> @@ -291,13 +312,14 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile)
>   	/* Extract all scripts, preinstall scripts must be run now */
>   	const char* tmpdir_scripts = get_tmpdirscripts();
>   	ret = extract_scripts(fdsw, &sw->scripts, fromfile);
> +	ret |= extract_scripts(fdsw, &sw->bootscripts, fromfile);
>   	if (ret) {
>   		ERROR("extracting script to %s failed", tmpdir_scripts);
>   		return ret;
>   	}
>   
>   	/* Scripts must be run before installing images */
> -	ret = run_prepost_scripts(sw, PREINSTALL);
> +	ret = run_prepost_scripts(&sw->scripts, PREINSTALL);
>   	if (ret) {
>   		ERROR("execute preinstall scripts failed");
>   		return ret;
> @@ -388,7 +410,7 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile)
>   
>   	}
>   
> -	ret = run_prepost_scripts(sw, POSTINSTALL);
> +	ret = run_prepost_scripts(&sw->scripts, POSTINSTALL);
>   	if (ret) {
>   		ERROR("execute postinstall scripts failed");
>   		return ret;
> @@ -397,31 +419,11 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile)
>   	if (!LIST_EMPTY(&sw->bootloader))
>   		ret = update_bootloader_env();
>   
> -	return ret;
> -}
> -
> -int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type)
> -{
> -	int ret;
> -	struct img_type *img;
> -	struct installer_handler *hnd;
> -
> -	/* Scripts must be run before installing images */
> -	LIST_FOREACH(img, &sw->scripts, next) {
> -		if (!img->is_script)
> -			continue;
> -		hnd = find_handler(img);
> -		if (hnd) {
> -			ret = hnd->installer(img, &type);
> -			if (ret)
> -				return ret;
> -		}
> -	}
> +	ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL);
>   
> -	return 0;
> +	return ret;
>   }
>   
> -
>   static void remove_sw_file(char __attribute__ ((__unused__)) *fname)
>   {
>   #ifndef CONFIG_NOCLEANUP
> @@ -430,11 +432,42 @@ static void remove_sw_file(char __attribute__ ((__unused__)) *fname)
>   #endif
>   }
>   
> +static void cleaup_img_entry(struct img_type *img)
> +{
> +	char *fn;
> +	int i;
> +	const char *tmp;
> +
> +	if (img->fname[0]) {
> +
> +		for (i = 0; i < 2; i++) {
> +			switch(i) {
> +			case 0:
> +				tmp = get_tmpdirscripts();
> +				break;
> +			case 1:
> +				tmp = get_tmpdir();
> +				break;
> +			}

Maybe you could replace the switch by an array and use the ARRAY_SIZE 
instead of the fix number:
const char *tmp[] = {get_tmpdirscripts(), get_tmpdir()}

> +
> +			if (asprintf(&fn, "%s%s", tmp, img->fname) == ENOMEM_ASPRINTF) {
> +				ERROR("Path too long: %s%s", tmp, img->fname);
> +			} else {
> +				remove_sw_file(fn);
> +				free(fn);
> +			}
> +		}
> +	}
> +	dict_drop_db(&img->properties);
> +}
> +
>   void cleanup_files(struct swupdate_cfg *software) {
>   	char fn[64];
>   	struct img_type *img;
>   	struct hw_type *hw;
>   	const char* TMPDIR = get_tmpdir();
> +	int count;
> +	struct imglist *list;
>   
>   	LIST_FOREACH(img, &software->images, next) {
>   		if (img->fname[0]) {
> @@ -447,22 +480,19 @@ void cleanup_files(struct swupdate_cfg *software) {
>   		LIST_REMOVE(img, next);
>   		free(img);
>   	}
> -	LIST_FOREACH(img, &software->scripts, next) {
> -		if (img->fname[0]) {
> -			if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdirscripts(),
> -				     img->fname) >= (int)sizeof(fn)) {
> -				ERROR("Path too long: %s%s", get_tmpdirscripts(), img->fname);
> -			}
> -			remove_sw_file(fn);
> -			if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdir(),
> -				     img->fname) >= (int)sizeof(fn)) {
> -				ERROR("Path too long: %s%s", TMPDIR, img->fname);
> -			}
> -			remove_sw_file(fn);
> +
> +	for (count = 0; count < 2; count++) {
> +		if (count == 0)
> +			list = &software->scripts;
> +		else
> +			list = &software->bootscripts;

Array?

> +
> +		LIST_FOREACH(img, list, next) {
> +			cleaup_img_entry(img);
> +
> +			LIST_REMOVE(img, next);
> +			free(img);
>   		}
> -		dict_drop_db(&img->properties);
> -		LIST_REMOVE(img, next);
> -		free(img);
>   	}
>   
>   	dict_drop_db(&software->bootloader);
> diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c
> index a200d7e..99b8329 100644
> --- a/corelib/stream_interface.c
> +++ b/corelib/stream_interface.c
> @@ -186,20 +186,38 @@ static int extract_files(int fd, struct swupdate_cfg *software)
>   				break;
>   			}
>   
> -			skip = check_if_required(&software->images, &fdh,
> +			int i;
> +
> +			for (i = 0; i < 3; i++) {
> +				switch(i) {
> +				case 0:
> +					skip = check_if_required(&software->images, &fdh,
>   						&software->installed_sw_list,
>   						get_tmpdir(),
>   						&img);
> -			if (skip == SKIP_FILE) {
> +					break;
>   				/*
>   				 *  Check for script, but scripts are not checked
>   				 *  for version
>   				 */
> -				skip = check_if_required(&software->scripts, &fdh,
> +				case 1:
> +					skip = check_if_required(&software->scripts, &fdh,
> +							NULL,
> +							get_tmpdir(),
> +							&img);
> +					break;
> +				case 2:
> +					skip = check_if_required(&software->bootscripts, &fdh,
>   							NULL,
>   							get_tmpdir(),
>   							&img);
> +					break;
> +				}

Array?

> +
> +				if (skip != SKIP_FILE)
> +					break;
>   			}
> +
>   			TRACE("Found file:\n\tfilename %s\n\tsize %u %s",
>   				fdh.filename,
>   				(unsigned int)fdh.size,

[snip]

Best regards
   Stefan
Stefano Babic Jan. 13, 2018, 3:22 p.m. | #2
Hi Stefan,

On 12/01/2018 20:34, Stefan Herbrechtsmeier wrote:
> Hi Stefano,

> 

> Am 12.01.2018 um 17:40 schrieb Stefano Babic:

>> commit ff12cd69445c0f49d44ad0b75dea6f6ec1b0e449 forbids to use a

>> bootloader

>> script in the "images" section of sw-description. This avoids to set

>> bootloader's

>> variables in the middle of an installation that can brick the device.

>> However, having a script is often much more comfortable as a list of

>> couple

>> <name, value> inside sw-description. This allows again to have

>> bootloader scripts,

>> but they must be inserted in the "bootenv" section of sw-description.

> 

> What is the different between a script and a bootloader script?

> 


A regular script in SWupdate is a shell or LUA script. A bootloader
script is not an executable file, but in sense of U-Boot's introduced
scripts (I know, I am guilty for this nomenclature because I introduced
this in U-Boot).

A bootloader script is just a file with coules <name> <value> entries, like:
	alpha	1
	beta	2
	gamma	3

A such file can be interpreted by u-boot's environment utility fw_setenv
if the parmeter "-s" is passed.

SWUpdate integrates this functionality and it is extended for other
bootloader, too. A bootscript can be for U-Boot or GRUB (and now for
EFIBootGuard).

>> Signed-off-by: Stefano Babic <sbabic@denx.de>

>> ---

>>   core/parser.c              |   2 +

>>   corelib/installer.c        | 108

>> +++++++++++++++++++++++++++++----------------

>>   corelib/stream_interface.c |  24 ++++++++--

>>   include/installer.h        |   1 -

>>   include/swupdate.h         |   1 +

>>   parser/parser.c            |  44 +++++++++++++-----

>>   6 files changed, 126 insertions(+), 54 deletions(-)

>>

>> diff --git a/core/parser.c b/core/parser.c

>> index a1232bd..cdfbea8 100644

>> --- a/core/parser.c

>> +++ b/core/parser.c

>> @@ -147,6 +147,8 @@ int parse(struct swupdate_cfg *sw, const char

>> *descfile)

>>                       "images / files");

>>       ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER,

>>                       "partitions");

>> +    ret |= check_handler_list(&sw->bootscripts, BOOTLOADER_HANDLER,

>> +                    "bootloader");

>>       if (ret)

>>           return -EINVAL;

>>   diff --git a/corelib/installer.c b/corelib/installer.c

>> index fc3011e..9a67399 100644

>> --- a/corelib/installer.c

>> +++ b/corelib/installer.c

>> @@ -233,6 +233,27 @@ static int prepare_boot_script(struct

>> swupdate_cfg *cfg, const char *script)

>>       return ret;

>>   }

>>   +static int run_prepost_scripts(struct imglist *list, script_fn type)

>> +{

>> +    int ret;

>> +    struct img_type *img;

>> +    struct installer_handler *hnd;

>> +

>> +    /* Scripts must be run before installing images */

>> +    LIST_FOREACH(img, list, next) {

>> +        if (!img->is_script)

>> +            continue;

>> +        hnd = find_handler(img);

>> +        if (hnd) {

>> +            ret = hnd->installer(img, &type);

>> +            if (ret)

>> +                return ret;

>> +        }

>> +    }

>> +

>> +    return 0;

>> +}

>> +

>>   static int update_bootloader_env(void)

>>   {

>>       int ret = 0;

>> @@ -291,13 +312,14 @@ int install_images(struct swupdate_cfg *sw, int

>> fdsw, int fromfile)

>>       /* Extract all scripts, preinstall scripts must be run now */

>>       const char* tmpdir_scripts = get_tmpdirscripts();

>>       ret = extract_scripts(fdsw, &sw->scripts, fromfile);

>> +    ret |= extract_scripts(fdsw, &sw->bootscripts, fromfile);

>>       if (ret) {

>>           ERROR("extracting script to %s failed", tmpdir_scripts);

>>           return ret;

>>       }

>>         /* Scripts must be run before installing images */

>> -    ret = run_prepost_scripts(sw, PREINSTALL);

>> +    ret = run_prepost_scripts(&sw->scripts, PREINSTALL);

>>       if (ret) {

>>           ERROR("execute preinstall scripts failed");

>>           return ret;

>> @@ -388,7 +410,7 @@ int install_images(struct swupdate_cfg *sw, int

>> fdsw, int fromfile)

>>         }

>>   -    ret = run_prepost_scripts(sw, POSTINSTALL);

>> +    ret = run_prepost_scripts(&sw->scripts, POSTINSTALL);

>>       if (ret) {

>>           ERROR("execute postinstall scripts failed");

>>           return ret;

>> @@ -397,31 +419,11 @@ int install_images(struct swupdate_cfg *sw, int

>> fdsw, int fromfile)

>>       if (!LIST_EMPTY(&sw->bootloader))

>>           ret = update_bootloader_env();

>>   -    return ret;

>> -}

>> -

>> -int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type)

>> -{

>> -    int ret;

>> -    struct img_type *img;

>> -    struct installer_handler *hnd;

>> -

>> -    /* Scripts must be run before installing images */

>> -    LIST_FOREACH(img, &sw->scripts, next) {

>> -        if (!img->is_script)

>> -            continue;

>> -        hnd = find_handler(img);

>> -        if (hnd) {

>> -            ret = hnd->installer(img, &type);

>> -            if (ret)

>> -                return ret;

>> -        }

>> -    }

>> +    ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL);

>>   -    return 0;

>> +    return ret;

>>   }

>>   -

>>   static void remove_sw_file(char __attribute__ ((__unused__)) *fname)

>>   {

>>   #ifndef CONFIG_NOCLEANUP

>> @@ -430,11 +432,42 @@ static void remove_sw_file(char __attribute__

>> ((__unused__)) *fname)

>>   #endif

>>   }

>>   +static void cleaup_img_entry(struct img_type *img)

>> +{

>> +    char *fn;

>> +    int i;

>> +    const char *tmp;

>> +

>> +    if (img->fname[0]) {

>> +

>> +        for (i = 0; i < 2; i++) {

>> +            switch(i) {

>> +            case 0:

>> +                tmp = get_tmpdirscripts();

>> +                break;

>> +            case 1:

>> +                tmp = get_tmpdir();

>> +                break;

>> +            }

> 

> Maybe you could replace the switch by an array and use the ARRAY_SIZE

> instead of the fix number:

> const char *tmp[] = {get_tmpdirscripts(), get_tmpdir()}


I'll do in V2, thanks.

> 

>> +

>> +            if (asprintf(&fn, "%s%s", tmp, img->fname) ==

>> ENOMEM_ASPRINTF) {

>> +                ERROR("Path too long: %s%s", tmp, img->fname);

>> +            } else {

>> +                remove_sw_file(fn);

>> +                free(fn);

>> +            }

>> +        }

>> +    }

>> +    dict_drop_db(&img->properties);

>> +}

>> +

>>   void cleanup_files(struct swupdate_cfg *software) {

>>       char fn[64];

>>       struct img_type *img;

>>       struct hw_type *hw;

>>       const char* TMPDIR = get_tmpdir();

>> +    int count;

>> +    struct imglist *list;

>>         LIST_FOREACH(img, &software->images, next) {

>>           if (img->fname[0]) {

>> @@ -447,22 +480,19 @@ void cleanup_files(struct swupdate_cfg *software) {

>>           LIST_REMOVE(img, next);

>>           free(img);

>>       }

>> -    LIST_FOREACH(img, &software->scripts, next) {

>> -        if (img->fname[0]) {

>> -            if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdirscripts(),

>> -                     img->fname) >= (int)sizeof(fn)) {

>> -                ERROR("Path too long: %s%s", get_tmpdirscripts(),

>> img->fname);

>> -            }

>> -            remove_sw_file(fn);

>> -            if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdir(),

>> -                     img->fname) >= (int)sizeof(fn)) {

>> -                ERROR("Path too long: %s%s", TMPDIR, img->fname);

>> -            }

>> -            remove_sw_file(fn);

>> +

>> +    for (count = 0; count < 2; count++) {

>> +        if (count == 0)

>> +            list = &software->scripts;

>> +        else

>> +            list = &software->bootscripts;

> 

> Array?

> 

>> +

>> +        LIST_FOREACH(img, list, next) {

>> +            cleaup_img_entry(img);

>> +

>> +            LIST_REMOVE(img, next);

>> +            free(img);

>>           }

>> -        dict_drop_db(&img->properties);

>> -        LIST_REMOVE(img, next);

>> -        free(img);

>>       }

>>         dict_drop_db(&software->bootloader);

>> diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c

>> index a200d7e..99b8329 100644

>> --- a/corelib/stream_interface.c

>> +++ b/corelib/stream_interface.c

>> @@ -186,20 +186,38 @@ static int extract_files(int fd, struct

>> swupdate_cfg *software)

>>                   break;

>>               }

>>   -            skip = check_if_required(&software->images, &fdh,

>> +            int i;

>> +

>> +            for (i = 0; i < 3; i++) {

>> +                switch(i) {

>> +                case 0:

>> +                    skip = check_if_required(&software->images, &fdh,

>>                           &software->installed_sw_list,

>>                           get_tmpdir(),

>>                           &img);

>> -            if (skip == SKIP_FILE) {

>> +                    break;

>>                   /*

>>                    *  Check for script, but scripts are not checked

>>                    *  for version

>>                    */

>> -                skip = check_if_required(&software->scripts, &fdh,

>> +                case 1:

>> +                    skip = check_if_required(&software->scripts, &fdh,

>> +                            NULL,

>> +                            get_tmpdir(),

>> +                            &img);

>> +                    break;

>> +                case 2:

>> +                    skip = check_if_required(&software->bootscripts,

>> &fdh,

>>                               NULL,

>>                               get_tmpdir(),

>>                               &img);

>> +                    break;

>> +                }

> 

> Array?

> 

>> +

>> +                if (skip != SKIP_FILE)

>> +                    break;

>>               }

>> +

>>               TRACE("Found file:\n\tfilename %s\n\tsize %u %s",

>>                   fdh.filename,

>>                   (unsigned int)fdh.size,

> 

> [snip]

> 

> Best regards

>   Stefan

> 


Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
=====================================================================

Patch

diff --git a/core/parser.c b/core/parser.c
index a1232bd..cdfbea8 100644
--- a/core/parser.c
+++ b/core/parser.c
@@ -147,6 +147,8 @@  int parse(struct swupdate_cfg *sw, const char *descfile)
 					"images / files");
 	ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER,
 					"partitions");
+	ret |= check_handler_list(&sw->bootscripts, BOOTLOADER_HANDLER,
+					"bootloader");
 	if (ret)
 		return -EINVAL;
 
diff --git a/corelib/installer.c b/corelib/installer.c
index fc3011e..9a67399 100644
--- a/corelib/installer.c
+++ b/corelib/installer.c
@@ -233,6 +233,27 @@  static int prepare_boot_script(struct swupdate_cfg *cfg, const char *script)
 	return ret;
 }
 
+static int run_prepost_scripts(struct imglist *list, script_fn type)
+{
+	int ret;
+	struct img_type *img;
+	struct installer_handler *hnd;
+
+	/* Scripts must be run before installing images */
+	LIST_FOREACH(img, list, next) {
+		if (!img->is_script)
+			continue;
+		hnd = find_handler(img);
+		if (hnd) {
+			ret = hnd->installer(img, &type);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int update_bootloader_env(void)
 {
 	int ret = 0;
@@ -291,13 +312,14 @@  int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile)
 	/* Extract all scripts, preinstall scripts must be run now */
 	const char* tmpdir_scripts = get_tmpdirscripts();
 	ret = extract_scripts(fdsw, &sw->scripts, fromfile);
+	ret |= extract_scripts(fdsw, &sw->bootscripts, fromfile);
 	if (ret) {
 		ERROR("extracting script to %s failed", tmpdir_scripts);
 		return ret;
 	}
 
 	/* Scripts must be run before installing images */
-	ret = run_prepost_scripts(sw, PREINSTALL);
+	ret = run_prepost_scripts(&sw->scripts, PREINSTALL);
 	if (ret) {
 		ERROR("execute preinstall scripts failed");
 		return ret;
@@ -388,7 +410,7 @@  int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile)
 
 	}
 
-	ret = run_prepost_scripts(sw, POSTINSTALL);
+	ret = run_prepost_scripts(&sw->scripts, POSTINSTALL);
 	if (ret) {
 		ERROR("execute postinstall scripts failed");
 		return ret;
@@ -397,31 +419,11 @@  int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile)
 	if (!LIST_EMPTY(&sw->bootloader))
 		ret = update_bootloader_env();
 
-	return ret;
-}
-
-int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type)
-{
-	int ret;
-	struct img_type *img;
-	struct installer_handler *hnd;
-
-	/* Scripts must be run before installing images */
-	LIST_FOREACH(img, &sw->scripts, next) {
-		if (!img->is_script)
-			continue;
-		hnd = find_handler(img);
-		if (hnd) {
-			ret = hnd->installer(img, &type);
-			if (ret)
-				return ret;
-		}
-	}
+	ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL);
 
-	return 0;
+	return ret;
 }
 
-
 static void remove_sw_file(char __attribute__ ((__unused__)) *fname)
 {
 #ifndef CONFIG_NOCLEANUP
@@ -430,11 +432,42 @@  static void remove_sw_file(char __attribute__ ((__unused__)) *fname)
 #endif
 }
 
+static void cleaup_img_entry(struct img_type *img)
+{
+	char *fn;
+	int i;
+	const char *tmp;
+
+	if (img->fname[0]) {
+
+		for (i = 0; i < 2; i++) {
+			switch(i) {
+			case 0:
+				tmp = get_tmpdirscripts();
+				break;
+			case 1:
+				tmp = get_tmpdir();
+				break;
+			}
+
+			if (asprintf(&fn, "%s%s", tmp, img->fname) == ENOMEM_ASPRINTF) {
+				ERROR("Path too long: %s%s", tmp, img->fname);
+			} else {
+				remove_sw_file(fn);
+				free(fn);
+			}
+		}
+	}
+	dict_drop_db(&img->properties);
+}
+
 void cleanup_files(struct swupdate_cfg *software) {
 	char fn[64];
 	struct img_type *img;
 	struct hw_type *hw;
 	const char* TMPDIR = get_tmpdir();
+	int count;
+	struct imglist *list;
 
 	LIST_FOREACH(img, &software->images, next) {
 		if (img->fname[0]) {
@@ -447,22 +480,19 @@  void cleanup_files(struct swupdate_cfg *software) {
 		LIST_REMOVE(img, next);
 		free(img);
 	}
-	LIST_FOREACH(img, &software->scripts, next) {
-		if (img->fname[0]) {
-			if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdirscripts(),
-				     img->fname) >= (int)sizeof(fn)) {
-				ERROR("Path too long: %s%s", get_tmpdirscripts(), img->fname);
-			}
-			remove_sw_file(fn);
-			if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdir(),
-				     img->fname) >= (int)sizeof(fn)) {
-				ERROR("Path too long: %s%s", TMPDIR, img->fname);
-			}
-			remove_sw_file(fn);
+
+	for (count = 0; count < 2; count++) {
+		if (count == 0)
+			list = &software->scripts;
+		else
+			list = &software->bootscripts;
+
+		LIST_FOREACH(img, list, next) {
+			cleaup_img_entry(img);
+
+			LIST_REMOVE(img, next);
+			free(img);
 		}
-		dict_drop_db(&img->properties);
-		LIST_REMOVE(img, next);
-		free(img);
 	}
 
 	dict_drop_db(&software->bootloader);
diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c
index a200d7e..99b8329 100644
--- a/corelib/stream_interface.c
+++ b/corelib/stream_interface.c
@@ -186,20 +186,38 @@  static int extract_files(int fd, struct swupdate_cfg *software)
 				break;
 			}
 
-			skip = check_if_required(&software->images, &fdh,
+			int i;
+
+			for (i = 0; i < 3; i++) {
+				switch(i) {
+				case 0:
+					skip = check_if_required(&software->images, &fdh,
 						&software->installed_sw_list,
 						get_tmpdir(),
 						&img);
-			if (skip == SKIP_FILE) {
+					break;
 				/*
 				 *  Check for script, but scripts are not checked
 				 *  for version
 				 */
-				skip = check_if_required(&software->scripts, &fdh,
+				case 1:
+					skip = check_if_required(&software->scripts, &fdh,
+							NULL,
+							get_tmpdir(),
+							&img);
+					break;
+				case 2:
+					skip = check_if_required(&software->bootscripts, &fdh,
 							NULL,
 							get_tmpdir(),
 							&img);
+					break;
+				}
+
+				if (skip != SKIP_FILE)
+					break;
 			}
+
 			TRACE("Found file:\n\tfilename %s\n\tsize %u %s",
 				fdh.filename,
 				(unsigned int)fdh.size,
diff --git a/include/installer.h b/include/installer.h
index 658b064..c0fe5e5 100644
--- a/include/installer.h
+++ b/include/installer.h
@@ -31,7 +31,6 @@  int check_if_required(struct imglist *list, struct filehdr *pfdh,
 				struct img_type **pimg);
 int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile);
 int install_single_image(struct img_type *img);
-int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type);
 int postupdate(struct swupdate_cfg *swcfg, const char *info);
 void cleanup_files(struct swupdate_cfg *software);
 
diff --git a/include/swupdate.h b/include/swupdate.h
index b065f7e..2cc824d 100644
--- a/include/swupdate.h
+++ b/include/swupdate.h
@@ -134,6 +134,7 @@  struct swupdate_cfg {
 	struct imglist images;
 	struct imglist partitions;
 	struct imglist scripts;
+	struct imglist bootscripts;
 	struct dictlist bootloader;
 	struct proclist extprocs;
 	void *dgst;	/* Structure for signed images */
diff --git a/parser/parser.c b/parser/parser.c
index 84b6576..9cd4204 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -351,6 +351,7 @@  static int parse_bootloader(parsertype p, void *cfg, struct swupdate_cfg *swcfg)
 {
 	void *setting, *elem;
 	int count, i;
+	struct img_type *script;
 	char name[32];
 	char value[255];
 
@@ -372,24 +373,45 @@  static int parse_bootloader(parsertype p, void *cfg, struct swupdate_cfg *swcfg)
 		/*
 		 * Check for mandatory field
 		 */
-		if(!(exist_field_string(p, elem, "name"))) {
-			TRACE("bootloader entry without variable name field, skipping..");
+		if(exist_field_string(p, elem, "name")) {
+			/*
+			 * Call directly get_field_string with size 0
+			 * to let allocate the place for the strings
+			 */
+			GET_FIELD_STRING(p, elem, "name", name);
+			GET_FIELD_STRING(p, elem, "value", value);
+			dict_set_value(&swcfg->bootloader, name, value);
+			TRACE("Bootloader var: %s = %s\n",
+				name,
+				dict_get_value(&swcfg->bootloader, name));
 			continue;
 		}
 
-
 		/*
-		 * Call directly get_field_string with size 0
-		 * to let allocate the place for the strings
+		 * Check if it is a bootloader script
 		 */
-		GET_FIELD_STRING(p, elem, "name", name);
-		GET_FIELD_STRING(p, elem, "value", value);
-		dict_set_value(&swcfg->bootloader, name, value);
+		if(!(exist_field_string(p, elem, "filename"))) {
+			TRACE("bootloader entry is neither a script nor name/value.");
+			continue;
+		}
+		script = (struct img_type *)calloc(1, sizeof(struct img_type));
+		if (!script) {
+			ERROR( "No memory: malloc failed\n");
+			return -ENOMEM;
+		}
+		GET_FIELD_STRING(p, elem, "filename", script->fname);
+		GET_FIELD_STRING(p, elem, "type", script->type);
+		GET_FIELD_STRING(p, elem, "data", script->type_data);
+		get_hash_value(p, elem, script->sha256);
+		get_field(p, elem, "encrypted", &script->is_encrypted);
+		get_field(p, elem, "compressed", &script->compressed);
+		get_field(p, elem, "encrypted", &script->is_encrypted);
+		script->is_script = 1;
 
-		TRACE("Bootloader var: %s = %s\n",
-			name,
-			dict_get_value(&swcfg->bootloader, name));
+		LIST_INSERT_HEAD(&swcfg->bootscripts, script, next);
 
+		TRACE("Found U-Boot Script: %s\n",
+			script->fname);
 	}
 
 	return 0;