diff options
author | Martin Pitt <martin.pitt@ubuntu.com> | 2009-04-03 16:46:45 +0200 |
---|---|---|
committer | Martin Pitt <martin.pitt@ubuntu.com> | 2009-04-03 16:46:45 +0200 |
commit | 97b023f94f1d79a19bc0489c0d167bdaebb765fd (patch) | |
tree | 62eb34648d9eaea8309a518131c3619825aa0e08 | |
parent | 746d4b8035a4ca7908503e7bbbea4db7284766e9 (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.c | 7 | ||||
-rw-r--r-- | hald/linux/osspec.c | 10 | ||||
-rw-r--r-- | hald/util.c | 33 | ||||
-rw-r--r-- | hald/util.h | 2 |
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 */ |