diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index f94fac1b410..50662037dee 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -85,6 +85,13 @@ static const char* const image_search_path_initrd[_IMAGE_CLASS_MAX] = { "/.extra/sysext\0" /* put sysext picked up by systemd-stub last, since not trusted */ }; +static const char* image_class_suffix_table[_IMAGE_CLASS_MAX] = { + [IMAGE_SYSEXT] = ".sysext", + [IMAGE_CONFEXT] = ".confext", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(image_class_suffix, ImageClass); + static Image *image_free(Image *i) { assert(i); @@ -201,29 +208,36 @@ static int image_new( return 0; } -static int extract_pretty(const char *path, const char *suffix, char **ret) { +static int extract_pretty( + const char *path, + const char *class_suffix, + const char *format_suffix, + char **ret) { + _cleanup_free_ char *name = NULL; - const char *p; + int r; assert(path); assert(ret); - p = last_path_component(path); + r = path_extract_filename(path, &name); + if (r < 0) + return r; - name = strdupcspn(p, "/"); - if (!name) - return -ENOMEM; - - if (suffix) { - char *e; - - e = endswith(name, suffix); - if (!e) + if (format_suffix) { + char *e = endswith(name, format_suffix); + if (!e) /* Format suffix is required */ return -EINVAL; *e = 0; } + if (class_suffix) { + char *e = endswith(name, class_suffix); + if (e) /* Class suffix is optional */ + *e = 0; + } + if (!image_name_is_valid(name)) return -EINVAL; @@ -282,7 +296,7 @@ static int image_make( return 0; if (!pretty) { - r = extract_pretty(filename, NULL, &pretty_buffer); + r = extract_pretty(filename, image_class_suffix_to_string(c), NULL, &pretty_buffer); if (r < 0) return r; @@ -369,7 +383,7 @@ static int image_make( (void) fd_getcrtime_at(dfd, filename, AT_SYMLINK_FOLLOW, &crtime); if (!pretty) { - r = extract_pretty(filename, ".raw", &pretty_buffer); + r = extract_pretty(filename, image_class_suffix_to_string(c), ".raw", &pretty_buffer); if (r < 0) return r; @@ -403,7 +417,7 @@ static int image_make( return 0; if (!pretty) { - r = extract_pretty(filename, NULL, &pretty_buffer); + r = extract_pretty(filename, NULL, NULL, &pretty_buffer); if (r < 0) return r; @@ -592,8 +606,7 @@ int image_discover( FOREACH_DIRENT_ALL(de, d, return -errno) { _cleanup_(image_unrefp) Image *image = NULL; - _cleanup_free_ char *truncated = NULL; - const char *pretty; + _cleanup_free_ char *pretty = NULL; struct stat st; int flags; @@ -610,22 +623,16 @@ int image_discover( return -errno; } - if (S_ISREG(st.st_mode)) { - const char *e; - - e = endswith(de->d_name, ".raw"); - if (!e) - continue; - - truncated = strndup(de->d_name, e - de->d_name); - if (!truncated) - return -ENOMEM; - - pretty = truncated; - } else if (S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) - pretty = de->d_name; + if (S_ISREG(st.st_mode)) + r = extract_pretty(de->d_name, image_class_suffix_to_string(class), ".raw", &pretty); + else if (S_ISDIR(st.st_mode)) + r = extract_pretty(de->d_name, image_class_suffix_to_string(class), NULL, &pretty); + else if (S_ISBLK(st.st_mode)) + r = extract_pretty(de->d_name, NULL, NULL, &pretty); else continue; + if (r < 0) + return r; if (!image_name_is_valid(pretty)) continue; diff --git a/src/shared/import-util.c b/src/shared/import-util.c index ec890645061..9057b78d286 100644 --- a/src/shared/import-util.c +++ b/src/shared/import-util.c @@ -167,6 +167,8 @@ int raw_strip_suffixes(const char *p, char **ret) { ".xz\0" ".gz\0" ".bz2\0" + ".sysext.raw\0" + ".confext.raw\0" ".raw\0" ".qcow2\0" ".img\0"