chiark / gitweb /
f0aab5d4649d4de926ba1f8f52f2bd2163a7cc10
[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_ struct udev_device *udev_device_unref(struct udev_device *udev_device)
1027 {
1028         if (udev_device == NULL)
1029                 return NULL;
1030         udev_device->refcount--;
1031         if (udev_device->refcount > 0)
1032                 return udev_device;
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         return NULL;
1053 }
1054
1055 /**
1056  * udev_device_get_devpath:
1057  * @udev_device: udev device
1058  *
1059  * Retrieve the kernel devpath value of the udev device. The path
1060  * does not contain the sys mount point, and starts with a '/'.
1061  *
1062  * Returns: the devpath of the udev device
1063  **/
1064 _public_ const char *udev_device_get_devpath(struct udev_device *udev_device)
1065 {
1066         if (udev_device == NULL)
1067                 return NULL;
1068         return udev_device->devpath;
1069 }
1070
1071 /**
1072  * udev_device_get_syspath:
1073  * @udev_device: udev device
1074  *
1075  * Retrieve the sys path of the udev device. The path is an
1076  * absolute path and starts with the sys mount point.
1077  *
1078  * Returns: the sys path of the udev device
1079  **/
1080 _public_ const char *udev_device_get_syspath(struct udev_device *udev_device)
1081 {
1082         if (udev_device == NULL)
1083                 return NULL;
1084         return udev_device->syspath;
1085 }
1086
1087 /**
1088  * udev_device_get_sysname:
1089  * @udev_device: udev device
1090  *
1091  * Get the kernel device name in /sys.
1092  *
1093  * Returns: the name string of the device device
1094  **/
1095 _public_ const char *udev_device_get_sysname(struct udev_device *udev_device)
1096 {
1097         if (udev_device == NULL)
1098                 return NULL;
1099         return udev_device->sysname;
1100 }
1101
1102 /**
1103  * udev_device_get_sysnum:
1104  * @udev_device: udev device
1105  *
1106  * Get the instance number of the device.
1107  *
1108  * Returns: the trailing number string of of the device name
1109  **/
1110 _public_ const char *udev_device_get_sysnum(struct udev_device *udev_device)
1111 {
1112         if (udev_device == NULL)
1113                 return NULL;
1114         return udev_device->sysnum;
1115 }
1116
1117 /**
1118  * udev_device_get_devnode:
1119  * @udev_device: udev device
1120  *
1121  * Retrieve the device node file name belonging to the udev device.
1122  * The path is an absolute path, and starts with the device directory.
1123  *
1124  * Returns: the device node file name of the udev device, or #NULL if no device node exists
1125  **/
1126 _public_ const char *udev_device_get_devnode(struct udev_device *udev_device)
1127 {
1128         if (udev_device == NULL)
1129                 return NULL;
1130         if (udev_device->devnode != NULL)
1131                 return udev_device->devnode;
1132         if (!udev_device->info_loaded)
1133                 udev_device_read_uevent_file(udev_device);
1134         return udev_device->devnode;
1135 }
1136
1137 /**
1138  * udev_device_get_devlinks_list_entry:
1139  * @udev_device: udev device
1140  *
1141  * Retrieve the list of device links pointing to the device file of
1142  * the udev device. The next list entry can be retrieved with
1143  * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
1144  * The devlink path can be retrieved from the list entry by
1145  * udev_list_entry_get_name(). The path is an absolute path, and starts with
1146  * the device directory.
1147  *
1148  * Returns: the first entry of the device node link list
1149  **/
1150 _public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
1151 {
1152         if (udev_device == NULL)
1153                 return NULL;
1154         if (!udev_device->info_loaded)
1155                 udev_device_read_db(udev_device, NULL);
1156         return udev_list_get_entry(&udev_device->devlinks_list);
1157 }
1158
1159 void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
1160 {
1161         udev_device->devlinks_uptodate = false;
1162         udev_list_cleanup(&udev_device->devlinks_list);
1163 }
1164
1165 /**
1166  * udev_device_get_properties_list_entry:
1167  * @udev_device: udev device
1168  *
1169  * Retrieve the list of key/value device properties of the udev
1170  * device. The next list entry can be retrieved with udev_list_entry_get_next(),
1171  * which returns #NULL if no more entries exist. The property name
1172  * can be retrieved from the list entry by udev_list_entry_get_name(),
1173  * the property value by udev_list_entry_get_value().
1174  *
1175  * Returns: the first entry of the property list
1176  **/
1177 _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
1178 {
1179         if (udev_device == NULL)
1180                 return NULL;
1181         if (!udev_device->info_loaded) {
1182                 udev_device_read_uevent_file(udev_device);
1183                 udev_device_read_db(udev_device, NULL);
1184         }
1185         if (!udev_device->devlinks_uptodate) {
1186                 char symlinks[UTIL_PATH_SIZE];
1187                 struct udev_list_entry *list_entry;
1188
1189                 udev_device->devlinks_uptodate = true;
1190                 list_entry = udev_device_get_devlinks_list_entry(udev_device);
1191                 if (list_entry != NULL) {
1192                         char *s;
1193                         size_t l;
1194
1195                         s = symlinks;
1196                         l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
1197                         udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
1198                                 l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
1199                         udev_device_add_property(udev_device, "DEVLINKS", symlinks);
1200                 }
1201         }
1202         if (!udev_device->tags_uptodate) {
1203                 udev_device->tags_uptodate = true;
1204                 if (udev_device_get_tags_list_entry(udev_device) != NULL) {
1205                         char tags[UTIL_PATH_SIZE];
1206                         struct udev_list_entry *list_entry;
1207                         char *s;
1208                         size_t l;
1209
1210                         s = tags;
1211                         l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
1212                         udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
1213                                 l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
1214                         udev_device_add_property(udev_device, "TAGS", tags);
1215                 }
1216         }
1217         return udev_list_get_entry(&udev_device->properties_list);
1218 }
1219
1220 /**
1221  * udev_device_get_action:
1222  * @udev_device: udev device
1223  *
1224  * This is only valid if the device was received through a monitor. Devices read from
1225  * sys do not have an action string. Usual actions are: add, remove, change, online,
1226  * offline.
1227  *
1228  * Returns: the kernel action value, or #NULL if there is no action value available.
1229  **/
1230 _public_ const char *udev_device_get_action(struct udev_device *udev_device)
1231 {
1232         if (udev_device == NULL)
1233                 return NULL;
1234         return udev_device->action;
1235 }
1236
1237 /**
1238  * udev_device_get_usec_since_initialized:
1239  * @udev_device: udev device
1240  *
1241  * Return the number of microseconds passed since udev set up the
1242  * device for the first time.
1243  *
1244  * This is only implemented for devices with need to store properties
1245  * in the udev database. All other devices return 0 here.
1246  *
1247  * Returns: the number of microseconds since the device was first seen.
1248  **/
1249 _public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
1250 {
1251         unsigned long long now_ts;
1252
1253         if (udev_device == NULL)
1254                 return 0;
1255         if (!udev_device->info_loaded)
1256                 udev_device_read_db(udev_device, NULL);
1257         if (udev_device->usec_initialized == 0)
1258                 return 0;
1259         now_ts = now_usec();
1260         if (now_ts == 0)
1261                 return 0;
1262         return now_ts - udev_device->usec_initialized;
1263 }
1264
1265 unsigned long long udev_device_get_usec_initialized(struct udev_device *udev_device)
1266 {
1267         return udev_device->usec_initialized;
1268 }
1269
1270 void udev_device_set_usec_initialized(struct udev_device *udev_device, unsigned long long usec_initialized)
1271 {
1272         char num[32];
1273
1274         udev_device->usec_initialized = usec_initialized;
1275         snprintf(num, sizeof(num), "%llu", usec_initialized);
1276         udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
1277 }
1278
1279 /**
1280  * udev_device_get_sysattr_value:
1281  * @udev_device: udev device
1282  * @sysattr: attribute name
1283  *
1284  * The retrieved value is cached in the device. Repeated calls will return the same
1285  * value and not open the attribute again.
1286  *
1287  * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
1288  **/
1289 _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
1290 {
1291         struct udev_list_entry *list_entry;
1292         char path[UTIL_PATH_SIZE];
1293         char value[4096];
1294         struct stat statbuf;
1295         int fd;
1296         ssize_t size;
1297         const char *val = NULL;
1298
1299         if (udev_device == NULL)
1300                 return NULL;
1301         if (sysattr == NULL)
1302                 return NULL;
1303
1304         /* look for possibly already cached result */
1305         list_entry = udev_list_get_entry(&udev_device->sysattr_value_list);
1306         list_entry = udev_list_entry_get_by_name(list_entry, sysattr);
1307         if (list_entry != NULL)
1308                 return udev_list_entry_get_value(list_entry);
1309
1310         util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
1311         if (lstat(path, &statbuf) != 0) {
1312                 udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL);
1313                 goto out;
1314         }
1315
1316         if (S_ISLNK(statbuf.st_mode)) {
1317                 struct udev_device *dev;
1318
1319                 /*
1320                  * Some core links return only the last element of the target path,
1321                  * these are just values, the paths should not be exposed.
1322                  */
1323                 if (streq(sysattr, "driver") ||
1324                     streq(sysattr, "subsystem") ||
1325                     streq(sysattr, "module")) {
1326                         if (util_get_sys_core_link_value(udev_device->udev, sysattr,
1327                                                          udev_device->syspath, value, sizeof(value)) < 0)
1328                                 return NULL;
1329                         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
1330                         val = udev_list_entry_get_value(list_entry);
1331                         goto out;
1332                 }
1333
1334                 /* resolve link to a device and return its syspath */
1335                 util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
1336                 dev = udev_device_new_from_syspath(udev_device->udev, path);
1337                 if (dev != NULL) {
1338                         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
1339                                                          udev_device_get_syspath(dev));
1340                         val = udev_list_entry_get_value(list_entry);
1341                         udev_device_unref(dev);
1342                 }
1343
1344                 goto out;
1345         }
1346
1347         /* skip directories */
1348         if (S_ISDIR(statbuf.st_mode))
1349                 goto out;
1350
1351         /* skip non-readable files */
1352         if ((statbuf.st_mode & S_IRUSR) == 0)
1353                 goto out;
1354
1355         /* read attribute value */
1356         fd = open(path, O_RDONLY|O_CLOEXEC);
1357         if (fd < 0)
1358                 goto out;
1359         size = read(fd, value, sizeof(value));
1360         close(fd);
1361         if (size < 0)
1362                 goto out;
1363         if (size == sizeof(value))
1364                 goto out;
1365
1366         /* got a valid value, store it in cache and return it */
1367         value[size] = '\0';
1368         util_remove_trailing_chars(value, '\n');
1369         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
1370         val = udev_list_entry_get_value(list_entry);
1371 out:
1372         return val;
1373 }
1374
1375 static int udev_device_sysattr_list_read(struct udev_device *udev_device)
1376 {
1377         struct dirent *dent;
1378         DIR *dir;
1379         int num = 0;
1380
1381         if (udev_device == NULL)
1382                 return -1;
1383         if (udev_device->sysattr_list_read)
1384                 return 0;
1385
1386         dir = opendir(udev_device_get_syspath(udev_device));
1387         if (!dir)
1388                 return -1;
1389
1390         for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
1391                 char path[UTIL_PATH_SIZE];
1392                 struct stat statbuf;
1393
1394                 /* only handle symlinks and regular files */
1395                 if (dent->d_type != DT_LNK && dent->d_type != DT_REG)
1396                         continue;
1397
1398                 util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
1399                 if (lstat(path, &statbuf) != 0)
1400                         continue;
1401                 if ((statbuf.st_mode & S_IRUSR) == 0)
1402                         continue;
1403
1404                 udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL);
1405                 num++;
1406         }
1407
1408         closedir(dir);
1409         udev_device->sysattr_list_read = true;
1410
1411         return num;
1412 }
1413
1414 /**
1415  * udev_device_get_sysattr_list_entry:
1416  * @udev_device: udev device
1417  *
1418  * Retrieve the list of available sysattrs, with value being empty;
1419  * This just return all available sysfs attributes for a particular
1420  * device without reading their values.
1421  *
1422  * Returns: the first entry of the property list
1423  **/
1424 _public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
1425 {
1426         if (!udev_device->sysattr_list_read) {
1427                 int ret;
1428                 ret = udev_device_sysattr_list_read(udev_device);
1429                 if (0 > ret)
1430                         return NULL;
1431         }
1432
1433         return udev_list_get_entry(&udev_device->sysattr_list);
1434 }
1435
1436 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
1437 {
1438         const char *pos;
1439         size_t len;
1440
1441         free(udev_device->syspath);
1442         udev_device->syspath = strdup(syspath);
1443         if (udev_device->syspath ==  NULL)
1444                 return -ENOMEM;
1445         udev_device->devpath = udev_device->syspath + strlen(TEST_PREFIX "/sys");
1446         udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath);
1447
1448         pos = strrchr(udev_device->syspath, '/');
1449         if (pos == NULL)
1450                 return -EINVAL;
1451         udev_device->sysname = strdup(&pos[1]);
1452         if (udev_device->sysname == NULL)
1453                 return -ENOMEM;
1454
1455         /* some devices have '!' in their name, change that to '/' */
1456         len = 0;
1457         while (udev_device->sysname[len] != '\0') {
1458                 if (udev_device->sysname[len] == '!')
1459                         udev_device->sysname[len] = '/';
1460                 len++;
1461         }
1462
1463         /* trailing number */
1464         while (len > 0 && isdigit(udev_device->sysname[--len]))
1465                 udev_device->sysnum = &udev_device->sysname[len];
1466
1467         /* sysname is completely numeric */
1468         if (len == 0)
1469                 udev_device->sysnum = NULL;
1470
1471         return 0;
1472 }
1473
1474 int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
1475 {
1476         free(udev_device->devnode);
1477         if (devnode[0] != '/') {
1478                 if (asprintf(&udev_device->devnode, TEST_PREFIX "/dev/%s", devnode) < 0)
1479                         udev_device->devnode = NULL;
1480         } else {
1481                 udev_device->devnode = strdup(devnode);
1482         }
1483         if (udev_device->devnode == NULL)
1484                 return -ENOMEM;
1485         udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);
1486         return 0;
1487 }
1488
1489 int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink, int unique)
1490 {
1491         struct udev_list_entry *list_entry;
1492
1493         udev_device->devlinks_uptodate = false;
1494         list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL);
1495         if (list_entry == NULL)
1496                 return -ENOMEM;
1497         if (unique)
1498                 udev_list_entry_set_num(list_entry, true);
1499         return 0;
1500 }
1501
1502 const char *udev_device_get_id_filename(struct udev_device *udev_device)
1503 {
1504         if (udev_device->id_filename == NULL) {
1505                 if (udev_device_get_subsystem(udev_device) == NULL)
1506                         return NULL;
1507
1508                 if (major(udev_device_get_devnum(udev_device)) > 0) {
1509                         /* use dev_t -- b259:131072, c254:0 */
1510                         if (asprintf(&udev_device->id_filename, "%c%u:%u",
1511                                      streq(udev_device_get_subsystem(udev_device), "block") ? 'b' : 'c',
1512                                      major(udev_device_get_devnum(udev_device)),
1513                                      minor(udev_device_get_devnum(udev_device))) < 0)
1514                                 udev_device->id_filename = NULL;
1515                 } else if (udev_device_get_ifindex(udev_device) > 0) {
1516                         /* use netdev ifindex -- n3 */
1517                         if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0)
1518                                 udev_device->id_filename = NULL;
1519                 } else {
1520                         /*
1521                          * use $subsys:$syname -- pci:0000:00:1f.2
1522                          * sysname() has '!' translated, get it from devpath
1523                          */
1524                         const char *sysname;
1525                         sysname = strrchr(udev_device->devpath, '/');
1526                         if (sysname == NULL)
1527                                 return NULL;
1528                         sysname = &sysname[1];
1529                         if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
1530                                 udev_device->id_filename = NULL;
1531                 }
1532         }
1533         return udev_device->id_filename;
1534 }
1535
1536 /**
1537  * udev_device_get_is_initialized:
1538  * @udev_device: udev device
1539  *
1540  * Check if udev has already handled the device and has set up
1541  * device node permissions and context, or has renamed a network
1542  * device.
1543  *
1544  * This is only implemented for devices with a device node
1545  * or network interfaces. All other devices return 1 here.
1546  *
1547  * Returns: 1 if the device is set up. 0 otherwise.
1548  **/
1549 _public_ int udev_device_get_is_initialized(struct udev_device *udev_device)
1550 {
1551         if (!udev_device->info_loaded)
1552                 udev_device_read_db(udev_device, NULL);
1553         return udev_device->is_initialized;
1554 }
1555
1556 void udev_device_set_is_initialized(struct udev_device *udev_device)
1557 {
1558         udev_device->is_initialized = true;
1559 }
1560
1561 int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
1562 {
1563         if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
1564                 return -EINVAL;
1565         udev_device->tags_uptodate = false;
1566         if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL)
1567                 return 0;
1568         return -ENOMEM;
1569 }
1570
1571 void udev_device_cleanup_tags_list(struct udev_device *udev_device)
1572 {
1573         udev_device->tags_uptodate = false;
1574         udev_list_cleanup(&udev_device->tags_list);
1575 }
1576
1577 /**
1578  * udev_device_get_tags_list_entry:
1579  * @udev_device: udev device
1580  *
1581  * Retrieve the list of tags attached to the udev device. The next
1582  * list entry can be retrieved with udev_list_entry_get_next(),
1583  * which returns #NULL if no more entries exist. The tag string
1584  * can be retrieved from the list entry by udev_list_entry_get_name().
1585  *
1586  * Returns: the first entry of the tag list
1587  **/
1588 _public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
1589 {
1590         if (udev_device == NULL)
1591                 return NULL;
1592         if (!udev_device->info_loaded)
1593                 udev_device_read_db(udev_device, NULL);
1594         return udev_list_get_entry(&udev_device->tags_list);
1595 }
1596
1597 /**
1598  * udev_device_has_tag:
1599  * @udev_device: udev device
1600  * @tag: tag name
1601  *
1602  * Check if a given device has a certain tag associated.
1603  *
1604  * Returns: 1 if the tag is found. 0 otherwise.
1605  **/
1606 _public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
1607 {
1608         struct udev_list_entry *list_entry;
1609
1610         if (udev_device == NULL)
1611                 return false;
1612         if (!udev_device->info_loaded)
1613                 udev_device_read_db(udev_device, NULL);
1614         list_entry = udev_device_get_tags_list_entry(udev_device);
1615         if (udev_list_entry_get_by_name(list_entry, tag) != NULL)
1616                 return true;
1617         return false;
1618 }
1619
1620 #define ENVP_SIZE                        128
1621 #define MONITOR_BUF_SIZE                4096
1622 static int update_envp_monitor_buf(struct udev_device *udev_device)
1623 {
1624         struct udev_list_entry *list_entry;
1625         char *s;
1626         size_t l;
1627         unsigned int i;
1628
1629         /* monitor buffer of property strings */
1630         free(udev_device->monitor_buf);
1631         udev_device->monitor_buf_len = 0;
1632         udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE);
1633         if (udev_device->monitor_buf == NULL)
1634                 return -ENOMEM;
1635
1636         /* envp array, strings will point into monitor buffer */
1637         if (udev_device->envp == NULL)
1638                 udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE);
1639         if (udev_device->envp == NULL)
1640                 return -ENOMEM;
1641
1642         i = 0;
1643         s = udev_device->monitor_buf;
1644         l = MONITOR_BUF_SIZE;
1645         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
1646                 const char *key;
1647
1648                 key = udev_list_entry_get_name(list_entry);
1649                 /* skip private variables */
1650                 if (key[0] == '.')
1651                         continue;
1652
1653                 /* add string to envp array */
1654                 udev_device->envp[i++] = s;
1655                 if (i+1 >= ENVP_SIZE)
1656                         return -EINVAL;
1657
1658                 /* add property string to monitor buffer */
1659                 l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
1660                 if (l == 0)
1661                         return -EINVAL;
1662                 /* advance past the trailing '\0' that util_strpcpyl() guarantees */
1663                 s++;
1664                 l--;
1665         }
1666         udev_device->envp[i] = NULL;
1667         udev_device->monitor_buf_len = s - udev_device->monitor_buf;
1668         udev_device->envp_uptodate = true;
1669         return 0;
1670 }
1671
1672 char **udev_device_get_properties_envp(struct udev_device *udev_device)
1673 {
1674         if (!udev_device->envp_uptodate)
1675                 if (update_envp_monitor_buf(udev_device) != 0)
1676                         return NULL;
1677         return udev_device->envp;
1678 }
1679
1680 ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf)
1681 {
1682         if (!udev_device->envp_uptodate)
1683                 if (update_envp_monitor_buf(udev_device) != 0)
1684                         return -EINVAL;
1685         *buf = udev_device->monitor_buf;
1686         return udev_device->monitor_buf_len;
1687 }
1688
1689 int udev_device_set_action(struct udev_device *udev_device, const char *action)
1690 {
1691         free(udev_device->action);
1692         udev_device->action = strdup(action);
1693         if (udev_device->action == NULL)
1694                 return -ENOMEM;
1695         udev_device_add_property(udev_device, "ACTION", udev_device->action);
1696         return 0;
1697 }
1698
1699 int udev_device_get_devlink_priority(struct udev_device *udev_device)
1700 {
1701         if (!udev_device->info_loaded)
1702                 udev_device_read_db(udev_device, NULL);
1703         return udev_device->devlink_priority;
1704 }
1705
1706 int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio)
1707 {
1708          udev_device->devlink_priority = prio;
1709         return 0;
1710 }
1711
1712 int udev_device_get_watch_handle(struct udev_device *udev_device)
1713 {
1714         if (!udev_device->info_loaded)
1715                 udev_device_read_db(udev_device, NULL);
1716         return udev_device->watch_handle;
1717 }
1718
1719 int udev_device_set_watch_handle(struct udev_device *udev_device, int handle)
1720 {
1721         udev_device->watch_handle = handle;
1722         return 0;
1723 }
1724
1725 bool udev_device_get_db_persist(struct udev_device *udev_device)
1726 {
1727         return udev_device->db_persist;
1728 }
1729
1730 void udev_device_set_db_persist(struct udev_device *udev_device)
1731 {
1732         udev_device->db_persist = true;
1733 }