]>
git.ipfire.org Git - thirdparty/systemd.git/blob - udevtrigger.c
4 * Copyright (C) 2004-2006 Kay Sievers <kay@vrfy.org>
5 * Copyright (C) 2006 Hannes Reinecke <hare@suse.de>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation version 2 of the License.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <sys/types.h>
36 static const char *udev_log_str
;
41 void log_message(int priority
, const char *format
, ...)
45 if (priority
> udev_log_priority
)
48 va_start(args
, format
);
49 vsyslog(priority
, format
, args
);
54 /* list of devices that we should run last due to any one of a number of reasons */
55 static char *last_list
[] = {
63 /* list of devices that we should run first due to any one of a number of reasons */
64 static char *first_list
[] = {
70 LIST_HEAD(device_first_list
);
71 LIST_HEAD(device_default_list
);
72 LIST_HEAD(device_last_list
);
74 static int device_list_insert(const char *path
)
76 struct list_head
*device_list
= &device_default_list
;
79 for (i
= 0; first_list
[i
] != NULL
; i
++) {
80 if (strncmp(path
, first_list
[i
], strlen(first_list
[i
])) == 0) {
81 device_list
= &device_first_list
;
85 for (i
= 0; last_list
[i
] != NULL
; i
++) {
86 if (strncmp(path
, last_list
[i
], strlen(last_list
[i
])) == 0) {
87 device_list
= &device_last_list
;
92 dbg("add '%s'" , path
);
93 /* double entries will be ignored */
94 name_list_add(device_list
, path
, 0);
98 static void trigger_uevent(const char *path
)
100 char filename
[PATH_SIZE
];
103 strlcpy(filename
, path
, sizeof(filename
));
104 strlcat(filename
, "/uevent", sizeof(filename
));
107 printf("%s\n", path
);
112 fd
= open(filename
, O_WRONLY
);
114 dbg("error on opening %s: %s\n", filename
, strerror(errno
));
118 if (write(fd
, "add", 3) < 0)
119 info("error on triggering %s: %s\n", filename
, strerror(errno
));
124 static void exec_lists(void)
126 struct name_entry
*loop_device
;
127 struct name_entry
*tmp_device
;
129 /* handle the devices on the "first" list first */
130 list_for_each_entry_safe(loop_device
, tmp_device
, &device_first_list
, node
) {
131 trigger_uevent(loop_device
->name
);
132 list_del(&loop_device
->node
);
136 /* handle the devices on the "default" list next */
137 list_for_each_entry_safe(loop_device
, tmp_device
, &device_default_list
, node
) {
138 trigger_uevent(loop_device
->name
);
139 list_del(&loop_device
->node
);
143 /* handle devices on the "last" list, if any */
144 list_for_each_entry_safe(loop_device
, tmp_device
, &device_last_list
, node
) {
145 trigger_uevent(loop_device
->name
);
146 list_del(&loop_device
->node
);
151 static int is_device(const char *path
)
153 char filename
[PATH_SIZE
];
156 /* look for the uevent file of the kobject */
157 strlcpy(filename
, path
, sizeof(filename
));
158 strlcat(filename
, "/uevent", sizeof(filename
));
159 if (stat(filename
, &statbuf
) < 0)
162 if (!(statbuf
.st_mode
& S_IWUSR
))
168 static void udev_scan_bus(void)
170 char base
[PATH_SIZE
];
174 strlcpy(base
, sysfs_path
, sizeof(base
));
175 strlcat(base
, "/bus", sizeof(base
));
179 for (dent
= readdir(dir
); dent
!= NULL
; dent
= readdir(dir
)) {
180 char dirname
[PATH_SIZE
];
182 struct dirent
*dent2
;
184 if (dent
->d_name
[0] == '.')
187 strlcpy(dirname
, base
, sizeof(dirname
));
188 strlcat(dirname
, "/", sizeof(dirname
));
189 strlcat(dirname
, dent
->d_name
, sizeof(dirname
));
190 strlcat(dirname
, "/devices", sizeof(dirname
));
192 /* look for devices */
193 dir2
= opendir(dirname
);
195 for (dent2
= readdir(dir2
); dent2
!= NULL
; dent2
= readdir(dir2
)) {
196 char dirname2
[PATH_SIZE
];
198 if (dent2
->d_name
[0] == '.')
201 strlcpy(dirname2
, dirname
, sizeof(dirname2
));
202 strlcat(dirname2
, "/", sizeof(dirname2
));
203 strlcat(dirname2
, dent2
->d_name
, sizeof(dirname2
));
205 if (is_device(dirname2
))
206 device_list_insert(dirname2
);
215 static void udev_scan_block(void)
217 char base
[PATH_SIZE
];
222 /* skip if "block" is already a "class" */
223 strlcpy(base
, sysfs_path
, sizeof(base
));
224 strlcat(base
, "/class/block", sizeof(base
));
225 if (stat(base
, &statbuf
) == 0)
228 strlcpy(base
, sysfs_path
, sizeof(base
));
229 strlcat(base
, "/block", sizeof(base
));
233 for (dent
= readdir(dir
); dent
!= NULL
; dent
= readdir(dir
)) {
234 char dirname
[PATH_SIZE
];
236 struct dirent
*dent2
;
238 if (dent
->d_name
[0] == '.')
241 strlcpy(dirname
, base
, sizeof(dirname
));
242 strlcat(dirname
, "/", sizeof(dirname
));
243 strlcat(dirname
, dent
->d_name
, sizeof(dirname
));
244 if (is_device(dirname
))
245 device_list_insert(dirname
);
249 /* look for partitions */
250 dir2
= opendir(dirname
);
252 for (dent2
= readdir(dir2
); dent2
!= NULL
; dent2
= readdir(dir2
)) {
253 char dirname2
[PATH_SIZE
];
255 if (dent2
->d_name
[0] == '.')
258 if (!strcmp(dent2
->d_name
,"device"))
261 strlcpy(dirname2
, dirname
, sizeof(dirname2
));
262 strlcat(dirname2
, "/", sizeof(dirname2
));
263 strlcat(dirname2
, dent2
->d_name
, sizeof(dirname2
));
264 if (is_device(dirname2
))
265 device_list_insert(dirname2
);
274 static void udev_scan_class(void)
276 char base
[PATH_SIZE
];
280 strlcpy(base
, sysfs_path
, sizeof(base
));
281 strlcat(base
, "/class", sizeof(base
));
285 for (dent
= readdir(dir
); dent
!= NULL
; dent
= readdir(dir
)) {
286 char dirname
[PATH_SIZE
];
288 struct dirent
*dent2
;
290 if (dent
->d_name
[0] == '.')
293 strlcpy(dirname
, base
, sizeof(dirname
));
294 strlcat(dirname
, "/", sizeof(dirname
));
295 strlcat(dirname
, dent
->d_name
, sizeof(dirname
));
296 dir2
= opendir(dirname
);
298 for (dent2
= readdir(dir2
); dent2
!= NULL
; dent2
= readdir(dir2
)) {
299 char dirname2
[PATH_SIZE
];
301 if (dent2
->d_name
[0] == '.')
304 if (!strcmp(dent2
->d_name
, "device"))
307 strlcpy(dirname2
, dirname
, sizeof(dirname2
));
308 strlcat(dirname2
, "/", sizeof(dirname2
));
309 strlcat(dirname2
, dent2
->d_name
, sizeof(dirname2
));
310 if (is_device(dirname2
))
311 device_list_insert(dirname2
);
320 int main(int argc
, char *argv
[], char *envp
[])
324 logging_init("udevtrigger");
326 dbg("version %s", UDEV_VERSION
);
328 udev_log_str
= getenv("UDEV_LOG");
330 for (i
= 1 ; i
< argc
; i
++) {
333 if (strcmp(arg
, "--verbose") == 0 || strcmp(arg
, "-v") == 0)
335 else if (strcmp(arg
, "--dry-run") == 0 || strcmp(arg
, "-n") == 0)
338 fprintf(stderr
, "Usage: udevtrigger [--verbose] [--dry-run]\n");