@@ -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;
@@ -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;
-}
+ ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL);
-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;
- }
- }
-
- return 0;
+ return ret;
}
-
static void remove_sw_file(char __attribute__ ((__unused__)) *fname)
{
#ifndef CONFIG_NOCLEANUP
@@ -430,11 +432,32 @@ 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[] = { get_tmpdirscripts(), get_tmpdir() };
+
+ if (img->fname[0]) {
+ for (i = 0; i < ARRAY_SIZE(tmp); i++) {
+ if (asprintf(&fn, "%s%s", tmp[i], img->fname) == ENOMEM_ASPRINTF) {
+ ERROR("Path too long: %s%s", tmp[i], 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[] = {&software->scripts, &software->bootscripts};
LIST_FOREACH(img, &software->images, next) {
if (img->fname[0]) {
@@ -447,22 +470,14 @@ 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 < ARRAY_SIZE(list); count++) {
+ LIST_FOREACH(img, list[count], 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);
@@ -186,20 +186,23 @@ static int extract_files(int fd, struct swupdate_cfg *software)
break;
}
- skip = check_if_required(&software->images, &fdh,
- &software->installed_sw_list,
+ int i;
+
+ struct imglist *list[] = {&software->images,
+ &software->scripts,
+ &software->bootscripts};
+
+ for (i = 0; i < ARRAY_SIZE(list); i++) {
+ skip = check_if_required(list[i], &fdh,
+ (list[i] == &software->images) ?
+ &software->installed_sw_list : NULL,
get_tmpdir(),
&img);
- if (skip == SKIP_FILE) {
- /*
- * Check for script, but scripts are not checked
- * for version
- */
- skip = check_if_required(&software->scripts, &fdh,
- NULL,
- get_tmpdir(),
- &img);
+
+ if (skip != SKIP_FILE)
+ break;
}
+
TRACE("Found file:\n\tfilename %s\n\tsize %u %s",
fdh.filename,
(unsigned int)fdh.size,
@@ -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);
@@ -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 */
@@ -359,6 +359,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];
@@ -380,24 +381,44 @@ 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);
+ 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;
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> --- Changes since V2: - use ARRAY_SIZE() macro Changes since V1: - replaces switch() with arrays core/parser.c | 2 + corelib/installer.c | 93 +++++++++++++++++++++++++++------------------- corelib/stream_interface.c | 25 +++++++------ include/installer.h | 1 - include/swupdate.h | 1 + parser/parser.c | 43 +++++++++++++++------ 6 files changed, 103 insertions(+), 62 deletions(-)