chiark / gitweb /
volume_id: run only once into a timeout for unreadable devices
[elogind.git] / udevmonitor.c
index 89053185e03966e9558464cd34edfe92580eee17..75e39481a02a3ff3773b215a6741766745acd0e0 100644 (file)
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
+#include <getopt.h>
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -42,7 +43,6 @@ static int init_udev_monitor_socket(void)
 {
        struct sockaddr_un saddr;
        socklen_t addrlen;
-       const int feature_on = 1;
        int retval;
 
        memset(&saddr, 0x00, sizeof(saddr));
@@ -66,9 +66,6 @@ static int init_udev_monitor_socket(void)
                return -1;
        }
 
-       /* enable receiving of the sender credentials */
-       setsockopt(udev_monitor_sock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on));
-
        return 0;
 }
 
@@ -126,32 +123,58 @@ static const char *search_key(const char *searchkey, const char *buf, size_t buf
        return NULL;
 }
 
-int main(int argc, char *argv[])
+int udevmonitor(int argc, char *argv[], char *envp[])
 {
        struct sigaction act;
+       int option;
        int env = 0;
+       int kernel = 0;
+       int udev = 0;
        fd_set readfds;
-       int i;
        int retval = 0;
 
-       for (i = 1 ; i < argc; i++) {
-               char *arg = argv[i];
-               if (strcmp(arg, "--env") == 0 || strcmp(arg, "-e") == 0)
+       static const struct option options[] = {
+               { "environment", 0, NULL, 'e' },
+               { "kernel", 0, NULL, 'k' },
+               { "udev", 0, NULL, 'u' },
+               { "help", 0, NULL, 'h' },
+               {}
+       };
+
+       while (1) {
+               option = getopt_long(argc, argv, "ekuh", options, NULL);
+               if (option == -1)
+                       break;
+
+               switch (option) {
+               case 'e':
                        env = 1;
-               else if (strcmp(arg, "--help") == 0  || strcmp(arg, "-h") == 0){
-                       printf("Usage: udevmonitor [--help] [--env]\n"
-                               "  --env    print the whole event environment\n"
-                               "  --help   print this help text\n\n");
-                       exit(0);
-               } else {
-                       fprintf(stderr, "unrecognized option '%s'\n", arg);
-                       exit(1);
+                       break;
+               case 'k':
+                       kernel = 1;
+                       break;
+               case 'u':
+                       udev = 1;
+                       break;
+               case 'h':
+                       printf("Usage: udevadm monitor [--environment] [--kernel] [--udev] [--help]\n"
+                              "  --env    print the whole event environment\n"
+                              "  --kernel print kernel uevents\n"
+                              "  --udev   print udev events\n"
+                              "  --help   print this help text\n\n");
+               default:
+                       goto out;
                }
        }
 
-       if (getuid() != 0) {
-               fprintf(stderr, "root privileges required\n");
-               exit(2);
+       if (!kernel && !udev) {
+               kernel = 1;
+               udev =1;
+       }
+
+       if (getuid() != 0 && kernel) {
+               fprintf(stderr, "root privileges needed to subscribe to kernel events\n");
+               goto out;
        }
 
        /* set signal handlers */
@@ -162,16 +185,20 @@ int main(int argc, char *argv[])
        sigaction(SIGINT, &act, NULL);
        sigaction(SIGTERM, &act, NULL);
 
-       retval = init_udev_monitor_socket();
-       if (retval)
-               goto out;
-
-       retval = init_uevent_netlink_sock();
-       if (retval)
-               goto out;
-
-       printf("udevmonitor prints the received event from the kernel [UEVENT]\n"
-              "and the event which udev sends out after rule processing [UDEV]\n\n");
+       printf("udevmonitor will print the received events for:\n");
+       if (udev) {
+               retval = init_udev_monitor_socket();
+               if (retval)
+                       goto out;
+               printf("UDEV the event which udev sends out after rule processing\n");
+       }
+       if (kernel) {
+               retval = init_uevent_netlink_sock();
+               if (retval)
+                       goto out;
+               printf("UEVENT the kernel uevent\n");
+       }
+       printf("\n");
 
        while (!udev_exit) {
                char buf[UEVENT_BUFFER_SIZE*2];
@@ -257,6 +284,6 @@ out:
                close(udev_monitor_sock);
 
        if (retval)
-               return 3;
+               return 1;
        return 0;
 }