diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-11-09 08:52:19 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-11-16 13:55:33 +0100 |
commit | dc91c971bf1ef0cb3eda77d56f4c18c5631c97e5 (patch) | |
tree | f6a86dbc34ec6466d893f2456acb9d6b39feb56b | |
parent | 9b49a3b49e78fa46ab5da45e5a176bab3df5803a (diff) | |
download | systemd-dc91c971bf1ef0cb3eda77d56f4c18c5631c97e5.tar.gz |
makefs: fix label for vfat filesystems
I was testing with a "test1.img" and mkfs.vfat rejects "TEST1.IMG" with the
error "Labels with characters *?.,;:/\|+=<>[]" are not allowed". So let's
replace those characters with "_".
-rw-r--r-- | src/shared/mkfs-util.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index fbf04aa7ae..db755095ee 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -8,6 +8,7 @@ #include "process-util.h" #include "stdio-util.h" #include "string-util.h" +#include "utf8.h" int mkfs_exists(const char *fstype) { const char *mkfs; @@ -31,6 +32,30 @@ int mkfs_exists(const char *fstype) { return true; } +static int mangle_fat_label(const char *s, char **ret) { + assert(s); + + _cleanup_free_ char *q = NULL; + int r; + + r = utf8_to_ascii(s, '_', &q); + if (r < 0) + return r; + + /* Classic FAT only allows 11 character uppercase labels */ + strshorten(q, 11); + ascii_strupper(q); + + /* mkfs.vfat: Labels with characters *?.,;:/\|+=<>[]" are not allowed. + * Let's also replace any control chars. */ + for (char *p = q; *p; p++) + if (strchr("*?.,;:/\\|+=<>[]\"", *p) || char_is_cc(*p)) + *p = '_'; + + *ret = TAKE_PTR(q); + return 0; +} + int make_filesystem( const char *node, const char *fstype, @@ -38,9 +63,8 @@ int make_filesystem( sd_id128_t uuid, bool discard) { - _cleanup_free_ char *mkfs = NULL; - char mangled_label[8 + 3 + 1], - vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {}; + _cleanup_free_ char *mkfs = NULL, *mangled_label = NULL; + char vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {}; int r; assert(node); @@ -66,10 +90,9 @@ int make_filesystem( } if (streq(fstype, "vfat")) { - /* Classic FAT only allows 11 character uppercase labels */ - strncpy(mangled_label, label, sizeof(mangled_label)-1); - mangled_label[sizeof(mangled_label)-1] = 0; - ascii_strupper(mangled_label); + r = mangle_fat_label(label, &mangled_label); + if (r < 0) + return log_error_errno(r, "Failed to determine FAT label from string \"%s\": %m", label); label = mangled_label; xsprintf(vol_id, "%08" PRIx32, |