chiark / gitweb /
9ef4610a6af99e2bd77fb42ddbd4207931b7b239
[elogind.git] / src / libudev / libudev-device.c
1 /*
2  * libudev - interface to udev device information
3  *
4  * Copyright (C) 2008-2010 Kay Sievers <kay.sievers@vrfy.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <stddef.h>
15 #include <unistd.h>
16 #include <stdbool.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <ctype.h>
22 #include <net/if.h>
23 #include <sys/stat.h>
24 #include <sys/ioctl.h>
25 #include <sys/socket.h>
26 #include <linux/sockios.h>
27
28 #include "libudev.h"
29 #include "libudev-private.h"
30
31 /**
32  * SECTION:libudev-device
33  * @short_description: kernel sys devices
34  *
35  * Representation of kernel sys devices. Devices are uniquely identified
36  * by their syspath, every device has exactly one path in the kernel sys
37  * filesystem. Devices usually belong to a kernel subsystem, and and have
38  * a unique name inside that subsystem.
39  */
40
41 /**
42  * udev_device:
43  *
44  * Opaque object representing one kernel sys device.
45  */
46 struct udev_device {
47         struct udev *udev;
48         struct udev_device *parent_device;
49         char *syspath;
50         const char *devpath;
51         char *sysname;
52         const char *sysnum;
53         char *devnode;
54         mode_t devnode_mode;
55         char *subsystem;
56         char *devtype;
57         char *driver;
58         char *action;
59         char *devpath_old;
60         char *id_filename;
61         char **envp;
62         char *monitor_buf;
63         size_t monitor_buf_len;
64         struct udev_list devlinks_list;
65         struct udev_list properties_list;
66         struct udev_list sysattr_value_list;
67         struct udev_list sysattr_list;
68         struct udev_list tags_list;
69         unsigned long long int seqnum;
70         unsigned long long int usec_initialized;
71         int devlink_priority;
72         int refcount;
73         dev_t devnum;
74         int ifindex;
75         int watch_handle;
76         int maj, min;
77         bool parent_set;
78         bool subsystem_set;
79         bool devtype_set;
80         bool devlinks_uptodate;
81         bool envp_uptodate;
82         bool tags_uptodate;
83         bool driver_set;
84         bool info_loaded;
85         bool db_loaded;
86         bool uevent_loaded;
87         bool is_initialized;
88         bool sysattr_list_read;
89         bool db_persist;
90 };
91
92 /**
93  * udev_device_get_seqnum:
94  * @udev_device: udev device
95  *
96  * This is only valid if the device was received through a monitor. Devices read from
97  * sys do not have a sequence number.
98  *
99  * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
100  **/
101 _public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
102 {
103         if (udev_device == NULL)
104                 return 0;
105         return udev_device->seqnum;
106 }
107
108 static int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum)
109 {
110         char num[32];
111
112         udev_device->seqnum = seqnum;
113         snprintf(num, sizeof(num), "%llu", seqnum);
114         udev_device_add_property(udev_device, "SEQNUM", num);
115         return 0;
116 }
117
118 int udev_device_get_ifindex(struct udev_device *udev_device)
119 {
120         if (!udev_device->info_loaded)
121                 udev_device_read_uevent_file(udev_device);
122         return udev_device->ifindex;
123 }
124
125 static int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex)
126 {
127         char num[32];
128
129         udev_device->ifindex = ifindex;
130         snprintf(num, sizeof(num), "%u", ifindex);
131         udev_device_add_property(udev_device, "IFINDEX", num);
132         return 0;
133 }
134
135 /**
136  * udev_device_get_devnum:
137  * @udev_device: udev device
138  *
139  * Get the device major/minor number.
140  *
141  * Returns: the dev_t number.
142  **/
143 _public_ dev_t udev_device_get_devnum(struct udev_device *udev_device)
144 {
145         if (udev_device == NULL)
146                 return makedev(0, 0);
147         if (!udev_device->info_loaded)
148                 udev_device_read_uevent_file(udev_device);
149         return udev_device->devnum;
150 }
151
152 static int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum)
153 {
154         char num[32];
155
156         udev_device->devnum = devnum;
157
158         snprintf(num, sizeof(num), "%u", major(devnum));
159         udev_device_add_property(udev_device, "MAJOR", num);
160         snprintf(num, sizeof(num), "%u", minor(devnum));
161         udev_device_add_property(udev_device, "MINOR", num);
162         return 0;
163 }
164
165 const char *udev_device_get_devpath_old(struct udev_device *udev_device)
166 {
167         return udev_device->devpath_old;
168 }
169
170 static int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old)
171 {
172         const char *pos;
173
174         free(udev_device->devpath_old);
175         udev_device->devpath_old = strdup(devpath_old);
176         if (udev_device->devpath_old == NULL)
177                 return -ENOMEM;
178         udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
179
180         pos = strrchr(udev_device->devpath_old, '/');
181         if (pos == NULL)
182                 return -EINVAL;
183         return 0;
184 }
185
186 /**
187  * udev_device_get_driver:
188  * @udev_device: udev device
189  *
190  * Get the kernel driver name.
191  *
192  * Returns: the driver name string, or #NULL if there is no driver attached.
193  **/
194 _public_ const char *udev_device_get_driver(struct udev_device *udev_device)
195 {
196         char driver[UTIL_NAME_SIZE];
197
198         if (udev_device == NULL)
199                 return NULL;
200         if (!udev_device->driver_set) {
201                 udev_device->driver_set = true;
202                 if (util_get_sys_core_link_value(udev_device->udev, "driver", udev_device->syspath, driver, sizeof(driver)) > 0)
203                         udev_device->driver = strdup(driver);
204         }
205         return udev_device->driver;
206 }
207
208 static int udev_device_set_driver(struct udev_device *udev_device, const char *driver)
209 {
210         free(udev_device->driver);
211         udev_device->driver = strdup(driver);
212         if (udev_device->driver == NULL)
213                 return -ENOMEM;
214         udev_device->driver_set = true;
215         udev_device_add_property(udev_device, "DRIVER", udev_device->driver);
216         return 0;
217 }
218
219 /**
220  * udev_device_get_devtype:
221  * @udev_device: udev device
222  *
223  * Retrieve the devtype string of the udev device.
224  *
225  * Returns: the devtype name of the udev device, or #NULL if it can not be determined
226  **/
227 _public_ const char *udev_device_get_devtype(struct udev_device *udev_device)
228 {
229         if (udev_device == NULL)
230                 return NULL;
231         if (!udev_device->devtype_set) {
232                 udev_device->devtype_set = true;
233                 udev_device_read_uevent_file(udev_device);
234         }
235         return udev_device->devtype;
236 }
237
238 static int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype)
239 {
240         free(udev_device->devtype);
241         udev_device->devtype = strdup(devtype);
242         if (udev_device->devtype == NULL)
243                 return -ENOMEM;
244         udev_device->devtype_set = true;
245         udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
246         return 0;
247 }
248
249 static int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem)
250 {
251         free(udev_device->subsystem);
252         udev_device->subsystem = strdup(subsystem);
253         if (udev_device->subsystem == NULL)
254                 return -ENOMEM;
255         udev_device->subsystem_set = true;
256         udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
257         return 0;
258 }
259
260 /**
261  * udev_device_get_subsystem:
262  * @udev_device: udev device
263  *
264  * Retrieve the subsystem string of the udev device. The string does not
265  * contain any "/".
266  *
267  * Returns: the subsystem name of the udev device, or #NULL if it can not be determined
268  **/
269 _public_ const char *udev_device_get_subsystem(struct udev_device *udev_device)
270 {
271         char subsystem[UTIL_NAME_SIZE];
272
273         if (udev_device == NULL)
274                 return NULL;
275         if (!udev_device->subsystem_set) {
276                 udev_device->subsystem_set = true;
277                 /* read "subsystem" link */
278                 if (util_get_sys_core_link_value(udev_device->udev, "subsystem", udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
279                         udev_device_set_subsystem(udev_device, subsystem);
280                         return udev_device->subsystem;
281                 }
282                 /* implicit names */
283                 if (startswith(udev_device->devpath, "/module/")) {
284                         udev_device_set_subsystem(udev_device, "module");
285                         return udev_device->subsystem;
286                 }
287                 if (strstr(udev_device->devpath, "/drivers/") != NULL) {
288                         udev_device_set_subsystem(udev_device, "drivers");
289                         return udev_device->subsystem;
290                 }
291                 if (startswith(udev_device->devpath, "/subsystem/") ||
292                     startswith(udev_device->devpath, "/class/") ||
293                     startswith(udev_device->devpath, "/bus/")) {
294                         udev_device_set_subsystem(udev_device, "subsystem");
295                         return udev_device->subsystem;
296                 }
297         }
298         return udev_device->subsystem;
299 }
300
301 mode_t udev_device_get_devnode_mode(struct udev_device *udev_device)
302 {
303         if (!udev_device->info_loaded)
304                 udev_device_read_uevent_file(udev_device);
305         return udev_device->devnode_mode;
306 }
307
308 static int udev_device_set_devnode_mode(struct udev_device *udev_device, mode_t mode)
309 {
310         char num[32];
311
312         udev_device->devnode_mode = mode;
313         snprintf(num, sizeof(num), "%#o", mode);
314         udev_device_add_property(udev_device, "DEVMODE", num);
315         return 0;
316 }
317
318 struct udev_list_entry *udev_device_add_property(struct udev_device *udev_device, const char *key, const char *value)
319 {
320         udev_device->envp_uptodate = false;
321         if (value == NULL) {
322                 struct udev_list_entry *list_entry;
323
324                 list_entry = udev_device_get_properties_list_entry(udev_device);
325                 list_entry = udev_list_entry_get_by_name(list_entry, key);
326                 if (list_entry != NULL)
327                         udev_list_entry_delete(list_entry);
328                 return NULL;
329         }
330         return udev_list_entry_add(&udev_device->properties_list, key, value);
331 }
332
333 static struct udev_list_entry *udev_device_add_property_from_string(struct udev_device *udev_device, const char *property)
334 {
335         char name[UTIL_LINE_SIZE];
336         char *val;
337
338         util_strscpy(name, sizeof(name), property);
339         val = strchr(name, '=');
340         if (val == NULL)
341                 return NULL;
342         val[0] = '\0';
343         val = &val[1];
344         if (val[0] == '\0')
345                 val = NULL;
346         return udev_device_add_property(udev_device, name, val);
347 }
348
349 /*
350  * parse property string, and if needed, update internal values accordingly
351  *
352  * udev_device_add_property_from_string_parse_finish() needs to be
353  * called after adding properties, and its return value checked
354  *
355  * udev_device_set_info_loaded() needs to be set, to avoid trying
356  * to use a device without a DEVPATH set
357  */
358 void udev_device_add_property_from_string_parse(struct udev_device *udev_device, const char *property)
359 {
360         if (startswith(property, "DEVPATH=")) {
361                 char path[UTIL_PATH_SIZE];
362
363                 util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys", &property[8], NULL);
364                 udev_device_set_syspath(udev_device, path);
365         } else if (startswith(property, "SUBSYSTEM=")) {
366                 udev_device_set_subsystem(udev_device, &property[10]);
367         } else if (startswith(property, "DEVTYPE=")) {
368                 udev_device_set_devtype(udev_device, &property[8]);
369         } else if (startswith(property, "DEVNAME=")) {
370                 udev_device_set_devnode(udev_device, &property[8]);
371         } else if (startswith(property, "DEVLINKS=")) {
372                 char devlinks[UTIL_PATH_SIZE];
373                 char *slink;
374                 char *next;
375
376                 util_strscpy(devlinks, sizeof(devlinks), &property[9]);
377                 slink = devlinks;
378                 next = strchr(slink, ' ');
379                 while (next != NULL) {
380                         next[0] = '\0';
381                         udev_device_add_devlink(udev_device, slink, 0);
382                         slink = &next[1];
383                         next = strchr(slink, ' ');
384                 }
385                 if (slink[0] != '\0')
386                         udev_device_add_devlink(udev_device, slink, 0);
387         } else if (startswith(property, "TAGS=")) {
388                 char tags[UTIL_PATH_SIZE];
389                 char *next;
390
391                 util_strscpy(tags, sizeof(tags), &property[5]);
392                 next = strchr(tags, ':');
393                 if (next != NULL) {
394                         next++;
395                         while (next[0] != '\0') {
396                                 char *tag;
397
398                                 tag = next;
399                                 next = strchr(tag, ':');
400                                 if (next == NULL)
401                                         break;
402                                 next[0] = '\0';
403                                 next++;
404                                 udev_device_add_tag(udev_device, tag);
405                         }
406                 }
407         } else if (startswith(property, "USEC_INITIALIZED=")) {
408                 udev_device_set_usec_initialized(udev_device, strtoull(&property[19], NULL, 10));
409         } else if (startswith(property, "DRIVER=")) {
410                 udev_device_set_driver(udev_device, &property[7]);
411         } else if (startswith(property, "ACTION=")) {
412                 udev_device_set_action(udev_device, &property[7]);
413         } else if (startswith(property, "MAJOR=")) {
414                 udev_device->maj = strtoull(&property[6], NULL, 10);
415         } else if (startswith(property, "MINOR=")) {
416                 udev_device->min = strtoull(&property[6], NULL, 10);
417         } else if (startswith(property, "DEVPATH_OLD=")) {
418                 udev_device_set_devpath_old(udev_device, &property[12]);
419         } else if (startswith(property, "SEQNUM=")) {
420                 udev_device_set_seqnum(udev_device, strtoull(&property[7], NULL, 10));
421         } else if (startswith(property, "IFINDEX=")) {
422                 udev_device_set_ifindex(udev_device, strtoull(&property[8], NULL, 10));
423         } else if (startswith(property, "DEVMODE=")) {
424                 udev_device_set_devnode_mode(udev_device, strtoul(&property[8], NULL, 8));
425         } else {
426                 udev_device_add_property_from_string(udev_device, property);
427         }
428 }
429
430 int udev_device_add_property_from_string_parse_finish(struct udev_device *udev_device)
431 {
432         if (udev_device->maj > 0)
433                 udev_device_set_devnum(udev_device, makedev(udev_device->maj, udev_device->min));
434         udev_device->maj = 0;
435         udev_device->min = 0;
436
437         if (udev_device->devpath == NULL || udev_device->subsystem == NULL)
438                 return -EINVAL;
439         return 0;
440 }
441
442 /**
443  * udev_device_get_property_value:
444  * @udev_device: udev device
445  * @key: property name
446  *
447  * Get the value of a given property.
448  *
449  * Returns: the property string, or #NULL if there is no such property.
450  **/
451 _public_ const char *udev_device_get_property_value(struct udev_device *udev_device, const char *key)
452 {
453         struct udev_list_entry *list_entry;
454
455         if (udev_device == NULL)
456                 return NULL;
457         if (key == NULL)
458                 return NULL;
459
460         list_entry = udev_device_get_properties_list_entry(udev_device);
461         list_entry = udev_list_entry_get_by_name(list_entry, key);
462         return udev_list_entry_get_value(list_entry);
463 }
464
465 int udev_device_read_db(struct udev_device *udev_device, const char *dbfile)
466 {
467         char filename[UTIL_PATH_SIZE];
468         char line[UTIL_LINE_SIZE];
469         FILE *f;
470
471         /* providing a database file will always force-load it */
472         if (dbfile == NULL) {
473                 const char *id;
474
475                 if (udev_device->db_loaded)
476                         return 0;
477                 udev_device->db_loaded = true;
478
479                 id = udev_device_get_id_filename(udev_device);
480                 if (id == NULL)
481                         return -1;
482                 util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/run/udev/data/", id, NULL);
483                 dbfile = filename;
484         }
485
486         f = fopen(dbfile, "re");
487         if (f == NULL) {
488                 udev_dbg(udev_device->udev, "no db file to read %s: %m\n", dbfile);
489                 return -1;
490         }
491         udev_device->is_initialized = true;
492
493         while (fgets(line, sizeof(line), f)) {
494                 ssize_t len;
495                 const char *val;
496                 struct udev_list_entry *entry;
497
498                 len = strlen(line);
499                 if (len < 4)
500                         break;
501                 line[len-1] = '\0';
502                 val = &line[2];
503                 switch(line[0]) {
504                 case 'S':
505                         util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", val, NULL);
506                         udev_device_add_devlink(udev_device, filename, 0);
507                         break;
508                 case 'L':
509                         udev_device_set_devlink_priority(udev_device, atoi(val));
510                         break;
511                 case 'E':
512                         entry = udev_device_add_property_from_string(udev_device, val);
513                         udev_list_entry_set_num(entry, true);
514                         break;
515                 case 'G':
516                         udev_device_add_tag(udev_device, val);
517                         break;
518                 case 'W':
519                         udev_device_set_watch_handle(udev_device, atoi(val));
520                         break;
521                 case 'I':
522                         udev_device_set_usec_initialized(udev_device, strtoull(val, NULL, 10));
523                         break;
524                 }
525         }
526         fclose(f);
527
528         udev_dbg(udev_device->udev, "device %p filled with db file data\n", udev_device);
529         return 0;
530 }
531
532 int udev_device_read_uevent_file(struct udev_device *udev_device)
533 {
534         char filename[UTIL_PATH_SIZE];
535         FILE *f;
536         char line[UTIL_LINE_SIZE];
537         int maj = 0;
538         int min = 0;
539
540         if (udev_device->uevent_loaded)
541                 return 0;
542
543         util_strscpyl(filename, sizeof(filename), udev_device->syspath, "/uevent", NULL);
544         f = fopen(filename, "re");
545         if (f == NULL)
546                 return -1;
547         udev_device->uevent_loaded = true;
548
549         while (fgets(line, sizeof(line), f)) {
550                 char *pos;
551
552                 pos = strchr(line, '\n');
553                 if (pos == NULL)
554                         continue;
555                 pos[0] = '\0';
556
557                 if (startswith(line, "DEVTYPE=")) {
558                         udev_device_set_devtype(udev_device, &line[8]);
559                         continue;
560                 }
561                 if (startswith(line, "IFINDEX=")) {
562                         udev_device_set_ifindex(udev_device, strtoull(&line[8], NULL, 10));
563                         continue;
564                 }
565                 if (startswith(line, "DEVNAME=")) {
566                         udev_device_set_devnode(udev_device, &line[8]);
567                         continue;
568                 }
569
570                 if (startswith(line, "MAJOR="))
571                         maj = strtoull(&line[6], NULL, 10);
572                 else if (startswith(line, "MINOR="))
573                         min = strtoull(&line[6], NULL, 10);
574                 else if (startswith(line, "DEVMODE="))
575                         udev_device->devnode_mode = strtoul(&line[8], NULL, 8);
576
577                 udev_device_add_property_from_string(udev_device, line);
578         }
579
580         udev_device->devnum = makedev(maj, min);
581         fclose(f);
582         return 0;
583 }
584
585 void udev_device_set_info_loaded(struct udev_device *device)
586 {
587         device->info_loaded = true;
588 }
589
590 struct udev_device *udev_device_new(struct udev *udev)
591 {
592         struct udev_device *udev_device;
593         struct udev_list_entry *list_entry;
594
595         if (udev == NULL)
596                 return NULL;
597
598         udev_device = calloc(1, sizeof(struct udev_device));
599         if (udev_device == NULL)
600                 return NULL;
601         udev_device->refcount = 1;
602         udev_device->udev = udev;
603         udev_list_init(udev, &udev_device->devlinks_list, true);
604         udev_list_init(udev, &udev_device->properties_list, true);
605         udev_list_init(udev, &udev_device->sysattr_value_list, true);
606         udev_list_init(udev, &udev_device->sysattr_list, false);
607         udev_list_init(udev, &udev_device->tags_list, true);
608         udev_device->watch_handle = -1;
609         /* copy global properties */
610         udev_list_entry_foreach(list_entry, udev_get_properties_list_entry(udev))
611                 udev_device_add_property(udev_device,
612                                          udev_list_entry_get_name(list_entry),
613                                          udev_list_entry_get_value(list_entry));
614         return udev_device;
615 }
616
617 /**
618  * udev_device_new_from_syspath:
619  * @udev: udev library context
620  * @syspath: sys device path including sys directory
621  *
622  * Create new udev device, and fill in information from the sys
623  * device and the udev database entry. The syspath is the absolute
624  * path to the device, including the sys mount point.
625  *
626  * The initial refcount is 1, and needs to be decremented to
627  * release the resources of the udev device.
628  *
629  * Returns: a new udev device, or #NULL, if it does not exist
630  **/
631 _public_ struct udev_device *udev_device_new_from_syspath(struct udev *udev, const char *syspath)
632 {
633         const char *subdir;
634         char path[UTIL_PATH_SIZE];
635         char *pos;
636         struct stat statbuf;
637         struct udev_device *udev_device;
638
639         if (udev == NULL)
640                 return NULL;
641         if (syspath == NULL)
642                 return NULL;
643
644         /* path starts in sys */
645         if (!startswith(syspath, TEST_PREFIX "/sys")) {
646                 udev_dbg(udev, "not in sys :%s\n", syspath);
647                 return NULL;
648         }
649
650         /* path is not a root directory */
651         subdir = syspath + strlen(TEST_PREFIX "/sys");
652         pos = strrchr(subdir, '/');
653         if (pos == NULL || pos[1] == '\0' || pos < &subdir[2])
654                 return NULL;
655
656         /* resolve possible symlink to real path */
657         util_strscpy(path, sizeof(path), syspath);
658         util_resolve_sys_link(udev, path, sizeof(path));
659
660         if (startswith(path + strlen(TEST_PREFIX "/sys"), "/devices/")) {
661                 char file[UTIL_PATH_SIZE];
662
663                 /* all "devices" require a "uevent" file */
664                 util_strscpyl(file, sizeof(file), path, "/uevent", NULL);
665                 if (stat(file, &statbuf) != 0)
666                         return NULL;
667         } else {
668                 /* everything else just needs to be a directory */
669                 if (stat(path, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode))
670                         return NULL;
671         }
672
673         udev_device = udev_device_new(udev);
674         if (udev_device == NULL)
675                 return NULL;
676
677         udev_device_set_syspath(udev_device, path);
678         udev_dbg(udev, "device %p has devpath '%s'\n", udev_device, udev_device_get_devpath(udev_device));
679
680         return udev_device;
681 }
682
683 /**
684  * udev_device_new_from_devnum:
685  * @udev: udev library context
686  * @type: char or block device
687  * @devnum: device major/minor number
688  *
689  * Create new udev device, and fill in information from the sys
690  * device and the udev database entry. The device is looked-up
691  * by its major/minor number and type. Character and block device
692  * numbers are not unique across the two types.
693  *
694  * The initial refcount is 1, and needs to be decremented to
695  * release the resources of the udev device.
696  *
697  * Returns: a new udev device, or #NULL, if it does not exist
698  **/
699 _public_ struct udev_device *udev_device_new_from_devnum(struct udev *udev, char type, dev_t devnum)
700 {
701         char path[UTIL_PATH_SIZE];
702         const char *type_str;
703
704         if (type == 'b')
705                 type_str = "block";
706         else if (type == 'c')
707                 type_str = "char";
708         else
709                 return NULL;
710
711         /* use /sys/dev/{block,char}/<maj>:<min> link */
712         snprintf(path, sizeof(path), TEST_PREFIX "/sys/dev/%s/%u:%u",
713                  type_str, major(devnum), minor(devnum));
714         return udev_device_new_from_syspath(udev, path);
715 }
716
717 struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id)
718 {
719         char type;
720         int maj, min;
721         char subsys[UTIL_PATH_SIZE];
722         char *sysname;
723
724         switch(id[0]) {
725         case 'b':
726         case 'c':
727                 if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3)
728                         return NULL;
729                 return udev_device_new_from_devnum(udev, type, makedev(maj, min));
730         case 'n': {
731                 int sk;
732                 struct ifreq ifr;
733                 struct udev_device *dev;
734                 int ifindex;
735
736                 ifindex = strtoul(&id[1], NULL, 10);
737                 if (ifindex <= 0)
738                         return NULL;
739
740                 sk = socket(PF_INET, SOCK_DGRAM, 0);
741                 if (sk < 0)
742                         return NULL;
743                 memset(&ifr, 0x00, sizeof(struct ifreq));
744                 ifr.ifr_ifindex = ifindex;
745                 if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) {
746                         close(sk);
747                         return NULL;
748                 }
749                 close(sk);
750
751                 dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name);
752                 if (dev == NULL)
753                         return NULL;
754                 if (udev_device_get_ifindex(dev) == ifindex)
755                         return dev;
756                 udev_device_unref(dev);
757                 return NULL;
758         }
759         case '+':
760                 util_strscpy(subsys, sizeof(subsys), &id[1]);
761                 sysname = strchr(subsys, ':');
762                 if (sysname == NULL)
763                         return NULL;
764                 sysname[0] = '\0';
765                 sysname = &sysname[1];
766                 return udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
767         default:
768                 return NULL;
769         }
770 }
771
772 /**
773  * udev_device_new_from_subsystem_sysname:
774  * @udev: udev library context
775  * @subsystem: the subsystem of the device
776  * @sysname: the name of the device
777  *
778  * Create new udev device, and fill in information from the sys device
779  * and the udev database entry. The device is looked up by the subsystem
780  * and name string of the device, like "mem" / "zero", or "block" / "sda".
781  *
782  * The initial refcount is 1, and needs to be decremented to
783  * release the resources of the udev device.
784  *
785  * Returns: a new udev device, or #NULL, if it does not exist
786  **/
787 _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
788 {
789         char path[UTIL_PATH_SIZE];
790         struct stat statbuf;
791
792         if (streq(subsystem, "subsystem")) {
793                 util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/subsystem/", sysname, NULL);
794                 if (stat(path, &statbuf) == 0)
795                         goto found;
796
797                 util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/bus/", sysname, NULL);
798                 if (stat(path, &statbuf) == 0)
799                         goto found;
800
801                 util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/class/", sysname, NULL);
802                 if (stat(path, &statbuf) == 0)
803                         goto found;
804                 goto out;
805         }
806
807         if (streq(subsystem, "module")) {
808                 util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/module/", sysname, NULL);
809                 if (stat(path, &statbuf) == 0)
810                         goto found;
811                 goto out;
812         }
813
814         if (streq(subsystem, "drivers")) {
815                 char subsys[UTIL_NAME_SIZE];
816                 char *driver;
817
818                 util_strscpy(subsys, sizeof(subsys), sysname);
819                 driver = strchr(subsys, ':');
820                 if (driver != NULL) {
821                         driver[0] = '\0';
822                         driver = &driver[1];
823
824                         util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/subsystem/", subsys, "/drivers/", driver, NULL);
825                         if (stat(path, &statbuf) == 0)
826                                 goto found;
827
828                         util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/bus/", subsys, "/drivers/", driver, NULL);
829                         if (stat(path, &statbuf) == 0)
830                                 goto found;
831                 }
832                 goto out;
833         }
834
835         util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/subsystem/", subsystem, "/devices/", sysname, NULL);
836         if (stat(path, &statbuf) == 0)
837                 goto found;
838
839         util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/bus/", subsystem, "/devices/", sysname, NULL);
840         if (stat(path, &statbuf) == 0)
841                 goto found;
842
843         util_strscpyl(path, sizeof(path), TEST_PREFIX "/sys/class/", subsystem, "/", sysname, NULL);
844         if (stat(path, &statbuf) == 0)
845                 goto found;
846 out:
847         return NULL;
848 found:
849         return udev_device_new_from_syspath(udev, path);
850 }
851
852 /**
853  * udev_device_new_from_environment
854  * @udev: udev library context
855  *
856  * Create new udev device, and fill in information from the
857  * current process environment. This only works reliable if
858  * the process is called from a udev rule. It is usually used
859  * for tools executed from IMPORT= rules.
860  *
861  * The initial refcount is 1, and needs to be decremented to
862  * release the resources of the udev device.
863  *
864  * Returns: a new udev device, or #NULL, if it does not exist
865  **/
866 _public_ struct udev_device *udev_device_new_from_environment(struct udev *udev)
867 {
868         int i;
869         struct udev_device *udev_device;
870
871         udev_device = udev_device_new(udev);
872         if (udev_device == NULL)
873                 return NULL;
874         udev_device_set_info_loaded(udev_device);
875
876         for (i = 0; environ[i] != NULL; i++)
877                 udev_device_add_property_from_string_parse(udev_device, environ[i]);
878
879         if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
880                 udev_dbg(udev, "missing values, invalid device\n");
881                 udev_device_unref(udev_device);
882                 udev_device = NULL;
883         }
884
885         return udev_device;
886 }
887
888 static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
889 {
890         struct udev_device *udev_device_parent = NULL;
891         char path[UTIL_PATH_SIZE];
892         const char *subdir;
893
894         util_strscpy(path, sizeof(path), udev_device->syspath);
895         subdir = path + strlen(TEST_PREFIX "/sys/");
896         for (;;) {
897                 char *pos;
898
899                 pos = strrchr(subdir, '/');
900                 if (pos == NULL || pos < &subdir[2])
901                         break;
902                 pos[0] = '\0';
903                 udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
904                 if (udev_device_parent != NULL)
905                         return udev_device_parent;
906         }
907         return NULL;
908 }
909
910 /**
911  * udev_device_get_parent:
912  * @udev_device: the device to start searching from
913  *
914  * Find the next parent device, and fill in information from the sys
915  * device and the udev database entry.
916  *
917  * The returned the device is not referenced. It is attached to the
918  * child device, and will be cleaned up when the child device
919  * is cleaned up.
920  *
921  * It is not necessarily just the upper level directory, empty or not
922  * recognized sys directories are ignored.
923  *
924  * It can be called as many times as needed, without caring about
925  * references.
926  *
927  * Returns: a new udev device, or #NULL, if it no parent exist.
928  **/
929 _public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
930 {
931         if (udev_device == NULL)
932                 return NULL;
933         if (!udev_device->parent_set) {
934                 udev_device->parent_set = true;
935                 udev_device->parent_device = device_new_from_parent(udev_device);
936         }
937         return udev_device->parent_device;
938 }
939
940 /**
941  * udev_device_get_parent_with_subsystem_devtype:
942  * @udev_device: udev device to start searching from
943  * @subsystem: the subsystem of the device
944  * @devtype: the type (DEVTYPE) of the device
945  *
946  * Find the next parent device, with a matching subsystem and devtype
947  * value, and fill in information from the sys device and the udev
948  * database entry.
949  *
950  * If devtype is #NULL, only subsystem is checked, and any devtype will
951  * match.
952  *
953  * The returned the device is not referenced. It is attached to the
954  * child device, and will be cleaned up when the child device
955  * is cleaned up.
956  *
957  * It can be called as many times as needed, without caring about
958  * references.
959  *
960  * Returns: a new udev device, or #NULL if no matching parent exists.
961  **/
962 _public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
963 {
964         struct udev_device *parent;
965
966         if (subsystem == NULL)
967                 return NULL;
968
969         parent = udev_device_get_parent(udev_device);
970         while (parent != NULL) {
971                 const char *parent_subsystem;
972                 const char *parent_devtype;
973
974                 parent_subsystem = udev_device_get_subsystem(parent);
975                 if (parent_subsystem != NULL && streq(parent_subsystem, subsystem)) {
976                         if (devtype == NULL)
977                                 break;
978                         parent_devtype = udev_device_get_devtype(parent);
979                         if (parent_devtype != NULL && streq(parent_devtype, devtype))
980                                 break;
981                 }
982                 parent = udev_device_get_parent(parent);
983         }
984         return parent;
985 }
986
987 /**
988  * udev_device_get_udev:
989  * @udev_device: udev device
990  *
991  * Retrieve the udev library context the device was created with.
992  *
993  * Returns: the udev library context
994  **/
995 _public_ struct udev *udev_device_get_udev(struct udev_device *udev_device)
996 {
997         if (udev_device == NULL)
998                 return NULL;
999         return udev_device->udev;
1000 }
1001
1002 /**
1003  * udev_device_ref:
1004  * @udev_device: udev device
1005  *
1006  * Take a reference of a udev device.
1007  *
1008  * Returns: the passed udev device
1009  **/
1010 _public_ struct udev_device *udev_device_ref(struct udev_device *udev_device)
1011 {
1012         if (udev_device == NULL)
1013                 return NULL;
1014         udev_device->refcount++;
1015         return udev_device;
1016 }
1017
1018 /**
1019  * udev_device_unref:
1020  * @udev_device: udev device
1021  *
1022  * Drop a reference of a udev device. If the refcount reaches zero,
1023  * the resources of the device will be released.
1024  *
1025  **/
1026 _public_ void udev_device_unref(struct udev_device *udev_device)
1027 {
1028         if (udev_device == NULL)
1029                 return;
1030         udev_device->refcount--;
1031         if (udev_device->refcount > 0)
1032                 return;
1033         if (udev_device->parent_device != NULL)
1034                 udev_device_unref(udev_device->parent_device);
1035         free(udev_device->syspath);
1036         free(udev_device->sysname);
1037         free(udev_device->devnode);
1038         free(udev_device->subsystem);
1039         free(udev_device->devtype);
1040         udev_list_cleanup(&udev_device->devlinks_list);
1041         udev_list_cleanup(&udev_device->properties_list);
1042         udev_list_cleanup(&udev_device->sysattr_value_list);
1043         udev_list_cleanup(&udev_device->sysattr_list);
1044         udev_list_cleanup(&udev_device->tags_list);
1045         free(udev_device->action);
1046         free(udev_device->driver);
1047         free(udev_device->devpath_old);
1048         free(udev_device->id_filename);
1049         free(udev_device->envp);
1050         free(udev_device->monitor_buf);
1051         free(udev_device);
1052 }
1053
1054 /**
1055  * udev_device_get_devpath:
1056  * @udev_device: udev device
1057  *
1058  * Retrieve the kernel devpath value of the udev device. The path
1059  * does not contain the sys mount point, and starts with a '/'.
1060  *
1061  * Returns: the devpath of the udev device
1062  **/
1063 _public_ const char *udev_device_get_devpath(struct udev_device *udev_device)
1064 {
1065         if (udev_device == NULL)
1066                 return NULL;
1067         return udev_device->devpath;
1068 }
1069
1070 /**
1071  * udev_device_get_syspath:
1072  * @udev_device: udev device
1073  *
1074  * Retrieve the sys path of the udev device. The path is an
1075  * absolute path and starts with the sys mount point.
1076  *
1077  * Returns: the sys path of the udev device
1078  **/
1079 _public_ const char *udev_device_get_syspath(struct udev_device *udev_device)
1080 {
1081         if (udev_device == NULL)
1082                 return NULL;
1083         return udev_device->syspath;
1084 }
1085
1086 /**
1087  * udev_device_get_sysname:
1088  * @udev_device: udev device
1089  *
1090  * Get the kernel device name in /sys.
1091  *
1092  * Returns: the name string of the device device
1093  **/
1094 _public_ const char *udev_device_get_sysname(struct udev_device *udev_device)
1095 {
1096         if (udev_device == NULL)
1097                 return NULL;
1098         return udev_device->sysname;
1099 }
1100
1101 /**
1102  * udev_device_get_sysnum:
1103  * @udev_device: udev device
1104  *
1105  * Get the instance number of the device.
1106  *
1107  * Returns: the trailing number string of of the device name
1108  **/
1109 _public_ const char *udev_device_get_sysnum(struct udev_device *udev_device)
1110 {
1111         if (udev_device == NULL)
1112                 return NULL;
1113         return udev_device->sysnum;
1114 }
1115
1116 /**
1117  * udev_device_get_devnode:
1118  * @udev_device: udev device
1119  *
1120  * Retrieve the device node file name belonging to the udev device.
1121  * The path is an absolute path, and starts with the device directory.
1122  *
1123  * Returns: the device node file name of the udev device, or #NULL if no device node exists
1124  **/
1125 _public_ const char *udev_device_get_devnode(struct udev_device *udev_device)
1126 {
1127         if (udev_device == NULL)
1128                 return NULL;
1129         if (udev_device->devnode != NULL)
1130                 return udev_device->devnode;
1131         if (!udev_device->info_loaded)
1132                 udev_device_read_uevent_file(udev_device);
1133         return udev_device->devnode;
1134 }
1135
1136 /**
1137  * udev_device_get_devlinks_list_entry:
1138  * @udev_device: udev device
1139  *
1140  * Retrieve the list of device links pointing to the device file of
1141  * the udev device. The next list entry can be retrieved with
1142  * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
1143  * The devlink path can be retrieved from the list entry by
1144  * udev_list_entry_get_name(). The path is an absolute path, and starts with
1145  * the device directory.
1146  *
1147  * Returns: the first entry of the device node link list
1148  **/
1149 _public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
1150 {
1151         if (udev_device == NULL)
1152                 return NULL;
1153         if (!udev_device->info_loaded)
1154                 udev_device_read_db(udev_device, NULL);
1155         return udev_list_get_entry(&udev_device->devlinks_list);
1156 }
1157
1158 void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
1159 {
1160         udev_device->devlinks_uptodate = false;
1161         udev_list_cleanup(&udev_device->devlinks_list);
1162 }
1163
1164 /**
1165  * udev_device_get_properties_list_entry:
1166  * @udev_device: udev device
1167  *
1168  * Retrieve the list of key/value device properties of the udev
1169  * device. The next list entry can be retrieved with udev_list_entry_get_next(),
1170  * which returns #NULL if no more entries exist. The property name
1171  * can be retrieved from the list entry by udev_list_entry_get_name(),
1172  * the property value by udev_list_entry_get_value().
1173  *
1174  * Returns: the first entry of the property list
1175  **/
1176 _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
1177 {
1178         if (udev_device == NULL)
1179                 return NULL;
1180         if (!udev_device->info_loaded) {
1181                 udev_device_read_uevent_file(udev_device);
1182                 udev_device_read_db(udev_device, NULL);
1183         }
1184         if (!udev_device->devlinks_uptodate) {
1185                 char symlinks[UTIL_PATH_SIZE];
1186                 struct udev_list_entry *list_entry;
1187
1188                 udev_device->devlinks_uptodate = true;
1189                 list_entry = udev_device_get_devlinks_list_entry(udev_device);
1190                 if (list_entry != NULL) {
1191                         char *s;
1192                         size_t l;
1193
1194                         s = symlinks;
1195                         l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
1196                         udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
1197                                 l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
1198                         udev_device_add_property(udev_device, "DEVLINKS", symlinks);
1199                 }
1200         }
1201         if (!udev_device->tags_uptodate) {
1202                 udev_device->tags_uptodate = true;
1203                 if (udev_device_get_tags_list_entry(udev_device) != NULL) {
1204                         char tags[UTIL_PATH_SIZE];
1205                         struct udev_list_entry *list_entry;
1206                         char *s;
1207                         size_t l;
1208
1209                         s = tags;
1210                         l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
1211                         udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
1212                                 l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
1213                         udev_device_add_property(udev_device, "TAGS", tags);
1214                 }
1215         }
1216         return udev_list_get_entry(&udev_device->properties_list);
1217 }
1218
1219 /**
1220  * udev_device_get_action:
1221  * @udev_device: udev device
1222  *
1223  * This is only valid if the device was received through a monitor. Devices read from
1224  * sys do not have an action string. Usual actions are: add, remove, change, online,
1225  * offline.
1226  *
1227  * Returns: the kernel action value, or #NULL if there is no action value available.
1228  **/
1229 _public_ const char *udev_device_get_action(struct udev_device *udev_device)
1230 {
1231         if (udev_device == NULL)
1232                 return NULL;
1233         return udev_device->action;
1234 }
1235
1236 /**
1237  * udev_device_get_usec_since_initialized:
1238  * @udev_device: udev device
1239  *
1240  * Return the number of microseconds passed since udev set up the
1241  * device for the first time.
1242  *
1243  * This is only implemented for devices with need to store properties
1244  * in the udev database. All other devices return 0 here.
1245  *
1246  * Returns: the number of microseconds since the device was first seen.
1247  **/
1248 _public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
1249 {
1250         unsigned long long now_ts;
1251
1252         if (udev_device == NULL)
1253                 return 0;
1254         if (!udev_device->info_loaded)
1255                 udev_device_read_db(udev_device, NULL);
1256         if (udev_device->usec_initialized == 0)
1257                 return 0;
1258         now_ts = now_usec();
1259         if (now_ts == 0)
1260                 return 0;
1261         return now_ts - udev_device->usec_initialized;
1262 }
1263
1264 unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device)
1265 {
1266         return udev_device->usec_initialized;
1267 }
1268
1269 void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized)
1270 {
1271         char num[32];
1272
1273         udev_device->usec_initialized = usec_initialized;
1274         snprintf(num, sizeof(num), "%llu", usec_initialized);
1275         udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
1276 }
1277
1278 /**
1279  * udev_device_get_sysattr_value:
1280  * @udev_device: udev device
1281  * @sysattr: attribute name
1282  *
1283  * The retrieved value is cached in the device. Repeated calls will return the same
1284  * value and not open the attribute again.
1285  *
1286  * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
1287  **/
1288 _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
1289 {
1290         struct udev_list_entry *list_entry;
1291         char path[UTIL_PATH_SIZE];
1292         char value[4096];
1293         struct stat statbuf;
1294         int fd;
1295         ssize_t size;
1296         const char *val = NULL;
1297
1298         if (udev_device == NULL)
1299                 return NULL;
1300         if (sysattr == NULL)
1301                 return NULL;
1302
1303         /* look for possibly already cached result */
1304         list_entry = udev_list_get_entry(&udev_device->sysattr_value_list);
1305         list_entry = udev_list_entry_get_by_name(list_entry, sysattr);
1306         if (list_entry != NULL)
1307                 return udev_list_entry_get_value(list_entry);
1308
1309         util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
1310         if (lstat(path, &statbuf) != 0) {
1311                 udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL);
1312                 goto out;
1313         }
1314
1315         if (S_ISLNK(statbuf.st_mode)) {
1316                 struct udev_device *dev;
1317
1318                 /*
1319                  * Some core links return only the last element of the target path,
1320                  * these are just values, the paths should not be exposed.
1321                  */
1322                 if (streq(sysattr, "driver") ||
1323                     streq(sysattr, "subsystem") ||
1324                     streq(sysattr, "module")) {
1325                         if (util_get_sys_core_link_value(udev_device->udev, sysattr,
1326                                                          udev_device->syspath, value, sizeof(value)) < 0)
1327                                 return NULL;
1328                         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
1329                         val = udev_list_entry_get_value(list_entry);
1330                         goto out;
1331                 }
1332
1333                 /* resolve link to a device and return its syspath */
1334                 util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
1335                 dev = udev_device_new_from_syspath(udev_device->udev, path);
1336                 if (dev != NULL) {
1337                         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
1338                                                          udev_device_get_syspath(dev));
1339                         val = udev_list_entry_get_value(list_entry);
1340                         udev_device_unref(dev);
1341                 }
1342
1343                 goto out;
1344         }
1345
1346         /* skip directories */
1347         if (S_ISDIR(statbuf.st_mode))
1348                 goto out;
1349
1350         /* skip non-readable files */
1351         if ((statbuf.st_mode & S_IRUSR) == 0)
1352                 goto out;
1353
1354         /* read attribute value */
1355         fd = open(path, O_RDONLY|O_CLOEXEC);
1356         if (fd < 0)
1357                 goto out;
1358         size = read(fd, value, sizeof(value));
1359         close(fd);
1360         if (size < 0)
1361                 goto out;
1362         if (size == sizeof(value))
1363                 goto out;
1364
1365         /* got a valid value, store it in cache and return it */
1366         value[size] = '\0';
1367         util_remove_trailing_chars(value, '\n');
1368         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
1369         val = udev_list_entry_get_value(list_entry);
1370 out:
1371         return val;
1372 }
1373
1374 static int udev_device_sysattr_list_read(struct udev_device *udev_device)
1375 {
1376         struct dirent *dent;
1377         DIR *dir;
1378         int num = 0;
1379
1380         if (udev_device == NULL)
1381                 return -1;
1382         if (udev_device->sysattr_list_read)
1383                 return 0;
1384
1385         dir = opendir(udev_device_get_syspath(udev_device));
1386         if (!dir)
1387                 return -1;
1388
1389         for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
1390                 char path[UTIL_PATH_SIZE];
1391                 struct stat statbuf;
1392
1393                 /* only handle symlinks and regular files */
1394                 if (dent->d_type != DT_LNK && dent->d_type != DT_REG)
1395                         continue;
1396
1397                 util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
1398                 if (lstat(path, &statbuf) != 0)
1399                         continue;
1400                 if ((statbuf.st_mode & S_IRUSR) == 0)
1401                         continue;
1402
1403                 udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL);
1404                 num++;
1405         }
1406
1407         closedir(dir);
1408         udev_device->sysattr_list_read = true;
1409
1410         return num;
1411 }
1412
1413 /**
1414  * udev_device_get_sysattr_list_entry:
1415  * @udev_device: udev device
1416  *
1417  * Retrieve the list of available sysattrs, with value being empty;
1418  * This just return all available sysfs attributes for a particular
1419  * device without reading their values.
1420  *
1421  * Returns: the first entry of the property list
1422  **/
1423 _public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
1424 {
1425         if (!udev_device->sysattr_list_read) {
1426                 int ret;
1427                 ret = udev_device_sysattr_list_read(udev_device);
1428                 if (0 > ret)
1429                         return NULL;
1430         }
1431
1432         return udev_list_get_entry(&udev_device->sysattr_list);
1433 }
1434
1435 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
1436 {
1437         const char *pos;
1438         size_t len;
1439
1440         free(udev_device->syspath);
1441         udev_device->syspath = strdup(syspath);
1442         if (udev_device->syspath ==  NULL)
1443                 return -ENOMEM;
1444         udev_device->devpath = udev_device->syspath + strlen(TEST_PREFIX "/sys");
1445         udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath);
1446
1447         pos = strrchr(udev_device->syspath, '/');
1448         if (pos == NULL)
1449                 return -EINVAL;
1450         udev_device->sysname = strdup(&pos[1]);
1451         if (udev_device->sysname == NULL)
1452                 return -ENOMEM;
1453
1454         /* some devices have '!' in their name, change that to '/' */
1455         len = 0;
1456         while (udev_device->sysname[len] != '\0') {
1457                 if (udev_device->sysname[len] == '!')
1458                         udev_device->sysname[len] = '/';
1459                 len++;
1460         }
1461
1462         /* trailing number */
1463         while (len > 0 && isdigit(udev_device->sysname[--len]))
1464                 udev_device->sysnum = &udev_device->sysname[len];
1465
1466         /* sysname is completely numeric */
1467         if (len == 0)
1468                 udev_device->sysnum = NULL;
1469
1470         return 0;
1471 }
1472
1473 int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
1474 {
1475         free(udev_device->devnode);
1476         if (devnode[0] != '/') {
1477                 if (asprintf(&udev_device->devnode, TEST_PREFIX "/dev/%s", devnode) < 0)
1478                         udev_device->devnode = NULL;
1479         } else {
1480                 udev_device->devnode = strdup(devnode);
1481         }
1482         if (udev_device->devnode == NULL)
1483                 return -ENOMEM;
1484         udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);
1485         return 0;
1486 }
1487
1488 int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink, int unique)
1489 {
1490         struct udev_list_entry *list_entry;
1491
1492         udev_device->devlinks_uptodate = false;
1493         list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL);
1494         if (list_entry == NULL)
1495                 return -ENOMEM;
1496         if (unique)
1497                 udev_list_entry_set_num(list_entry, true);
1498         return 0;
1499 }
1500
1501 const char *udev_device_get_id_filename(struct udev_device *udev_device)
1502 {
1503         if (udev_device->id_filename == NULL) {
1504                 if (udev_device_get_subsystem(udev_device) == NULL)
1505                         return NULL;
1506
1507                 if (major(udev_device_get_devnum(udev_device)) > 0) {
1508                         /* use dev_t -- b259:131072, c254:0 */
1509                         if (asprintf(&udev_device->id_filename, "%c%u:%u",
1510                                      streq(udev_device_get_subsystem(udev_device), "block") ? 'b' : 'c',
1511                                      major(udev_device_get_devnum(udev_device)),
1512                                      minor(udev_device_get_devnum(udev_device))) < 0)
1513                                 udev_device->id_filename = NULL;
1514                 } else if (udev_device_get_ifindex(udev_device) > 0) {
1515                         /* use netdev ifindex -- n3 */
1516                         if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0)
1517                                 udev_device->id_filename = NULL;
1518                 } else {
1519                         /*
1520                          * use $subsys:$syname -- pci:0000:00:1f.2
1521                          * sysname() has '!' translated, get it from devpath
1522                          */
1523                         const char *sysname;
1524                         sysname = strrchr(udev_device->devpath, '/');
1525                         if (sysname == NULL)
1526                                 return NULL;
1527                         sysname = &sysname[1];
1528                         if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
1529                                 udev_device->id_filename = NULL;
1530                 }
1531         }
1532         return udev_device->id_filename;
1533 }
1534
1535 /**
1536  * udev_device_get_is_initialized:
1537  * @udev_device: udev device
1538  *
1539  * Check if udev has already handled the device and has set up
1540  * device node permissions and context, or has renamed a network
1541  * device.
1542  *
1543  * This is only implemented for devices with a device node
1544  * or network interfaces. All other devices return 1 here.
1545  *
1546  * Returns: 1 if the device is set up. 0 otherwise.
1547  **/
1548 _public_ int udev_device_get_is_initialized(struct udev_device *udev_device)
1549 {
1550         if (!udev_device->info_loaded)
1551                 udev_device_read_db(udev_device, NULL);
1552         return udev_device->is_initialized;
1553 }
1554
1555 void udev_device_set_is_initialized(struct udev_device *udev_device)
1556 {
1557         udev_device->is_initialized = true;
1558 }
1559
1560 int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
1561 {
1562         if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
1563                 return -EINVAL;
1564         udev_device->tags_uptodate = false;
1565         if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL)
1566                 return 0;
1567         return -ENOMEM;
1568 }
1569
1570 void udev_device_cleanup_tags_list(struct udev_device *udev_device)
1571 {
1572         udev_device->tags_uptodate = false;
1573         udev_list_cleanup(&udev_device->tags_list);
1574 }
1575
1576 /**
1577  * udev_device_get_tags_list_entry:
1578  * @udev_device: udev device
1579  *
1580  * Retrieve the list of tags attached to the udev device. The next
1581  * list entry can be retrieved with udev_list_entry_get_next(),
1582  * which returns #NULL if no more entries exist. The tag string
1583  * can be retrieved from the list entry by udev_list_entry_get_name().
1584  *
1585  * Returns: the first entry of the tag list
1586  **/
1587 _public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
1588 {
1589         if (udev_device == NULL)
1590                 return NULL;
1591         if (!udev_device->info_loaded)
1592                 udev_device_read_db(udev_device, NULL);
1593         return udev_list_get_entry(&udev_device->tags_list);
1594 }
1595
1596 /**
1597  * udev_device_has_tag:
1598  * @udev_device: udev device
1599  * @tag: tag name
1600  *
1601  * Check if a given device has a certain tag associated.
1602  *
1603  * Returns: 1 if the tag is found. 0 otherwise.
1604  **/
1605 _public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
1606 {
1607         struct udev_list_entry *list_entry;
1608
1609         if (udev_device == NULL)
1610                 return false;
1611         if (!udev_device->info_loaded)
1612                 udev_device_read_db(udev_device, NULL);
1613         list_entry = udev_device_get_tags_list_entry(udev_device);
1614         if (udev_list_entry_get_by_name(list_entry, tag) != NULL)
1615                 return true;
1616         return false;
1617 }
1618
1619 #define ENVP_SIZE                        128
1620 #define MONITOR_BUF_SIZE                4096
1621 static int update_envp_monitor_buf(struct udev_device *udev_device)
1622 {
1623         struct udev_list_entry *list_entry;
1624         char *s;
1625         size_t l;
1626         unsigned int i;
1627
1628         /* monitor buffer of property strings */
1629         free(udev_device->monitor_buf);
1630         udev_device->monitor_buf_len = 0;
1631         udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE);
1632         if (udev_device->monitor_buf == NULL)
1633                 return -ENOMEM;
1634
1635         /* envp array, strings will point into monitor buffer */
1636         if (udev_device->envp == NULL)
1637                 udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE);
1638         if (udev_device->envp == NULL)
1639                 return -ENOMEM;
1640
1641         i = 0;
1642         s = udev_device->monitor_buf;
1643         l = MONITOR_BUF_SIZE;
1644         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
1645                 const char *key;
1646
1647                 key = udev_list_entry_get_name(list_entry);
1648                 /* skip private variables */
1649                 if (key[0] == '.')
1650                         continue;
1651
1652                 /* add string to envp array */
1653                 udev_device->envp[i++] = s;
1654                 if (i+1 >= ENVP_SIZE)
1655                         return -EINVAL;
1656
1657                 /* add property string to monitor buffer */
1658                 l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
1659                 if (l == 0)
1660                         return -EINVAL;
1661                 /* advance past the trailing '\0' that util_strpcpyl() guarantees */
1662                 s++;
1663                 l--;
1664         }
1665         udev_device->envp[i] = NULL;
1666         udev_device->monitor_buf_len = s - udev_device->monitor_buf;
1667         udev_device->envp_uptodate = true;
1668         return 0;
1669 }
1670
1671 char **udev_device_get_properties_envp(struct udev_device *udev_device)
1672 {
1673         if (!udev_device->envp_uptodate)
1674                 if (update_envp_monitor_buf(udev_device) != 0)
1675                         return NULL;
1676         return udev_device->envp;
1677 }
1678
1679 ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf)
1680 {
1681         if (!udev_device->envp_uptodate)
1682                 if (update_envp_monitor_buf(udev_device) != 0)
1683                         return -EINVAL;
1684         *buf = udev_device->monitor_buf;
1685         return udev_device->monitor_buf_len;
1686 }
1687
1688 int udev_device_set_action(struct udev_device *udev_device, const char *action)
1689 {
1690         free(udev_device->action);
1691         udev_device->action = strdup(action);
1692         if (udev_device->action == NULL)
1693                 return -ENOMEM;
1694         udev_device_add_property(udev_device, "ACTION", udev_device->action);
1695         return 0;
1696 }
1697
1698 int udev_device_get_devlink_priority(struct udev_device *udev_device)
1699 {
1700         if (!udev_device->info_loaded)
1701                 udev_device_read_db(udev_device, NULL);
1702         return udev_device->devlink_priority;
1703 }
1704
1705 int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio)
1706 {
1707          udev_device->devlink_priority = prio;
1708         return 0;
1709 }
1710
1711 int udev_device_get_watch_handle(struct udev_device *udev_device)
1712 {
1713         if (!udev_device->info_loaded)
1714                 udev_device_read_db(udev_device, NULL);
1715         return udev_device->watch_handle;
1716 }
1717
1718 int udev_device_set_watch_handle(struct udev_device *udev_device, int handle)
1719 {
1720         udev_device->watch_handle = handle;
1721         return 0;
1722 }
1723
1724 bool udev_device_get_db_persist(struct udev_device *udev_device)
1725 {
1726         return udev_device->db_persist;
1727 }
1728
1729 void udev_device_set_db_persist(struct udev_device *udev_device)
1730 {
1731         udev_device->db_persist = true;
1732 }