summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/udev/files/udevsynthesize.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/udev/files/udevsynthesize.patch')
-rw-r--r--meta/recipes-core/udev/files/udevsynthesize.patch778
1 files changed, 0 insertions, 778 deletions
diff --git a/meta/recipes-core/udev/files/udevsynthesize.patch b/meta/recipes-core/udev/files/udevsynthesize.patch
deleted file mode 100644
index 5122ea2b22..0000000000
--- a/meta/recipes-core/udev/files/udevsynthesize.patch
+++ /dev/null
@@ -1,778 +0,0 @@
1Upstream-Status: Inappropriate [distribution]
2
3--- udev-081/udevsynthesize.c.orig 2006-01-29 12:22:45.000000000 +0100
4+++ udev-081/udevsynthesize.c 2006-01-29 12:22:40.000000000 +0100
5@@ -0,0 +1,763 @@
6+/*
7+ * udevcoldplug.c
8+ *
9+ * Copyright (C) 2005 SUSE Linux Products GmbH
10+ *
11+ * Author:
12+ * Kay Sievers <kay.sievers@vrfy.org>
13+ *
14+ * Synthesize kernel events from sysfs information and pass them
15+ * to the udevd daemon.
16+ *
17+ * This program is free software; you can redistribute it and/or modify it
18+ * under the terms of the GNU General Public License as published by the
19+ * Free Software Foundation version 2 of the License.
20+ *
21+ * This program is distributed in the hope that it will be useful, but
22+ * WITHOUT ANY WARRANTY; without even the implied warranty of
23+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24+ * General Public License for more details.
25+ *
26+ * You should have received a copy of the GNU General Public License along
27+ * with this program; if not, write to the Free Software Foundation, Inc.,
28+ * 675 Mass Ave, Cambridge, MA 02139, USA.
29+ *
30+ */
31+
32+#include <stdlib.h>
33+#include <stddef.h>
34+#include <string.h>
35+#include <stdio.h>
36+#include <unistd.h>
37+#include <errno.h>
38+#include <ctype.h>
39+#include <fcntl.h>
40+#include <dirent.h>
41+#include <signal.h>
42+#include <syslog.h>
43+#include <sys/socket.h>
44+#include <sys/un.h>
45+#include <sys/wait.h>
46+#include <sys/stat.h>
47+#include <sys/types.h>
48+
49+#include "udev_libc_wrapper.h"
50+#include "udev.h"
51+#include "udevd.h"
52+#include "udev_version.h"
53+#include "logging.h"
54+
55+#include "list.h"
56+
57+#ifndef DT_DIR
58+#define DT_DIR 4
59+#endif
60+
61+static const char *udev_log_str;
62+static int udevd_sock = -1;
63+
64+#ifdef USE_LOG
65+void log_message(int priority, const char *format, ...)
66+{
67+ va_list args;
68+
69+ if (priority > udev_log_priority)
70+ return;
71+
72+ va_start(args, format);
73+ vsyslog(priority, format, args);
74+ va_end(args);
75+}
76+#endif
77+
78+struct device {
79+ struct list_head node;
80+ struct udevd_msg msg;
81+ size_t bufpos;
82+ char *path;
83+};
84+
85+static dev_t read_devt(const char *path)
86+{
87+ char filename[PATH_SIZE];
88+ char majorminor[64];
89+ unsigned int major, minor;
90+ ssize_t count;
91+ int fd;
92+
93+ snprintf(filename, sizeof(filename), "%s/%s", path, "dev");
94+ filename[sizeof(filename)-1] = '\0';
95+
96+ fd = open(filename, O_RDONLY);
97+ if (fd < 0)
98+ return 0;
99+
100+ count = read(fd, majorminor, sizeof(majorminor));
101+ close(fd);
102+ majorminor[count] = '\0';
103+ if (sscanf(majorminor, "%u:%u", &major, &minor) != 2)
104+ return 0;
105+ dbg("found major=%d, minor=%d", major, minor);
106+
107+ return makedev(major, minor);
108+}
109+
110+static ssize_t read_file(const char *directory, const char *file, char *str, size_t len)
111+{
112+ char filename[PATH_SIZE];
113+ ssize_t count;
114+ int fd;
115+
116+ memset(filename, 0, sizeof(filename));
117+ snprintf(filename, sizeof(filename), "%s/%s", directory, file);
118+ filename[sizeof(filename)-1] = '\0';
119+
120+ fd = open(filename, O_RDONLY);
121+ if (fd < 0)
122+ return -1;
123+
124+ count = read(fd, str, len-1);
125+ close(fd);
126+
127+ if (count > (ssize_t)len)
128+ count = len;
129+ str[count-1] = '\0';
130+
131+ return count;
132+}
133+
134+static ssize_t read_link(const char *directory, const char *file, char *str, size_t size)
135+{
136+ char filename[PATH_SIZE];
137+ char target[PATH_SIZE];
138+ int len;
139+ char *back;
140+ char *strip;
141+ int level = 1;
142+
143+ snprintf(filename, sizeof(filename), "%s/%s", directory, file);
144+ filename[sizeof(filename)-1] = '\0';
145+
146+ len = readlink(filename, target, sizeof(target)-1);
147+ if (len < 0)
148+ return -1;
149+ target[len] = '\0';
150+
151+ back = target;
152+ while (strncmp(back, "../", 3) == 0) {
153+ back += 3;
154+ level++;
155+ }
156+ while(level--) {
157+ strip = strrchr(filename, '/');
158+ if (!strip)
159+ return -1;
160+ strip[0] = '\0';
161+ }
162+
163+ snprintf(str, size, "%s/%s", filename, back);
164+ str[size-1] = '\0';
165+
166+ return len;
167+}
168+
169+static char *add_env_key(struct device *device, const char *key, const char *value)
170+{
171+ size_t pos = device->bufpos;
172+ device->bufpos += sprintf(&device->msg.envbuf[device->bufpos], "%s=%s", key, value)+1;
173+ return &device->msg.envbuf[pos];
174+}
175+
176+static struct device *device_create(const char *path, const char *subsystem, dev_t devt)
177+{
178+ struct device *device;
179+ const char *devpath = &path[strlen(sysfs_path)];
180+ char target[PATH_SIZE];
181+
182+ device = malloc(sizeof(struct device));
183+ if (device == NULL) {
184+ dbg("error malloc");
185+ return NULL;
186+ }
187+ memset(device, 0x00, sizeof(struct device));
188+
189+ device->path = add_env_key(device, "DEVPATH", devpath);
190+ device->path += strlen("DEVPATH=");
191+ add_env_key(device, "SUBSYSTEM", subsystem);
192+ add_env_key(device, "ACTION", "add");
193+ add_env_key(device, "UDEV_COLDPLUG", "1");
194+
195+ if (major(devt)) {
196+ char number[32];
197+ sprintf(number, "%u", major(devt));
198+ add_env_key(device, "MAJOR", number);
199+ sprintf(number, "%u", minor(devt));
200+ add_env_key(device, "MINOR", number);
201+ }
202+
203+ if (strncmp(devpath, "/block/", strlen("/block/")) == 0 ||
204+ strncmp(devpath, "/class/", strlen("/class/")) == 0) {
205+ char physpath[PATH_SIZE];
206+
207+ if (read_link(path, "device", physpath, sizeof(physpath)) > (ssize_t)strlen(sysfs_path)) {
208+ add_env_key(device, "PHYSDEVPATH", &physpath[strlen(sysfs_path)]);
209+ if (read_link(physpath, "driver", target, sizeof(target)) > (ssize_t)strlen(sysfs_path)) {
210+ char *pos = strrchr(target, '/');
211+ if (pos)
212+ add_env_key(device, "PHYSDEVDRIVER", &pos[1]);
213+ }
214+ if (read_link(physpath, "bus", target, sizeof(target)) > (ssize_t)strlen(sysfs_path)) {
215+ char *pos = strrchr(target, '/');
216+ if (pos)
217+ add_env_key(device, "PHYSDEVBUS", &pos[1]);
218+ }
219+ }
220+ } else if (strncmp(devpath, "/devices/", strlen("/devices/")) == 0) {
221+ if (read_link(path, "driver", target, sizeof(target)) > (ssize_t)strlen(sysfs_path)) {
222+ char *pos = strrchr(target, '/');
223+ if (pos)
224+ add_env_key(device, "PHYSDEVDRIVER", &pos[1]);
225+ }
226+ if (read_link(path, "bus", target, sizeof(target)) > (ssize_t)strlen(sysfs_path)) {
227+ char *pos = strrchr(target, '/');
228+ if (pos)
229+ add_env_key(device, "PHYSDEVBUS", &pos[1]);
230+ }
231+ }
232+
233+ return device;
234+}
235+
236+static int device_list_insert(struct list_head *device_list, struct device *device)
237+{
238+ struct device *loop_device;
239+
240+ dbg("insert: '%s'", device->path);
241+
242+ /* sort files in lexical order */
243+ list_for_each_entry(loop_device, device_list, node)
244+ if (strcmp(loop_device->path, device->path) > 0)
245+ break;
246+
247+ list_add_tail(&device->node, &loop_device->node);
248+
249+ return 0;
250+}
251+
252+static int add_device_udevd(struct device *device)
253+{
254+ size_t msg_len;
255+ struct sockaddr_un saddr;
256+ socklen_t addrlen;
257+ int retval;
258+
259+ memset(&saddr, 0x00, sizeof(struct sockaddr_un));
260+ saddr.sun_family = AF_LOCAL;
261+ /* use abstract namespace for socket path */
262+ strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH);
263+ addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1;
264+
265+ strcpy(device->msg.magic, UDEV_MAGIC);
266+ device->msg.type = UDEVD_UEVENT_UDEVSEND;
267+
268+ msg_len = offsetof(struct udevd_msg, envbuf) + device->bufpos;
269+ dbg("msg_len=%i", msg_len);
270+
271+ retval = sendto(udevd_sock, &device->msg, msg_len, 0, (struct sockaddr *)&saddr, addrlen);
272+ if (retval < 0)
273+ return -1;
274+
275+ return 0;
276+}
277+
278+static void exec_list(struct list_head *device_list, const char *first[], const char *last[])
279+{
280+ struct device *loop_device;
281+ struct device *tmp_device;
282+ int i;
283+
284+ /* handle the "first" type devices first */
285+ if (first)
286+ list_for_each_entry_safe(loop_device, tmp_device, device_list, node) {
287+ for (i = 0; first[i] != NULL; i++) {
288+ if (strncmp(loop_device->path, first[i], strlen(first[i])) == 0) {
289+ add_device_udevd(loop_device);
290+ list_del(&loop_device->node);
291+ free(loop_device);
292+ break;
293+ }
294+ }
295+ }
296+
297+ /* handle the devices we are allowed to, excluding the "last" type devices */
298+ if (last)
299+ list_for_each_entry_safe(loop_device, tmp_device, device_list, node) {
300+ int found = 0;
301+ for (i = 0; last[i] != NULL; i++) {
302+ if (strncmp(loop_device->path, last[i], strlen(last[i])) == 0) {
303+ found = 1;
304+ break;
305+ }
306+ }
307+ if (found)
308+ continue;
309+
310+ add_device_udevd(loop_device);
311+ list_del(&loop_device->node);
312+ free(loop_device);
313+ }
314+
315+ /* handle the rest of the devices */
316+ list_for_each_entry_safe(loop_device, tmp_device, device_list, node) {
317+ add_device_udevd(loop_device);
318+ list_del(&loop_device->node);
319+ free(loop_device);
320+ }
321+}
322+
323+static int udev_scan_class(void)
324+{
325+ char base[PATH_SIZE];
326+ DIR *dir;
327+ struct dirent *dent;
328+ LIST_HEAD(device_list);
329+
330+ /* we want /dev/null and /dev/console first */
331+ const char *first[] = {
332+ "/class/mem",
333+ "/class/tty",
334+ NULL,
335+ };
336+
337+ snprintf(base, sizeof(base), "%s/class", sysfs_path);
338+ base[sizeof(base)-1] = '\0';
339+
340+ dir = opendir(base);
341+ if (!dir)
342+ return -1;
343+
344+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
345+ char dirname[PATH_SIZE];
346+ DIR *dir2;
347+ struct dirent *dent2;
348+
349+ if (dent->d_name[0] == '.')
350+ continue;
351+
352+ snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name);
353+ dirname[sizeof(dirname)-1] = '\0';
354+
355+ dir2 = opendir(dirname);
356+ if (!dir2)
357+ continue;
358+ for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
359+ char dirname2[PATH_SIZE];
360+ struct device *device;
361+ dev_t devt;
362+
363+ if (dent2->d_name[0] == '.')
364+ continue;
365+ if (dent2->d_type != DT_DIR)
366+ continue;
367+
368+ snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name);
369+ dirname2[sizeof(dirname2)-1] = '\0';
370+ devt = read_devt(dirname2);
371+ device = device_create(dirname2, dent->d_name, devt);
372+
373+ if (strcmp(dent->d_name, "net") == 0 ||
374+ strcmp(dent->d_name, "bluetooth") == 0) {
375+ add_env_key(device, "INTERFACE", dent2->d_name);
376+ } else if (strcmp(dent->d_name, "pcmcia_socket") == 0 &&
377+ strlen(dent->d_name) > 14) {
378+ add_env_key(device, "SOCKET_NO",
379+ dent2->d_name + 14);
380+ }
381+
382+ device_list_insert(&device_list, device);
383+ }
384+ closedir(dir2);
385+ }
386+ closedir(dir);
387+ exec_list(&device_list, first, NULL);
388+
389+ return 0;
390+}
391+
392+static int udev_scan_block(void)
393+{
394+ char base[PATH_SIZE];
395+ DIR *dir;
396+ struct dirent *dent;
397+ LIST_HEAD(device_list);
398+
399+ /* dm wants to have the block devices around before it */
400+ const char *last[] = {
401+ "/block/dm",
402+ NULL,
403+ };
404+
405+ snprintf(base, sizeof(base), "%s/block", sysfs_path);
406+ base[sizeof(base)-1] = '\0';
407+
408+ dir = opendir(base);
409+ if (!dir)
410+ return -1;
411+
412+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
413+ char dirname[PATH_SIZE];
414+ struct device *device;
415+ struct dirent *dent2;
416+ DIR *dir2;
417+ dev_t devt;
418+
419+ if (dent->d_name[0] == '.')
420+ continue;
421+ if (dent->d_type != DT_DIR)
422+ continue;
423+
424+ snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name);
425+ dirname[sizeof(dirname)-1] = '\0';
426+ devt = read_devt(dirname);
427+ if (major(devt)) {
428+ device = device_create(dirname, "block", devt);
429+ device_list_insert(&device_list, device);
430+ }
431+
432+ /* look for partitions */
433+ dir2 = opendir(dirname);
434+ if (!dir2)
435+ continue;
436+ for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) {
437+ char dirname2[PATH_SIZE];
438+
439+ if (dent2->d_name[0] == '.')
440+ continue;
441+ if (dent2->d_type != DT_DIR)
442+ continue;
443+
444+ snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name);
445+ dirname2[sizeof(dirname2)-1] = '\0';
446+ devt = read_devt(dirname2);
447+ if (major(devt)) {
448+ device = device_create(dirname2, "block", devt);
449+ device_list_insert(&device_list, device);
450+ continue;
451+ }
452+ }
453+ closedir(dir2);
454+ }
455+ closedir(dir);
456+ exec_list(&device_list, NULL, last);
457+
458+ return 0;
459+}
460+
461+static int pci_handler(struct device *device)
462+{
463+ char path[PATH_SIZE];
464+ char value[PATH_SIZE];
465+ char vendor[PATH_SIZE];
466+ char product[PATH_SIZE];
467+ const char *name;
468+
469+ snprintf(path, sizeof(path), "%s%s", sysfs_path, device->path);
470+ path[sizeof(path)-1] = '\0';
471+
472+ if (read_file(path, "modalias", value, sizeof(value)) > 0)
473+ add_env_key(device, "MODALIAS", value);
474+
475+ name = strrchr(device->path, '/');
476+ if (name)
477+ add_env_key(device, "PCI_SLOT_NAME", &name[1]);
478+
479+ if (read_file(path, "class", value, sizeof(value)) > 0)
480+ add_env_key(device, "PCI_CLASS", &value[2]);
481+
482+ if (read_file(path, "vendor", vendor, sizeof(vendor)) > 0 &&
483+ read_file(path, "device", product, sizeof(product)) > 0) {
484+ snprintf(value, sizeof(value), "%s:%s", &vendor[2], &product[2]);
485+ path[sizeof(value)-1] = '\0';
486+ add_env_key(device, "PCI_ID", value);
487+ }
488+
489+ if (read_file(path, "subsystem_vendor", vendor, sizeof(vendor)) > 0 &&
490+ read_file(path, "subsystem_device", product, sizeof(product)) > 0) {
491+ snprintf(value, sizeof(value), "%s:%s", &vendor[2], &product[2]);
492+ path[sizeof(value)-1] = '\0';
493+ add_env_key(device, "PCI_SUBSYS_ID", value);
494+ }
495+
496+ return 0;
497+}
498+
499+static int usb_handler(struct device *device)
500+{
501+ char path[PATH_SIZE];
502+ char value[PATH_SIZE];
503+ char str1[PATH_SIZE];
504+ char str2[PATH_SIZE];
505+ char str3[PATH_SIZE];
506+ unsigned int int1;
507+ unsigned int int2;
508+ unsigned int int3;
509+ char *pos;
510+
511+ snprintf(path, sizeof(path), "%s%s", sysfs_path, device->path);
512+ path[sizeof(path)-1] = '\0';
513+
514+ /* device events have : in their directory name */
515+ pos = strrchr(path, '/');
516+ if (!strchr(pos, ':'))
517+ return 0; /* and do not have other variables */
518+
519+ if (read_file(path, "modalias", value, sizeof(value)) > 0)
520+ add_env_key(device, "MODALIAS", value);
521+
522+ if (read_file(path, "bInterfaceClass", str1, sizeof(str1)) > 0 &&
523+ read_file(path, "bInterfaceSubClass", str2, sizeof(str2)) > 0 &&
524+ read_file(path, "bInterfaceProtocol", str3, sizeof(str3)) > 0) {
525+ int1 = (int) strtol(str1, NULL, 16);
526+ int2 = (int) strtol(str2, NULL, 16);
527+ int3 = (int) strtol(str3, NULL, 16);
528+ snprintf(value, sizeof(value), "%u/%u/%u", int1, int2, int3);
529+ path[sizeof(value)-1] = '\0';
530+ add_env_key(device, "INTERFACE", value);
531+ }
532+
533+ /* move to the parent directory */
534+ pos[0] = '\0';
535+
536+ if (read_file(path, "idVendor", str1, sizeof(str1)) > 0 &&
537+ read_file(path, "idProduct", str2, sizeof(str2)) > 0 &&
538+ read_file(path, "bcdDevice", str3, sizeof(str3)) > 0) {
539+ int1 = (int) strtol(str1, NULL, 16);
540+ int2 = (int) strtol(str2, NULL, 16);
541+ int3 = (int) strtol(str3, NULL, 16);
542+ snprintf(value, sizeof(value), "%x/%x/%x", int1, int2, int3);
543+ path[sizeof(value)-1] = '\0';
544+ add_env_key(device, "PRODUCT", value);
545+ }
546+
547+ if (read_file(path, "bDeviceClass", str1, sizeof(str1)) > 0 &&
548+ read_file(path, "bDeviceSubClass", str2, sizeof(str2)) > 0 &&
549+ read_file(path, "bDeviceProtocol", str3, sizeof(str3)) > 0) {
550+ int1 = (int) strtol(str1, NULL, 16);
551+ int2 = (int) strtol(str2, NULL, 16);
552+ int3 = (int) strtol(str3, NULL, 16);
553+ snprintf(value, sizeof(value), "%u/%u/%u", int1, int2, int3);
554+ path[sizeof(value)-1] = '\0';
555+ add_env_key(device, "TYPE", value);
556+ }
557+
558+ if (read_file(path, "devnum", str2, sizeof(str2)) > 0) {
559+ pos = strrchr(path, 'b');
560+ int1 = (int) strtol(pos + 1, NULL, 16);
561+ int2 = (int) strtol(str2, NULL, 16);
562+ snprintf(value, sizeof(value),
563+ "/proc/bus/usb/%03d/%03d", int1, int2);
564+ path[sizeof(value)-1] = '\0';
565+ add_env_key(device, "DEVICE", value);
566+ }
567+
568+ return 0;
569+}
570+
571+static int serio_handler(struct device *device)
572+{
573+ char path[PATH_SIZE];
574+ char value[PATH_SIZE];
575+
576+ snprintf(path, sizeof(path), "%s%s", sysfs_path, device->path);
577+ path[sizeof(path)-1] = '\0';
578+
579+ if (read_file(path, "modalias", value, sizeof(value)) > 0)
580+ add_env_key(device, "MODALIAS", value);
581+
582+ if (read_file(path, "id/type", value, sizeof(value)) > 0)
583+ add_env_key(device, "SERIO_TYPE", value);
584+
585+ if (read_file(path, "id/proto", value, sizeof(value)) > 0)
586+ add_env_key(device, "SERIO_PROTO", value);
587+
588+ if (read_file(path, "id/id", value, sizeof(value)) > 0)
589+ add_env_key(device, "SERIO_ID", value);
590+
591+ if (read_file(path, "id/extra", value, sizeof(value)) > 0)
592+ add_env_key(device, "SERIO_EXTRA", value);
593+
594+ return 0;
595+}
596+
597+static int ccw_handler(struct device *device)
598+{
599+ char path[PATH_SIZE];
600+ char value[PATH_SIZE], *tmp;
601+
602+ snprintf(path, sizeof(path), "%s%s", sysfs_path, device->path);
603+ path[sizeof(path)-1] = '\0';
604+
605+ if (read_file(path, "modalias", value, sizeof(value)) > 0)
606+ add_env_key(device, "MODALIAS", value);
607+
608+ if (read_file(path, "cutype", value, sizeof(value)) > 0) {
609+ value[4] = 0;
610+ tmp = &value[5];
611+ add_env_key(device, "CU_TYPE", value);
612+ add_env_key(device, "CU_MODEL", tmp);
613+ }
614+
615+ if (read_file(path, "devtype", value, sizeof(value)) > 0) {
616+ if (value[0] == 'n') {
617+ add_env_key(device, "DEV_TYPE", "0000");
618+ add_env_key(device, "DEV_MODEL", "00");
619+ }
620+ else {
621+ value[4] = 0;
622+ tmp = &value[5];
623+ add_env_key(device, "DEV_TYPE", value);
624+ add_env_key(device, "DEV_MODEL", tmp);
625+ }
626+ }
627+
628+ return 0;
629+}
630+
631+static int modalias_handler(struct device *device)
632+{
633+ char path[PATH_SIZE];
634+ char value[PATH_SIZE];
635+
636+ snprintf(path, sizeof(path), "%s%s", sysfs_path, device->path);
637+ path[sizeof(path)-1] = '\0';
638+
639+ if (read_file(path, "modalias", value, sizeof(value)) > 0)
640+ add_env_key(device, "MODALIAS", value);
641+
642+ return 0;
643+}
644+
645+static int udev_scan_bus(const char *bus, int bus_handler(struct device *device))
646+{
647+ char base[PATH_SIZE];
648+ DIR *dir;
649+ struct dirent *dent;
650+ LIST_HEAD(device_list);
651+
652+ snprintf(base, sizeof(base), "%s/bus/%s/devices", sysfs_path, bus);
653+ base[sizeof(base)-1] = '\0';
654+
655+ dir = opendir(base);
656+ if (!dir)
657+ return -1;
658+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
659+ char devpath[PATH_SIZE];
660+ struct device *device;
661+
662+ if (dent->d_name[0] == '.')
663+ continue;
664+
665+ if (read_link(base, dent->d_name, devpath, sizeof(devpath)) < 0)
666+ continue;
667+
668+ device = device_create(devpath, bus, makedev(0, 0));
669+ if (bus_handler) {
670+ if (bus_handler(device) < 0) {
671+ dbg("'%s' bus handler skipped event", devpath);
672+ free(device);
673+ continue;
674+ }
675+ }
676+
677+ device_list_insert(&device_list, device);
678+ }
679+ closedir(dir);
680+ exec_list(&device_list, NULL, NULL);
681+
682+ return 0;
683+}
684+
685+static int udev_scan_devices(void)
686+{
687+ char base[PATH_SIZE];
688+ DIR *dir;
689+ struct dirent *dent;
690+
691+ snprintf(base, sizeof(base), "%s/bus", sysfs_path);
692+ base[sizeof(base)-1] = '\0';
693+
694+ dir = opendir(base);
695+ if (!dir)
696+ return -1;
697+
698+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
699+ if (dent->d_name[0] == '.')
700+ continue;
701+ if (dent->d_type != DT_DIR)
702+ continue;
703+
704+ /* add bus specific env values */
705+ if (strcmp(dent->d_name, "pci") == 0)
706+ udev_scan_bus("pci", pci_handler);
707+ else if (strcmp(dent->d_name, "usb") == 0)
708+ udev_scan_bus("usb", usb_handler);
709+ else if (strcmp(dent->d_name, "serio") == 0)
710+ udev_scan_bus("serio", serio_handler);
711+ else if (strcmp(dent->d_name, "ccw") == 0)
712+ udev_scan_bus("ccw", ccw_handler);
713+ else
714+ udev_scan_bus(dent->d_name, modalias_handler);
715+ }
716+ closedir(dir);
717+
718+ return 0;
719+}
720+
721+int main(int argc, char *argv[], char *envp[])
722+{
723+ LIST_HEAD(device_list);
724+ int i;
725+
726+ logging_init("udevcoldplug");
727+ udev_config_init(); sysfs_init();
728+ dbg("version %s", UDEV_VERSION);
729+
730+ udev_log_str = getenv("UDEV_LOG");
731+
732+ /* disable all logging if not explicitely requested */
733+ if (udev_log_str == NULL)
734+ udev_log_priority = 0;
735+
736+ for (i = 1 ; i < argc; i++) {
737+ char *arg = argv[i];
738+
739+ if (strcmp(arg, "help") == 0 || strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0) {
740+ printf("Usage: udevcoldplug \n"
741+ " --help print this help text\n\n");
742+ exit(0);
743+ } else {
744+ fprintf(stderr, "unknown option\n\n");
745+ exit(1);
746+ }
747+ }
748+
749+ udevd_sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
750+ if (udevd_sock < 0) {
751+ err("error getting socket");
752+ return 1;
753+ }
754+
755+ /* create nodes for already available devices */
756+ udev_scan_class();
757+ udev_scan_block();
758+
759+ /* synthesize events for bus devices
760+ * may load modules or configure the device */
761+ udev_scan_devices();
762+
763+ if (udevd_sock >= 0)
764+ close(udevd_sock);
765+ logging_close();
766+
767+ return 0;
768+}
769--- udev-081/Makefile
770+++ udev-081/Makefile
771@@ -58,6 +58,7 @@ PROGRAMS = \
772 udevmonitor \
773 udevinfo \
774 udevtest \
775+ udevsynthesize \
776 udevstart
777
778 HEADERS = \