]>
Commit | Line | Data |
---|---|---|
3b47c739 | 1 | /* |
e3396a2d | 2 | * Copyright (C) 2005-2006 Kay Sievers <kay.sievers@vrfy.org> |
3b47c739 | 3 | * |
3b47c739 KS |
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., | |
27b77df4 | 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
3b47c739 KS |
16 | * |
17 | */ | |
18 | ||
3b47c739 KS |
19 | #include <time.h> |
20 | #include <errno.h> | |
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <stddef.h> | |
24 | #include <string.h> | |
25 | #include <unistd.h> | |
9571122e KS |
26 | #include <sys/types.h> |
27 | #include <sys/socket.h> | |
28 | #include <sys/wait.h> | |
29 | #include <sys/un.h> | |
3b47c739 KS |
30 | |
31 | #include "udev.h" | |
3b47c739 | 32 | #include "udevd.h" |
3b47c739 | 33 | |
3b47c739 | 34 | static int sock = -1; |
916c5e47 | 35 | static int udev_log = 0; |
3b47c739 KS |
36 | |
37 | #ifdef USE_LOG | |
8ab44e3f | 38 | void log_message (int priority, const char *format, ...) |
3b47c739 KS |
39 | { |
40 | va_list args; | |
41 | ||
916c5e47 | 42 | if (priority > udev_log) |
8ab44e3f KS |
43 | return; |
44 | ||
3b47c739 | 45 | va_start(args, format); |
8ab44e3f | 46 | vsyslog(priority, format, args); |
3b47c739 KS |
47 | va_end(args); |
48 | } | |
49 | #endif | |
50 | ||
3b47c739 KS |
51 | int main(int argc, char *argv[], char *envp[]) |
52 | { | |
b3518c16 | 53 | static struct udevd_ctrl_msg ctrl_msg; |
3b47c739 KS |
54 | struct sockaddr_un saddr; |
55 | socklen_t addrlen; | |
8ab44e3f | 56 | const char *env; |
1343a952 | 57 | const char *arg; |
7628ff6e KS |
58 | const char *val; |
59 | int *intval; | |
3b47c739 KS |
60 | int retval = 1; |
61 | ||
8ab44e3f KS |
62 | env = getenv("UDEV_LOG"); |
63 | if (env) | |
916c5e47 | 64 | udev_log = log_priority(env); |
8ab44e3f | 65 | |
3b47c739 KS |
66 | logging_init("udevcontrol"); |
67 | dbg("version %s", UDEV_VERSION); | |
68 | ||
2b996ad1 KS |
69 | if (argc < 2) { |
70 | fprintf(stderr, "missing command\n\n"); | |
3b47c739 KS |
71 | goto exit; |
72 | } | |
b3518c16 KS |
73 | memset(&ctrl_msg, 0x00, sizeof(struct udevd_ctrl_msg)); |
74 | strcpy(ctrl_msg.magic, UDEVD_CTRL_MAGIC); | |
1343a952 HH |
75 | arg = argv[1]; |
76 | ||
77 | if (!strcmp(arg, "stop_exec_queue")) | |
78 | ctrl_msg.type = UDEVD_CTRL_STOP_EXEC_QUEUE; | |
79 | else if (!strcmp(arg, "start_exec_queue")) | |
80 | ctrl_msg.type = UDEVD_CTRL_START_EXEC_QUEUE; | |
81 | else if (!strcmp(arg, "reload_rules")) | |
82 | ctrl_msg.type = UDEVD_CTRL_RELOAD_RULES; | |
83 | else if (!strncmp(arg, "log_priority=", strlen("log_priority="))) { | |
84 | intval = (int *) ctrl_msg.buf; | |
85 | val = &arg[strlen("log_priority=")]; | |
86 | ctrl_msg.type = UDEVD_CTRL_SET_LOG_LEVEL; | |
87 | *intval = log_priority(val); | |
88 | info("send log_priority=%i", *intval); | |
89 | } else if (!strncmp(arg, "max_childs=", strlen("max_childs="))) { | |
90 | char *endp; | |
91 | int count; | |
92 | ||
93 | intval = (int *) ctrl_msg.buf; | |
94 | val = &arg[strlen("max_childs=")]; | |
95 | ctrl_msg.type = UDEVD_CTRL_SET_MAX_CHILDS; | |
96 | count = strtoul(val, &endp, 0); | |
97 | if (endp[0] != '\0' || count < 1) { | |
98 | fprintf(stderr, "invalid number\n"); | |
99 | goto exit; | |
100 | } | |
101 | *intval = count; | |
102 | info("send max_childs=%i", *intval); | |
103 | } else if (!strncmp(arg, "max_childs_running=", strlen("max_childs_running="))) { | |
104 | char *endp; | |
105 | int count; | |
106 | ||
107 | intval = (int *) ctrl_msg.buf; | |
108 | val = &arg[strlen("max_childs_running=")]; | |
109 | ctrl_msg.type = UDEVD_CTRL_SET_MAX_CHILDS_RUNNING; | |
110 | count = strtoul(val, &endp, 0); | |
111 | if (endp[0] != '\0' || count < 1) { | |
112 | fprintf(stderr, "invalid number\n"); | |
f1e9ccb9 | 113 | goto exit; |
1343a952 HH |
114 | } |
115 | *intval = count; | |
116 | info("send max_childs_running=%i", *intval); | |
117 | } else if (!strncmp(arg, "env", strlen("env"))) { | |
118 | val = argv[2]; | |
119 | if (val == NULL) { | |
120 | fprintf(stderr, "missing key\n"); | |
f1e9ccb9 | 121 | goto exit; |
2b996ad1 | 122 | } |
1343a952 HH |
123 | ctrl_msg.type = UDEVD_CTRL_ENV; |
124 | strlcpy(ctrl_msg.buf, val, sizeof(ctrl_msg.buf)); | |
125 | info("send env '%s'", val); | |
126 | } else if (strcmp(arg, "help") == 0 || strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) { | |
127 | printf("Usage: udevcontrol COMMAND\n" | |
128 | " log_priority=<level> set the udev log level for the daemon\n" | |
129 | " stop_exec_queue keep udevd from executing events, queue only\n" | |
130 | " start_exec_queue execute events, flush queue\n" | |
131 | " reload_rules reloads the rules files\n" | |
132 | " env <var>=<value> set a global environment variable\n" | |
133 | " max_childs=<N> maximum number of childs\n" | |
134 | " max_childs_running=<N> maximum number of childs running at the same time\n" | |
135 | " help print this help text\n\n"); | |
136 | goto exit; | |
137 | } else { | |
138 | fprintf(stderr, "unrecognized command '%s'\n", arg); | |
139 | goto exit; | |
2b996ad1 KS |
140 | } |
141 | ||
142 | if (getuid() != 0) { | |
e3396a2d | 143 | fprintf(stderr, "root privileges required\n"); |
f1e9ccb9 | 144 | goto exit; |
3b47c739 KS |
145 | } |
146 | ||
147 | sock = socket(AF_LOCAL, SOCK_DGRAM, 0); | |
148 | if (sock == -1) { | |
ff3e4bed | 149 | err("error getting socket: %s", strerror(errno)); |
3b47c739 KS |
150 | goto exit; |
151 | } | |
152 | ||
153 | memset(&saddr, 0x00, sizeof(struct sockaddr_un)); | |
154 | saddr.sun_family = AF_LOCAL; | |
155 | /* use abstract namespace for socket path */ | |
b3518c16 | 156 | strcpy(&saddr.sun_path[1], UDEVD_CTRL_SOCK_PATH); |
3b47c739 KS |
157 | addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; |
158 | ||
b3518c16 | 159 | retval = sendto(sock, &ctrl_msg, sizeof(ctrl_msg), 0, (struct sockaddr *)&saddr, addrlen); |
60d7b201 | 160 | if (retval == -1) { |
ff3e4bed | 161 | err("error sending message: %s", strerror(errno)); |
60d7b201 HR |
162 | retval = 1; |
163 | } else { | |
b3518c16 | 164 | dbg("sent message type=0x%02x, %u bytes sent", ctrl_msg.type, retval); |
60d7b201 HR |
165 | retval = 0; |
166 | } | |
3b47c739 KS |
167 | |
168 | close(sock); | |
3b47c739 KS |
169 | exit: |
170 | logging_close(); | |
3b47c739 KS |
171 | return retval; |
172 | } |