summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pitt <martin.pitt@ubuntu.com>2009-04-03 16:46:45 +0200
committerMartin Pitt <martin.pitt@ubuntu.com>2009-04-03 16:46:45 +0200
commit97b023f94f1d79a19bc0489c0d167bdaebb765fd (patch)
tree62eb34648d9eaea8309a518131c3619825aa0e08
parent746d4b8035a4ca7908503e7bbbea4db7284766e9 (diff)
fix volume label parsing
Not probing volumes ourselves and reading from the udev db (commit 79b92dbdf65b8c978d5a8f6fb2b421aac83c3de3) caused a regression: udevadm info's ID_FS_LABEL is mangled, e. g. spaces appear as '_'. Use ID_FS_LABEL_ENC instead and use a new hal/util.c function hal_util_decode_escape() to decode those. https://launchpad.net/bugs/347370
-rw-r--r--hald/linux/coldplug.c7
-rw-r--r--hald/linux/osspec.c10
-rw-r--r--hald/util.c33
-rw-r--r--hald/util.h2
4 files changed, 47 insertions, 5 deletions
diff --git a/hald/linux/coldplug.c b/hald/linux/coldplug.c
index 16fa34ce..276382d8 100644
--- a/hald/linux/coldplug.c
+++ b/hald/linux/coldplug.c
@@ -159,6 +159,7 @@ hal_util_init_sysfs_to_udev_map (void)
int udevinfo_exitcode;
UdevInfo *info = NULL;
char *p;
+ int len;
sysfs_to_udev_map = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, udev_info_free);
@@ -252,8 +253,10 @@ hal_util_init_sysfs_to_udev_map (void)
info->fsversion = &line[17];
} else if (strncmp(line, "E: ID_FS_UUID=", 14) == 0) {
info->fsuuid = &line[14];
- } else if (strncmp(line, "E: ID_FS_LABEL=", 15) == 0) {
- info->fslabel = &line[15];
+ } else if (strncmp(line, "E: ID_FS_LABEL_ENC=", 19) == 0) {
+ len = strlen (&line[15]);
+ info->fslabel = g_malloc0 (len + 1);
+ hal_util_decode_escape (&line[19], info->fslabel, len + 1);
}
}
diff --git a/hald/linux/osspec.c b/hald/linux/osspec.c
index 4599c7cf..56e3b654 100644
--- a/hald/linux/osspec.c
+++ b/hald/linux/osspec.c
@@ -128,7 +128,7 @@ hald_udev_data (GIOChannel *source, GIOCondition condition, gpointer user_data)
while (bufpos < sizeof (buf)) {
size_t keylen;
char *key;
- char *str;
+ char *str, *dstr;
key = &buf[bufpos];
keylen = strlen(key);
@@ -206,11 +206,15 @@ hald_udev_data (GIOChannel *source, GIOCondition condition, gpointer user_data)
g_strlcpy (hotplug_event->sysfs.fsuuid, str, sizeof(hotplug_event->sysfs.fsuuid));
g_free (str);
}
- } else if (strncmp(key, "ID_FS_LABEL=", 12) == 0) {
- if ((str = hal_util_strdup_valid_utf8(&key[12])) != NULL ) {
+ } else if (strncmp(key, "ID_FS_LABEL_ENC=", 16) == 0) {
+ dstr = g_malloc0 (keylen - 15);
+ hal_util_decode_escape (&key[16], dstr, sizeof(hotplug_event->sysfs.fslabel));
+
+ if ((str = hal_util_strdup_valid_utf8(dstr)) != NULL ) {
g_strlcpy (hotplug_event->sysfs.fslabel, str, sizeof(hotplug_event->sysfs.fslabel));
g_free (str);
}
+ g_free (dstr);
}
}
diff --git a/hald/util.c b/hald/util.c
index c7f80abe..7fa3011b 100644
--- a/hald/util.c
+++ b/hald/util.c
@@ -1228,3 +1228,36 @@ is_valid_interface_name (const char *name) {
return TRUE;
}
+static int
+hexdigit (char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a';
+ if (c >= 'A' && c <= 'F')
+ return c - 'A';
+ HAL_ERROR (("'%c' is not a valid hex digit", c));
+ return 0;
+}
+
+/* Decode string with \xNN escapes */
+void
+hal_util_decode_escape (const char* src, char* result, int maxlen)
+{
+ int len;
+
+ if (src == NULL || maxlen == 0)
+ return;
+
+ for (len = 0; len < maxlen && *src; ++len) {
+ /* note that C's short-circuiting avoids reading past \0 */
+ if (*src == '\\' && src[1] == 'x' && isalnum (src[2]) && isalnum (src[3])) {
+ result[len] = (hexdigit(src[2]) << 4) | hexdigit(src[3]);
+ src += 4;
+ } else
+ result[len] = *src++;
+ }
+}
+
+
diff --git a/hald/util.h b/hald/util.h
index 5377e359..c2a1584b 100644
--- a/hald/util.h
+++ b/hald/util.h
@@ -117,4 +117,6 @@ char *hal_util_readlink (const char *link);
gboolean is_valid_interface_name (const char *name);
+void hal_util_decode_escape (const char* src, char* result, int maxlen);
+
#endif /* UTIL_H */