chiark / gitweb /
Docs: udev.xml: `comma-separated' is a better description
[elogind.git] / udev / udevadm.c
1 /*
2  * Copyright (C) 2007-2009 Kay Sievers <kay.sievers@vrfy.org>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stddef.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <getopt.h>
25
26 #include "udev.h"
27
28 static int debug;
29
30 static void log_fn(struct udev *udev, int priority,
31                    const char *file, int line, const char *fn,
32                    const char *format, va_list args)
33 {
34         if (debug) {
35                 fprintf(stderr, "%s: ", fn);
36                 vfprintf(stderr, format, args);
37         } else {
38                 va_list args2;
39
40                 va_copy(args2, args);
41                 vfprintf(stderr, format, args2);
42                 va_end(args2);
43                 vsyslog(priority, format, args);
44         }
45 }
46
47 struct command {
48         const char *name;
49         int (*cmd)(struct udev *udev, int argc, char *argv[]);
50         const char *help;
51         int debug;
52 };
53
54 static const struct command cmds[];
55
56 static int version(struct udev *udev, int argc, char *argv[])
57 {
58         printf("%s\n", VERSION);
59         return 0;
60 }
61
62 static int help(struct udev *udev, int argc, char *argv[])
63 {
64         const struct command *cmd;
65
66         printf("Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n");
67         for (cmd = cmds; cmd->name != NULL; cmd++)
68                 if (cmd->help != NULL)
69                         printf("  %-12s %s\n", cmd->name, cmd->help);
70         printf("\n");
71         return 0;
72 }
73
74 static const struct command cmds[] = {
75         {
76                 .name = "info",
77                 .cmd = udevadm_info,
78                 .help = "query sysfs or the udev database",
79         },
80         {
81                 .name = "trigger",
82                 .cmd = udevadm_trigger,
83                 .help = "request events from the kernel",
84         },
85         {
86                 .name = "settle",
87                 .cmd = udevadm_settle,
88                 .help = "wait for the event queue to finish",
89         },
90         {
91                 .name = "control",
92                 .cmd = udevadm_control,
93                 .help = "control the udev daemon",
94         },
95         {
96                 .name = "monitor",
97                 .cmd = udevadm_monitor,
98                 .help = "listen to kernel and udev events",
99         },
100         {
101                 .name = "test",
102                 .cmd = udevadm_test,
103                 .help = "simulation run",
104                 .debug = 1,
105         },
106         {
107                 .name = "version",
108                 .cmd = version,
109         },
110         {
111                 .name = "help",
112                 .cmd = help,
113         },
114         {}
115 };
116
117 static int run_command(struct udev *udev, const struct command *cmd, int argc, char *argv[])
118 {
119         if (cmd->debug) {
120                 debug = 1;
121                 if (udev_get_log_priority(udev) < LOG_INFO)
122                         udev_set_log_priority(udev, LOG_INFO);
123         }
124         info(udev, "calling: %s\n", cmd->name);
125         return cmd->cmd(udev, argc, argv);
126 }
127
128 int main(int argc, char *argv[])
129 {
130         struct udev *udev;
131         static const struct option options[] = {
132                 { "debug", no_argument, NULL, 'd' },
133                 { "help", no_argument, NULL, 'h' },
134                 { "version", no_argument, NULL, 'V' },
135                 {}
136         };
137         const char *command;
138         int i;
139         int rc = 1;
140
141         udev = udev_new();
142         if (udev == NULL)
143                 goto out;
144
145         udev_log_init("udevadm");
146         udev_set_log_fn(udev, log_fn);
147         udev_selinux_init(udev);
148
149         for (;;) {
150                 int option;
151
152                 option = getopt_long(argc, argv, "+dhV", options, NULL);
153                 if (option == -1)
154                         break;
155
156                 switch (option) {
157                 case 'd':
158                         debug = 1;
159                         if (udev_get_log_priority(udev) < LOG_INFO)
160                                 udev_set_log_priority(udev, LOG_INFO);
161                         break;
162                 case 'h':
163                         rc = help(udev, argc, argv);
164                         goto out;
165                 case 'V':
166                         rc = version(udev, argc, argv);
167                         goto out;
168                 default:
169                         goto out;
170                 }
171         }
172         command = argv[optind];
173
174         info(udev, "runtime dir '%s'\n", udev_get_run_path(udev));
175
176         if (command != NULL)
177                 for (i = 0; cmds[i].cmd != NULL; i++) {
178                         if (strcmp(cmds[i].name, command) == 0) {
179                                 argc -= optind;
180                                 argv += optind;
181                                 optind = 0;
182                                 rc = run_command(udev, &cmds[i], argc, argv);
183                                 goto out;
184                         }
185                 }
186
187         fprintf(stderr, "missing or unknown command\n\n");
188         help(udev, argc, argv);
189         rc = 2;
190 out:
191         udev_selinux_exit(udev);
192         udev_unref(udev);
193         udev_log_close();
194         return rc;
195 }