chiark / gitweb /
make: do not delete autotools generated file with distclean
[elogind.git] / extras / volume_id / vol_id.c
index 0137b84fbeac91e8a51878b057c8e4bafe82bb42..889bd3483da174b13f8dac46b55a2cb332720bea 100644 (file)
@@ -31,6 +31,8 @@
 #include <grp.h>
 #include <getopt.h>
 #include <fcntl.h>
+#include <sys/stat.h>
+#include <inttypes.h>
 #include <sys/ioctl.h>
 
 #include "../../udev/udev.h"
@@ -57,44 +59,14 @@ static void vid_log(int priority, const char *file, int line, const char *format
 {
        va_list args;
 
+       if (priority > udev_get_log_priority(udev_ctx))
+               return;
        va_start(args, format);
-       udev_log(udev_ctx, priority, file, line, NULL, format, args);
+       log_fn(udev_ctx, priority, file, line, NULL, format, args);
        va_end(args);
        return;
 }
 
-static void set_str(char *to, const char *from, size_t count)
-{
-       size_t i, j, len;
-
-       /* strip trailing whitespace */
-       len = strnlen(from, count);
-       while (len && isspace(from[len-1]))
-               len--;
-
-       /* strip leading whitespace */
-       i = 0;
-       while (isspace(from[i]) && (i < len))
-               i++;
-
-       j = 0;
-       while (i < len) {
-               /* substitute multiple whitespace */
-               if (isspace(from[i])) {
-                       while (isspace(from[i]))
-                               i++;
-                       to[j++] = '_';
-               }
-               /* skip chars */
-               if (from[i] == '/') {
-                       i++;
-                       continue;
-               }
-               to[j++] = from[i++];
-       }
-       to[j] = '\0';
-}
-
 static int all_probers(volume_id_probe_fn_t probe_fn,
                       struct volume_id *id, uint64_t off, uint64_t size,
                       void *data)
@@ -117,6 +89,7 @@ int main(int argc, char *argv[])
                { "type", no_argument, NULL, 't' },
                { "export", no_argument, NULL, 'x' },
                { "skip-raid", no_argument, NULL, 's' },
+               { "size", required_argument, NULL, 'S' },
                { "probe-all", no_argument, NULL, 'a' },
                { "offset", optional_argument, NULL, 'o' },
                { "debug", no_argument, NULL, 'd' },
@@ -135,8 +108,11 @@ int main(int argc, char *argv[])
        struct volume_id *vid = NULL;
        char label_safe[256];
        char label_enc[256];
+       char uuid_safe[256];
        char uuid_enc[256];
-       uint64_t size;
+       char type_enc[256];
+       char type_version_enc[256];
+       uint64_t size = 0;
        int skip_raid = 0;
        int probe_all = 0;
        uint64_t offset = 0;
@@ -158,7 +134,7 @@ int main(int argc, char *argv[])
        while (1) {
                int option;
 
-               option = getopt_long(argc, argv, "lLutxsaodh", options, NULL);
+               option = getopt_long(argc, argv, "lLutxsS:aodh", options, NULL);
                if (option == -1)
                        break;
 
@@ -189,6 +165,10 @@ int main(int argc, char *argv[])
                case 'a':
                        probe_all = 1;
                        break;
+               case 'S':
+                       if (optarg[0] != '\0')
+                               size = strtoull(optarg, NULL, 0);
+                       break;
                case 'o':
                        if (optarg[0] != '\0')
                                offset = strtoull(optarg, NULL, 0);
@@ -203,6 +183,7 @@ int main(int argc, char *argv[])
                            " --skip-raid      don't probe for raid\n"
                            " --probe-all      find possibly conflicting signatures\n"
                            " --offset=<bytes> probe at the given offset\n"
+                           " --size=<bytes>   overwrite device size\n"
                            " --debug          print debug output to stderr\n"
                            " --help\n\n");
                        goto exit;
@@ -233,9 +214,19 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       if (ioctl(fd, BLKGETSIZE64, &size) != 0)
-               size = 0;
-       info(udev_ctx, "BLKGETSIZE64=%llu (%lluGB)\n", (unsigned long long)size, (unsigned long long)size >> 30);
+       if (size == 0) {
+               if (ioctl(fd, BLKGETSIZE64, &size) == 0) {
+                       info(udev_ctx, "BLKGETSIZE64=%" PRIu64 " (%" PRIu64 "GB)\n", size, size >> 30);
+               } else {
+                       struct stat statbuf;
+
+                       if (fstat(fd, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
+                               size = statbuf.st_size;
+                       else
+                               size = 0;
+                       info(udev_ctx, "stat=%" PRIu64 " (%" PRIu64 "GB)\n", size, size >> 30);
+               }
+       }
 
        /* try to drop all privileges before reading disk content */
        if (getuid() == 0) {
@@ -260,7 +251,8 @@ int main(int argc, char *argv[])
        else
                retval = volume_id_probe_all(vid, offset, size);
        if (retval != 0) {
-               fprintf(stderr, "%s: unknown volume type\n", node);
+               fprintf(stderr, "unknown or non-unique volume type "
+                               "(--probe-all lists possibly conflicting types)\n");
                rc = 4;
                goto exit;
        }
@@ -274,22 +266,26 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       set_str(label_safe, label, sizeof(label_safe));
-       util_replace_chars(label_safe, ALLOWED_CHARS_INPUT);
-
+       udev_util_replace_whitespace(label, label_safe, sizeof(label_safe));
+       udev_util_replace_chars(label_safe, UDEV_ALLOWED_CHARS_INPUT);
        volume_id_encode_string(label, label_enc, sizeof(label_enc));
+
+       udev_util_replace_whitespace(uuid, uuid_safe, sizeof(uuid_safe));
+       udev_util_replace_chars(uuid_safe, UDEV_ALLOWED_CHARS_INPUT);
        volume_id_encode_string(uuid, uuid_enc, sizeof(uuid_enc));
 
+       volume_id_encode_string(type, type_enc, sizeof(type_enc));
+       volume_id_encode_string(type_version, type_version_enc, sizeof(type_version_enc));
+
        switch (print) {
        case PRINT_EXPORT:
                printf("ID_FS_USAGE=%s\n", usage);
-               printf("ID_FS_TYPE=%s\n", type);
-               printf("ID_FS_VERSION=%s\n", type_version);
-               printf("ID_FS_UUID=%s\n", uuid);
+               printf("ID_FS_TYPE=%s\n", type_enc);
+               printf("ID_FS_VERSION=%s\n", type_version_enc);
+               printf("ID_FS_UUID=%s\n", uuid_safe);
                printf("ID_FS_UUID_ENC=%s\n", uuid_enc);
-               printf("ID_FS_LABEL=%s\n", label);
+               printf("ID_FS_LABEL=%s\n", label_safe);
                printf("ID_FS_LABEL_ENC=%s\n", label_enc);
-               printf("ID_FS_LABEL_SAFE=%s\n", label_safe);
                break;
        case PRINT_TYPE:
                printf("%s\n", type);