From c54670d564e52615faced9f700135527a71da594 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 11 Nov 2009 17:21:36 +0100 Subject: [PATCH] blkid: add ID_FS_AMBIVALENT for udev output UI tools that read information from udev need a way how inform users about ambivalent probing result (more valid filesystems on the device). This patch add a new ID_FS_AMBIVALENT variable: ID_FS_AMBIVALENT= [ ...] where is: :[:] all strings are encoded (white spaces and utf8 are replaced with \hex). For example: # blkid -p -o udev /dev/sda1 ID_FS_AMBIVALEN=filesystem:vfat:FAT12 other:swap:2 Signed-off-by: Karel Zak --- misc-utils/blkid.c | 90 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-) diff --git a/misc-utils/blkid.c b/misc-utils/blkid.c index 0182a9bb..6e055a95 100644 --- a/misc-utils/blkid.c +++ b/misc-utils/blkid.c @@ -323,6 +323,84 @@ static void print_tags(blkid_dev dev, char *show[], int output) printf("\n"); } + +static int append_str(char **res, size_t *sz, const char *a, const char *b) +{ + char *str = *res; + size_t asz = a ? strlen(a) : 0; + size_t bsz = b ? strlen(b) : 0; + size_t len = *sz + asz + bsz; + + if (!len) + return -1; + + str = realloc(str, len + 1); + if (!str) { + free(*res); + return -1; + } + *res = str; + str += *sz; + + if (a) { + memcpy(str, a, asz); + str += asz; + } + if (b) { + memcpy(str, b, bsz); + str += bsz; + } + *str = '\0'; + *sz = len; + return 0; +} + +/* + * Compose and print ID_FS_AMBIVALENT for udev + */ +static int print_udev_ambivalent(blkid_probe pr) +{ + char *val = NULL; + size_t valsz = 0; + int count = 0, rc = -1; + + while (!blkid_do_probe(pr)) { + const char *usage = NULL, *type = NULL, *version = NULL; + char enc[256]; + + blkid_probe_lookup_value(pr, "USAGE", &usage, NULL); + blkid_probe_lookup_value(pr, "TYPE", &type, NULL); + blkid_probe_lookup_value(pr, "VERSION", &version, NULL); + + if (!usage || !type) + continue; + + blkid_encode_string(usage, enc, sizeof(enc)); + if (append_str(&val, &valsz, enc, ":")) + goto done; + + blkid_encode_string(type, enc, sizeof(enc)); + if (append_str(&val, &valsz, enc, version ? ":" : " ")) + goto done; + + if (version) { + blkid_encode_string(version, enc, sizeof(enc)); + if (append_str(&val, &valsz, enc, " ")) + goto done; + } + count++; + } + + if (count > 1) { + *(val + valsz - 1) = '\0'; /* rem tailing whitespace */ + printf("ID_FS_AMBIVALEN=%s\n", val); + rc = 0; + } +done: + free(val); + return rc; +} + static int lowprobe_device(blkid_probe pr, const char *devname, char *show[], int output, blkid_loff_t offset, blkid_loff_t size) { @@ -362,10 +440,16 @@ static int lowprobe_device(blkid_probe pr, const char *devname, char *show[], if (nvals > 1 && !(output & (OUTPUT_VALUE_ONLY | OUTPUT_UDEV_LIST))) printf("\n"); done: - if (rc == -2) - fprintf(stderr, "%s: ambivalent result " - "(probably more filesystems on the device)\n", + if (rc == -2) { + if (output & OUTPUT_UDEV_LIST) + print_udev_ambivalent(pr); + else + fprintf(stderr, + "%s: ambivalent result (probably more " + "filesystems on the device, use wipefs(8) " + "to see more details)\n", devname); + } close(fd); return !nvals ? 2 : 0; } -- 2.39.5