summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/udev/files/udevsynthesize.patch
diff options
context:
space:
mode:
authorOtavio Salvador <otavio@ossystems.com.br>2011-12-20 13:00:05 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-01-03 12:14:27 +0000
commitf4e60ec827d574efdd74663c4904a7da51304fcc (patch)
tree43959cb13d4b1a13734dad04f79921316e8e8c19 /meta/recipes-core/udev/files/udevsynthesize.patch
parenta99a63959b2e91519a26ff6305729b1072e638fa (diff)
downloadpoky-f4e60ec827d574efdd74663c4904a7da51304fcc.tar.gz
udev: drop 145 version
The 164 version has been the default version for some time and as we don't have any clear reasoning to keep 145 around, we're removing it now. Some files were also removed as 164 recipe provides specific versions of it and thus those were going to be unused. (From OE-Core rev: 7376f027c39716561b513a70f6e7f86fb14df178) Signed-off-by: Otavio Salvador <otavio@ossystems.com.br> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
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 = \