chiark / gitweb /
[PATCH] add "serio" to bus list
[elogind.git] / extras / volume_id / udev_volume_id.c
index 18915cb62b18bde6d6a26d22bf9e4a485030848c..843b70baf5672c95113f4c33e4819b5228d33d3c 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 -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 "../../libsysfs/sysfs/libsysfs.h"
-#include "../../udev_lib.h"
+#include "../../udev_utils.h"
 #include "../../logging.h"
-#include "volume_id.h"
-#include "dasdlabel.h"
+#include "volume_id/volume_id.h"
+#include "volume_id/dasd/dasd.h"
+
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
 
 #ifdef LOG
-unsigned char logname[LOGNAME_SIZE];
 void log_message(int level, const char *format, ...)
 {
        va_list args;
@@ -44,57 +46,29 @@ void log_message(int level, const char *format, ...)
 }
 #endif
 
-static struct volume_id *open_classdev(struct sysfs_class_device *class_dev)
-{
-       struct volume_id *vid;
-       struct sysfs_attribute *attr;
-       int major, minor;
-
-       attr = sysfs_get_classdev_attr(class_dev, "dev");
-
-       if (attr == NULL) {
-               printf("error reading 'dev' attribute\n");
-               return NULL;
-       }
-
-       if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) {
-               printf("error getting major/minor number\n");
-               return NULL;
-       }
-
-       vid = volume_id_open_dev_t(makedev(major, minor));
-       if (vid == NULL) {
-               printf("error open volume\n");
-               return NULL;
-       }
-
-       return vid;
-}
+extern int optind;
 
 int main(int argc, char *argv[])
 {
-       const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n"
+       const char help[] = "usage: udev_volume_id [-t|-l|-u] <device>\n"
                            "       -t filesystem type\n"
                            "       -l filesystem label\n"
                            "       -u filesystem uuid\n"
-                           "       -d disk label from main device\n"
                            "\n";
-       static const char short_options[] = "htlud";
-       int option;
-       char sysfs_path[SYSFS_PATH_MAX];
-       char dev_path[SYSFS_PATH_MAX];
-       struct sysfs_class_device *class_dev = NULL;
-       struct sysfs_class_device *class_dev_parent = NULL;
+       static const char short_options[] = "htlu";
        struct volume_id *vid = NULL;
-       char *devpath;
-       char probe = 'p';
+       const char *device;
        char print = 'a';
-       char dasd_label[7];
        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;
@@ -109,9 +83,6 @@ int main(int argc, char *argv[])
                case 'u':
                        print = 'u';
                        continue;
-               case 'd':
-                       probe = 'd';
-                       continue;
                case 'h':
                case '?':
                default:
@@ -120,64 +91,36 @@ int main(int argc, char *argv[])
                }
        }
 
-       devpath = getenv("DEVPATH");
-       if (devpath == NULL) {
-               printf("error DEVPATH empty\n");
-               goto exit;
+       device = argv[optind];
+       if (device == NULL) {
+               printf(help);
+               exit(1);
        }
 
-       if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) {
-               printf("error getting sysfs mount path\n");
+       vid = volume_id_open_node(device);
+       if (vid == NULL) {
+               printf("error open volume\n");
                goto exit;
        }
 
-       strfieldcpy(dev_path, sysfs_path);
-       strfieldcat(dev_path, devpath);
+       if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0)
+               size = 0;
 
-       class_dev = sysfs_open_class_device_path(dev_path);
-       if (class_dev == NULL) {
-               printf("error getting class device\n");
-               goto exit;
-       }
+       if (volume_id_probe_all(vid, 0, size) == 0)
+               goto print;
 
-       switch(probe) {
-       case 'p' :
-               /* open block device */
-               vid = open_classdev(class_dev);
-               if (vid == NULL)
-                       goto exit;
-               if (volume_id_probe(vid, ALL) == 0)
-                       goto print;
-               break;
-       case 'd' :
-               /* if we are on a partition, close it and open main block device */
-               class_dev_parent = sysfs_get_classdev_parent(class_dev);
-               if (class_dev_parent != NULL) {
-                       volume_id_close(vid);
-                       vid = open_classdev(class_dev_parent);
-               } else {
-                       vid = open_classdev(class_dev_parent);
-               }
-               if (vid == NULL)
-                       goto exit;
-               if (probe_ibm_partition(vid->fd, dasd_label) == 0) {
-                       vid->fs_name = "dasd";
-                       strncpy(vid->label_string, dasd_label, 6);
-                       vid->label_string[6] = '\0';
-                       goto print;
-               }
-               break;
-       }
+       if (volume_id_probe_dasd(vid) == 0)
+               goto print;
 
        printf("unknown volume type\n");
        goto exit;
 
 
 print:
-       len = strnlen(vid->label_string, VOLUME_ID_LABEL_SIZE);
+       len = strnlen(vid->label, VOLUME_ID_LABEL_SIZE);
 
        /* remove trailing spaces */
-       while (len > 0 && isspace(vid->label_string[len-1]))
+       while (len > 0 && isspace(vid->label[len-1]))
                len--;
        name[len] = '\0';
 
@@ -185,14 +128,14 @@ print:
        i = 0;
        j = 0;
        while (j < len) {
-               switch(vid->label_string[j]) {
+               switch(vid->label[j]) {
                case '/' :
                        break;
                case ' ' :
                        name[i++] = '_';
                        break;
                default :
-                       name[i++] = vid->label_string[j];
+                       name[i++] = vid->label[j];
                }
                j++;
        }
@@ -200,35 +143,38 @@ print:
 
        switch (print) {
        case 't':
-               printf("%s\n", vid->fs_name);
+               printf("%s\n", vid->type);
                break;
        case 'l':
-               if (name[0] == '\0') {
+               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') {
+               if (vid->uuid[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) {
                        rc = 2;
                        goto exit;
                }
-               printf("%s\n", vid->uuid_string);
+               printf("%s\n", vid->uuid);
                break;
        case 'a':
-               printf("T:%s\n", vid->fs_name);
-               printf("L:%s\n", vid->label_string);
+               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_string);
+               printf("U:%s\n", vid->uuid);
        }
        rc = 0;
 
 exit:
-       if (class_dev != NULL)
-               sysfs_close_class_device(class_dev);
        if (vid != NULL)
                volume_id_close(vid);
 
+       logging_close();
+
        exit(rc);
 }