chiark / gitweb /
udevadm: log message if udevadm link is used
[elogind.git] / udev / udevadm.c
1 /*
2  * Copyright (C) 2007-2008 Kay Sievers <kay.sievers@vrfy.org>
3  *
4  *      This program is free software; you can redistribute it and/or modify it
5  *      under the terms of the GNU General Public License as published by the
6  *      Free Software Foundation version 2 of the License.
7  * 
8  *      This program is distributed in the hope that it will be useful, but
9  *      WITHOUT ANY WARRANTY; without even the implied warranty of
10  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  *      General Public License for more details.
12  * 
13  *      You should have received a copy of the GNU General Public License along
14  *      with this program; if not, write to the Free Software Foundation, Inc.,
15  *      51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16  *
17  */
18
19 #include "config.h"
20
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <stddef.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <getopt.h>
28
29 #include "udev.h"
30
31 static int debug;
32
33 static void log_fn(struct udev *udev, int priority,
34                    const char *file, int line, const char *fn,
35                    const char *format, va_list args)
36 {
37         if (debug) {
38                 fprintf(stderr, "%s: ", fn);
39                 vfprintf(stderr, format, args);
40         } else {
41                 vsyslog(priority, format, args);
42         }
43 }
44
45 struct command {
46         const char *name;
47         int (*cmd)(struct udev *udev, int argc, char *argv[]);
48         const char *help;
49         int debug;
50 };
51
52 static const struct command cmds[];
53
54 static int version(struct udev *udev, int argc, char *argv[])
55 {
56         printf("%s\n", VERSION);
57         return 0;
58 }
59
60 static int help(struct udev *udev, int argc, char *argv[])
61 {
62         const struct command *cmd;
63
64         printf("Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n");
65         for (cmd = cmds; cmd->name != NULL; cmd++)
66                 if (cmd->help != NULL)
67                         printf("  %-12s %s\n", cmd->name, cmd->help);
68         printf("\n");
69         return 0;
70 }
71
72 static const struct command cmds[] = {
73         {
74                 .name = "info",
75                 .cmd = udevadm_info,
76                 .help = "query sysfs or the udev database",
77         },
78         {
79                 .name = "trigger",
80                 .cmd = udevadm_trigger,
81                 .help = "request events from the kernel",
82         },
83         {
84                 .name = "settle",
85                 .cmd = udevadm_settle, "",
86                 .help = "wait for the event queue to finish",
87         },
88         {
89                 .name = "control",
90                 .cmd = udevadm_control,
91                 .help = "control the udev daemon",
92         },
93         {
94                 .name = "monitor",
95                 .cmd = udevadm_monitor,
96                 .help = "listen to kernel and udev events",
97         },
98         {
99                 .name = "test",
100                 .cmd = udevadm_test,
101                 .help = "simulation run",
102                 .debug = 1,
103         },
104         {
105                 .name = "version",
106                 .cmd = version,
107         },
108         {
109                 .name = "help",
110                 .cmd = help,
111         },
112         {}
113 };
114
115 static int run_command(struct udev *udev, const struct command *cmd, int argc, char *argv[])
116 {
117         if (cmd->debug) {
118                 debug = 1;
119                 if (udev_get_log_priority(udev) < LOG_INFO)
120                         udev_set_log_priority(udev, LOG_INFO);
121         }
122         info(udev, "calling: %s\n", cmd->name);
123         return cmd->cmd(udev, argc, argv);
124 }
125
126 int main(int argc, char *argv[])
127 {
128         struct udev *udev;
129         static const struct option options[] = {
130                 { "debug", 0, NULL, 'd' },
131                 { "help", 0, NULL, 'h' },
132                 { "version", 0, NULL, 'V' },
133                 {}
134         };
135         const char *command;
136         int i;
137         const char *pos;
138         int rc = 1;
139
140         udev = udev_new();
141         if (udev == NULL)
142                 goto out;
143
144         logging_init("udevadm");
145         udev_set_log_fn(udev, log_fn);
146         sysfs_init();
147
148         /* see if we are a compat link, this will be removed in a future release */
149         command = argv[0];
150         pos = strrchr(command, '/');
151         if (pos != NULL)
152                 command = &pos[1];
153
154         /* the trailing part of the binary or link name is the command */
155         if (strncmp(command, "udev", 4) == 0)
156                 command = &command[4];
157
158         for (i = 0; cmds[i].cmd != NULL; i++) {
159                 if (strcmp(cmds[i].name, command) == 0) {
160                         char path[128];
161                         char prog[512];
162                         ssize_t len;
163
164                         snprintf(path, sizeof(path), "/proc/%lu/exe", (unsigned long) getppid());
165                         len = readlink(path, prog, sizeof(prog));
166                         if (len > 0) {
167                                 prog[len] = '\0';
168                                 fprintf(stderr, "the program '%s' called '%s', it should use 'udevadm %s <options>', "
169                                        "this will stop working in a future release\n", prog, argv[0], command);
170                                 err(udev, "the program '%s' called '%s', it should use 'udevadm %s <options>', "
171                                     "this will stop working in a future release\n", prog, argv[0], command);
172                         }
173                         rc = run_command(udev, &cmds[i], argc, argv);
174                         goto out;
175                 }
176         }
177
178         while (1) {
179                 int option;
180
181                 option = getopt_long(argc, argv, "+dhV", options, NULL);
182                 if (option == -1)
183                         break;
184
185                 switch (option) {
186                 case 'd':
187                         debug = 1;
188                         if (udev_get_log_priority(udev) < LOG_INFO)
189                                 udev_set_log_priority(udev, LOG_INFO);
190                         break;
191                 case 'h':
192                         rc = help(udev, argc, argv);
193                         goto out;
194                 case 'V':
195                         rc = version(udev, argc, argv);
196                         goto out;
197                 default:
198                         goto out;
199                 }
200         }
201         command = argv[optind];
202
203         if (command != NULL)
204                 for (i = 0; cmds[i].cmd != NULL; i++) {
205                         if (strcmp(cmds[i].name, command) == 0) {
206                                 optind++;
207                                 rc = run_command(udev, &cmds[i], argc, argv);
208                                 goto out;
209                         }
210                 }
211
212         fprintf(stderr, "missing or unknown command\n\n");
213         help(udev, argc, argv);
214         rc = 2;
215 out:
216         sysfs_cleanup();
217         udev_unref(udev);
218         logging_close();
219         return rc;
220 }