summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-11-09 08:52:19 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-11-16 13:55:33 +0100
commitdc91c971bf1ef0cb3eda77d56f4c18c5631c97e5 (patch)
treef6a86dbc34ec6466d893f2456acb9d6b39feb56b
parent9b49a3b49e78fa46ab5da45e5a176bab3df5803a (diff)
downloadsystemd-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.c37
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,