chiark / gitweb /
[PATCH] udev_volume_id: volume_id v35
[elogind.git] / extras / volume_id / udev_volume_id.c
index 88779ccd36889ce096bc43ef6b67e4a7fb62a723..c36b89f8bd4d8d443cdde11ff6400226e22fbf0e 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * udev_volume_id - udev callout to read filesystem label and uuid
  *
- * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2005 Kay Sievers <kay.sievers@vrfy.org>
  *
  *     sample udev rule for creation of a symlink with the filsystem uuid:
- *     KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -M%M -m%m -u", SYMLINK="%c"
+ *     KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -u %N", SYMLINK="%c"
  *
  *     This program is free software; you can redistribute it and/or modify it
  *     under the terms of the GNU General Public License as published by the
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/ioctl.h>
 
-#include "volume_id.h"
+#include "../../udev_utils.h"
+#include "../../logging.h"
+#include "volume_id/volume_id.h"
+#include "volume_id/dasd.h"
+
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+
+#ifdef LOG
+void log_message(int level, const char *format, ...)
+{
+       va_list args;
+
+       va_start(args, format);
+       vsyslog(level, format, args);
+       va_end(args);
+}
+#endif
+
+extern int optind;
 
 int main(int argc, char *argv[])
 {
-       struct volume_id *vid;
-       const char help[] = "usage: udev_volume_id -m<minor> -M<major> [-t|-l|-u]\n";
-       int major = -1;
-       int minor = -1;
-       char *tail;
-       static const char short_options[] = "M:m:htlu";
-       int option;
-       char print = '\0';
-       int rc;
+       const char help[] = "usage: udev_volume_id [-t|-l|-u] <device>\n"
+                           "       -t filesystem type\n"
+                           "       -l filesystem label\n"
+                           "       -u filesystem uuid\n"
+                           "\n";
+       static const char short_options[] = "htlu";
+       struct volume_id *vid = NULL;
+       const char *device;
+       char print = 'a';
+       static char name[VOLUME_ID_LABEL_SIZE];
+       int len, i, j;
+       unsigned long long size;
+       int rc = 1;
 
+       logging_init("udev_volume_id");
 
        while (1) {
+               int option;
+
                option = getopt(argc, argv, short_options);
                if (option == -1)
                        break;
 
                switch (option) {
-               case 'M':
-                       major = (int) strtoul(optarg, &tail, 10);
-                       if (tail[0] != '\0') {
-                               printf("invalid major\n");
-                               exit(1);
-                       }
-                       break;
-               case 'm':
-                       minor = (int) strtoul(optarg, &tail, 10);
-                       if (tail[0] != '\0') {
-                               printf("invalid minor\n");
-                               exit(1);
-                       }
-                       break;
                case 't':
                        print = 't';
-                       break;
+                       continue;
                case 'l':
                        print = 'l';
-                       break;
+                       continue;
                case 'u':
                        print = 'u';
-                       break;
+                       continue;
                case 'h':
                case '?':
                default:
@@ -77,44 +91,90 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (major == -1 || minor == -1) {
+       device = argv[optind];
+       if (device == NULL) {
                printf(help);
                exit(1);
        }
 
-       vid = volume_id_open_dev_t(makedev(major, minor));
+       vid = volume_id_open_node(device);
        if (vid == NULL) {
                printf("error open volume\n");
-               exit(1);
+               goto exit;
        }
 
-       rc = volume_id_probe(vid, ALL);
-       if (rc != 0) {
-               printf("error probing volume\n");
-               exit(1);
+       if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
+               size = 0;
+
+       if (volume_id_probe_all(vid, 0, size) == 0)
+               goto print;
+
+       if (volume_id_probe_dasd(vid) == 0)
+               goto print;
+
+       printf("unknown volume type\n");
+       goto exit;
+
+
+print:
+       len = strnlen(vid->label, VOLUME_ID_LABEL_SIZE);
+
+       /* remove trailing spaces */
+       while (len > 0 && isspace(vid->label[len-1]))
+               len--;
+       name[len] = '\0';
+
+       /* substitute chars */
+       i = 0;
+       j = 0;
+       while (j < len) {
+               switch(vid->label[j]) {
+               case '/' :
+                       break;
+               case ' ' :
+                       name[i++] = '_';
+                       break;
+               default :
+                       name[i++] = vid->label[j];
+               }
+               j++;
        }
+       name[i] = '\0';
 
        switch (print) {
        case 't':
-               printf("%s\n", vid->fs_name);
+               printf("%s\n", vid->type);
                break;
        case 'l':
-               if (vid->label_string[0] == '\0')
-                       exit(2);
-               printf("%s\n", vid->label_string);
+               if (name[0] == '\0' ||
+                   (vid->usage_id != VOLUME_ID_FILESYSTEM && vid->usage_id != VOLUME_ID_DISKLABEL)) {
+                       rc = 2;
+                       goto exit;
+               }
+               printf("%s\n", name);
                break;
        case 'u':
-               if (vid->uuid_string[0] == '\0')
-                       exit(2);
-               printf("%s\n", vid->uuid_string);
+               if (vid->uuid[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) {
+                       rc = 2;
+                       goto exit;
+               }
+               printf("%s\n", vid->uuid);
                break;
-       default:
-               printf("T:%s\n", vid->fs_name);
-               printf("L:%s\n", vid->label_string);
-               printf("U:%s\n", vid->uuid_string);
+       case 'a':
+               printf("F:%s\n", vid->usage);
+               printf("T:%s\n", vid->type);
+               printf("V:%s\n", vid->type_version);
+               printf("L:%s\n", vid->label);
+               printf("N:%s\n", name);
+               printf("U:%s\n", vid->uuid);
        }
+       rc = 0;
+
+exit:
+       if (vid != NULL)
+               volume_id_close(vid);
 
-       volume_id_close(vid);
+       logging_close();
 
-       exit(0);
+       exit(rc);
 }