chiark / gitweb /
181a9d8eebf394135a10a0ea88e936500d705baf
[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         usec_t 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 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), "/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);
382                         slink = &next[1];
383                         next = strchr(slink, ' ');
384                 }
385                 if (slink[0] != '\0')
386                         udev_device_add_devlink(udev_device, slink);
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), "/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), "/dev/", val, NULL);
506                         udev_device_add_devlink(udev_device, filename);
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, "/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("/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("/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), "/sys/dev/%s/%u:%u",
713                  type_str, major(devnum), minor(devnum));
714         return udev_device_new_from_syspath(udev, path);
715 }
716
717 /**
718  * udev_device_new_from_device_id:
719  * @udev: udev library context
720  * @id: text string identifying a kernel device
721  *
722  * Create new udev device, and fill in information from the sys
723  * device and the udev database entry. The device is looked-up
724  * by a special string:
725  *   b8:2          - block device major:minor
726  *   c128:1        - char device major:minor
727  *   n3            - network device ifindex
728  *   +sound:card29 - kernel driver core subsystem:device name
729  *
730  * The initial refcount is 1, and needs to be decremented to
731  * release the resources of the udev device.
732  *
733  * Returns: a new udev device, or #NULL, if it does not exist
734  **/
735 _public_ struct udev_device *udev_device_new_from_device_id(struct udev *udev, char *id)
736 {
737         char type;
738         int maj, min;
739         char subsys[UTIL_PATH_SIZE];
740         char *sysname;
741
742         switch(id[0]) {
743         case 'b':
744         case 'c':
745                 if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3)
746                         return NULL;
747                 return udev_device_new_from_devnum(udev, type, makedev(maj, min));
748         case 'n': {
749                 int sk;
750                 struct ifreq ifr;
751                 struct udev_device *dev;
752                 int ifindex;
753
754                 ifindex = strtoul(&id[1], NULL, 10);
755                 if (ifindex <= 0)
756                         return NULL;
757
758                 sk = socket(PF_INET, SOCK_DGRAM, 0);
759                 if (sk < 0)
760                         return NULL;
761                 memset(&ifr, 0x00, sizeof(struct ifreq));
762                 ifr.ifr_ifindex = ifindex;
763                 if (ioctl(sk, SIOCGIFNAME, &ifr) != 0) {
764                         close(sk);
765                         return NULL;
766                 }
767                 close(sk);
768
769                 dev = udev_device_new_from_subsystem_sysname(udev, "net", ifr.ifr_name);
770                 if (dev == NULL)
771                         return NULL;
772                 if (udev_device_get_ifindex(dev) == ifindex)
773                         return dev;
774                 udev_device_unref(dev);
775                 return NULL;
776         }
777         case '+':
778                 util_strscpy(subsys, sizeof(subsys), &id[1]);
779                 sysname = strchr(subsys, ':');
780                 if (sysname == NULL)
781                         return NULL;
782                 sysname[0] = '\0';
783                 sysname = &sysname[1];
784                 return udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
785         default:
786                 return NULL;
787         }
788 }
789
790 /**
791  * udev_device_new_from_subsystem_sysname:
792  * @udev: udev library context
793  * @subsystem: the subsystem of the device
794  * @sysname: the name of the device
795  *
796  * Create new udev device, and fill in information from the sys device
797  * and the udev database entry. The device is looked up by the subsystem
798  * and name string of the device, like "mem" / "zero", or "block" / "sda".
799  *
800  * The initial refcount is 1, and needs to be decremented to
801  * release the resources of the udev device.
802  *
803  * Returns: a new udev device, or #NULL, if it does not exist
804  **/
805 _public_ struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
806 {
807         char path[UTIL_PATH_SIZE];
808         struct stat statbuf;
809
810         if (streq(subsystem, "subsystem")) {
811                 util_strscpyl(path, sizeof(path), "/sys/subsystem/", sysname, NULL);
812                 if (stat(path, &statbuf) == 0)
813                         goto found;
814
815                 util_strscpyl(path, sizeof(path), "/sys/bus/", sysname, NULL);
816                 if (stat(path, &statbuf) == 0)
817                         goto found;
818
819                 util_strscpyl(path, sizeof(path), "/sys/class/", sysname, NULL);
820                 if (stat(path, &statbuf) == 0)
821                         goto found;
822                 goto out;
823         }
824
825         if (streq(subsystem, "module")) {
826                 util_strscpyl(path, sizeof(path), "/sys/module/", sysname, NULL);
827                 if (stat(path, &statbuf) == 0)
828                         goto found;
829                 goto out;
830         }
831
832         if (streq(subsystem, "drivers")) {
833                 char subsys[UTIL_NAME_SIZE];
834                 char *driver;
835
836                 util_strscpy(subsys, sizeof(subsys), sysname);
837                 driver = strchr(subsys, ':');
838                 if (driver != NULL) {
839                         driver[0] = '\0';
840                         driver = &driver[1];
841
842                         util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsys, "/drivers/", driver, NULL);
843                         if (stat(path, &statbuf) == 0)
844                                 goto found;
845
846                         util_strscpyl(path, sizeof(path), "/sys/bus/", subsys, "/drivers/", driver, NULL);
847                         if (stat(path, &statbuf) == 0)
848                                 goto found;
849                 }
850                 goto out;
851         }
852
853         util_strscpyl(path, sizeof(path), "/sys/subsystem/", subsystem, "/devices/", sysname, NULL);
854         if (stat(path, &statbuf) == 0)
855                 goto found;
856
857         util_strscpyl(path, sizeof(path), "/sys/bus/", subsystem, "/devices/", sysname, NULL);
858         if (stat(path, &statbuf) == 0)
859                 goto found;
860
861         util_strscpyl(path, sizeof(path), "/sys/class/", subsystem, "/", sysname, NULL);
862         if (stat(path, &statbuf) == 0)
863                 goto found;
864 out:
865         return NULL;
866 found:
867         return udev_device_new_from_syspath(udev, path);
868 }
869
870 /**
871  * udev_device_new_from_environment
872  * @udev: udev library context
873  *
874  * Create new udev device, and fill in information from the
875  * current process environment. This only works reliable if
876  * the process is called from a udev rule. It is usually used
877  * for tools executed from IMPORT= rules.
878  *
879  * The initial refcount is 1, and needs to be decremented to
880  * release the resources of the udev device.
881  *
882  * Returns: a new udev device, or #NULL, if it does not exist
883  **/
884 _public_ struct udev_device *udev_device_new_from_environment(struct udev *udev)
885 {
886         int i;
887         struct udev_device *udev_device;
888
889         udev_device = udev_device_new(udev);
890         if (udev_device == NULL)
891                 return NULL;
892         udev_device_set_info_loaded(udev_device);
893
894         for (i = 0; environ[i] != NULL; i++)
895                 udev_device_add_property_from_string_parse(udev_device, environ[i]);
896
897         if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
898                 udev_dbg(udev, "missing values, invalid device\n");
899                 udev_device_unref(udev_device);
900                 udev_device = NULL;
901         }
902
903         return udev_device;
904 }
905
906 static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
907 {
908         struct udev_device *udev_device_parent = NULL;
909         char path[UTIL_PATH_SIZE];
910         const char *subdir;
911
912         util_strscpy(path, sizeof(path), udev_device->syspath);
913         subdir = path + strlen("/sys/");
914         for (;;) {
915                 char *pos;
916
917                 pos = strrchr(subdir, '/');
918                 if (pos == NULL || pos < &subdir[2])
919                         break;
920                 pos[0] = '\0';
921                 udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
922                 if (udev_device_parent != NULL)
923                         return udev_device_parent;
924         }
925         return NULL;
926 }
927
928 /**
929  * udev_device_get_parent:
930  * @udev_device: the device to start searching from
931  *
932  * Find the next parent device, and fill in information from the sys
933  * device and the udev database entry.
934  *
935  * The returned the device is not referenced. It is attached to the
936  * child device, and will be cleaned up when the child device
937  * is cleaned up.
938  *
939  * It is not necessarily just the upper level directory, empty or not
940  * recognized sys directories are ignored.
941  *
942  * It can be called as many times as needed, without caring about
943  * references.
944  *
945  * Returns: a new udev device, or #NULL, if it no parent exist.
946  **/
947 _public_ struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
948 {
949         if (udev_device == NULL)
950                 return NULL;
951         if (!udev_device->parent_set) {
952                 udev_device->parent_set = true;
953                 udev_device->parent_device = device_new_from_parent(udev_device);
954         }
955         return udev_device->parent_device;
956 }
957
958 /**
959  * udev_device_get_parent_with_subsystem_devtype:
960  * @udev_device: udev device to start searching from
961  * @subsystem: the subsystem of the device
962  * @devtype: the type (DEVTYPE) of the device
963  *
964  * Find the next parent device, with a matching subsystem and devtype
965  * value, and fill in information from the sys device and the udev
966  * database entry.
967  *
968  * If devtype is #NULL, only subsystem is checked, and any devtype will
969  * match.
970  *
971  * The returned the device is not referenced. It is attached to the
972  * child device, and will be cleaned up when the child device
973  * is cleaned up.
974  *
975  * It can be called as many times as needed, without caring about
976  * references.
977  *
978  * Returns: a new udev device, or #NULL if no matching parent exists.
979  **/
980 _public_ struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
981 {
982         struct udev_device *parent;
983
984         if (subsystem == NULL)
985                 return NULL;
986
987         parent = udev_device_get_parent(udev_device);
988         while (parent != NULL) {
989                 const char *parent_subsystem;
990                 const char *parent_devtype;
991
992                 parent_subsystem = udev_device_get_subsystem(parent);
993                 if (parent_subsystem != NULL && streq(parent_subsystem, subsystem)) {
994                         if (devtype == NULL)
995                                 break;
996                         parent_devtype = udev_device_get_devtype(parent);
997                         if (parent_devtype != NULL && streq(parent_devtype, devtype))
998                                 break;
999                 }
1000                 parent = udev_device_get_parent(parent);
1001         }
1002         return parent;
1003 }
1004
1005 /**
1006  * udev_device_get_udev:
1007  * @udev_device: udev device
1008  *
1009  * Retrieve the udev library context the device was created with.
1010  *
1011  * Returns: the udev library context
1012  **/
1013 _public_ struct udev *udev_device_get_udev(struct udev_device *udev_device)
1014 {
1015         if (udev_device == NULL)
1016                 return NULL;
1017         return udev_device->udev;
1018 }
1019
1020 /**
1021  * udev_device_ref:
1022  * @udev_device: udev device
1023  *
1024  * Take a reference of a udev device.
1025  *
1026  * Returns: the passed udev device
1027  **/
1028 _public_ struct udev_device *udev_device_ref(struct udev_device *udev_device)
1029 {
1030         if (udev_device == NULL)
1031                 return NULL;
1032         udev_device->refcount++;
1033         return udev_device;
1034 }
1035
1036 /**
1037  * udev_device_unref:
1038  * @udev_device: udev device
1039  *
1040  * Drop a reference of a udev device. If the refcount reaches zero,
1041  * the resources of the device will be released.
1042  *
1043  * Returns: the passed udev device if it has still an active reference, or #NULL otherwise.
1044  **/
1045 _public_ struct udev_device *udev_device_unref(struct udev_device *udev_device)
1046 {
1047         if (udev_device == NULL)
1048                 return NULL;
1049         udev_device->refcount--;
1050         if (udev_device->refcount > 0)
1051                 return udev_device;
1052         if (udev_device->parent_device != NULL)
1053                 udev_device_unref(udev_device->parent_device);
1054         free(udev_device->syspath);
1055         free(udev_device->sysname);
1056         free(udev_device->devnode);
1057         free(udev_device->subsystem);
1058         free(udev_device->devtype);
1059         udev_list_cleanup(&udev_device->devlinks_list);
1060         udev_list_cleanup(&udev_device->properties_list);
1061         udev_list_cleanup(&udev_device->sysattr_value_list);
1062         udev_list_cleanup(&udev_device->sysattr_list);
1063         udev_list_cleanup(&udev_device->tags_list);
1064         free(udev_device->action);
1065         free(udev_device->driver);
1066         free(udev_device->devpath_old);
1067         free(udev_device->id_filename);
1068         free(udev_device->envp);
1069         free(udev_device->monitor_buf);
1070         free(udev_device);
1071         return NULL;
1072 }
1073
1074 /**
1075  * udev_device_get_devpath:
1076  * @udev_device: udev device
1077  *
1078  * Retrieve the kernel devpath value of the udev device. The path
1079  * does not contain the sys mount point, and starts with a '/'.
1080  *
1081  * Returns: the devpath of the udev device
1082  **/
1083 _public_ const char *udev_device_get_devpath(struct udev_device *udev_device)
1084 {
1085         if (udev_device == NULL)
1086                 return NULL;
1087         return udev_device->devpath;
1088 }
1089
1090 /**
1091  * udev_device_get_syspath:
1092  * @udev_device: udev device
1093  *
1094  * Retrieve the sys path of the udev device. The path is an
1095  * absolute path and starts with the sys mount point.
1096  *
1097  * Returns: the sys path of the udev device
1098  **/
1099 _public_ const char *udev_device_get_syspath(struct udev_device *udev_device)
1100 {
1101         if (udev_device == NULL)
1102                 return NULL;
1103         return udev_device->syspath;
1104 }
1105
1106 /**
1107  * udev_device_get_sysname:
1108  * @udev_device: udev device
1109  *
1110  * Get the kernel device name in /sys.
1111  *
1112  * Returns: the name string of the device device
1113  **/
1114 _public_ const char *udev_device_get_sysname(struct udev_device *udev_device)
1115 {
1116         if (udev_device == NULL)
1117                 return NULL;
1118         return udev_device->sysname;
1119 }
1120
1121 /**
1122  * udev_device_get_sysnum:
1123  * @udev_device: udev device
1124  *
1125  * Get the instance number of the device.
1126  *
1127  * Returns: the trailing number string of the device name
1128  **/
1129 _public_ const char *udev_device_get_sysnum(struct udev_device *udev_device)
1130 {
1131         if (udev_device == NULL)
1132                 return NULL;
1133         return udev_device->sysnum;
1134 }
1135
1136 /**
1137  * udev_device_get_devnode:
1138  * @udev_device: udev device
1139  *
1140  * Retrieve the device node file name belonging to the udev device.
1141  * The path is an absolute path, and starts with the device directory.
1142  *
1143  * Returns: the device node file name of the udev device, or #NULL if no device node exists
1144  **/
1145 _public_ const char *udev_device_get_devnode(struct udev_device *udev_device)
1146 {
1147         if (udev_device == NULL)
1148                 return NULL;
1149         if (udev_device->devnode != NULL)
1150                 return udev_device->devnode;
1151         if (!udev_device->info_loaded)
1152                 udev_device_read_uevent_file(udev_device);
1153         return udev_device->devnode;
1154 }
1155
1156 /**
1157  * udev_device_get_devlinks_list_entry:
1158  * @udev_device: udev device
1159  *
1160  * Retrieve the list of device links pointing to the device file of
1161  * the udev device. The next list entry can be retrieved with
1162  * udev_list_entry_get_next(), which returns #NULL if no more entries exist.
1163  * The devlink path can be retrieved from the list entry by
1164  * udev_list_entry_get_name(). The path is an absolute path, and starts with
1165  * the device directory.
1166  *
1167  * Returns: the first entry of the device node link list
1168  **/
1169 _public_ struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
1170 {
1171         if (udev_device == NULL)
1172                 return NULL;
1173         if (!udev_device->info_loaded)
1174                 udev_device_read_db(udev_device, NULL);
1175         return udev_list_get_entry(&udev_device->devlinks_list);
1176 }
1177
1178 void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
1179 {
1180         udev_device->devlinks_uptodate = false;
1181         udev_list_cleanup(&udev_device->devlinks_list);
1182 }
1183
1184 /**
1185  * udev_device_get_properties_list_entry:
1186  * @udev_device: udev device
1187  *
1188  * Retrieve the list of key/value device properties of the udev
1189  * device. The next list entry can be retrieved with udev_list_entry_get_next(),
1190  * which returns #NULL if no more entries exist. The property name
1191  * can be retrieved from the list entry by udev_list_entry_get_name(),
1192  * the property value by udev_list_entry_get_value().
1193  *
1194  * Returns: the first entry of the property list
1195  **/
1196 _public_ struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
1197 {
1198         if (udev_device == NULL)
1199                 return NULL;
1200         if (!udev_device->info_loaded) {
1201                 udev_device_read_uevent_file(udev_device);
1202                 udev_device_read_db(udev_device, NULL);
1203         }
1204         if (!udev_device->devlinks_uptodate) {
1205                 char symlinks[UTIL_PATH_SIZE];
1206                 struct udev_list_entry *list_entry;
1207
1208                 udev_device->devlinks_uptodate = true;
1209                 list_entry = udev_device_get_devlinks_list_entry(udev_device);
1210                 if (list_entry != NULL) {
1211                         char *s;
1212                         size_t l;
1213
1214                         s = symlinks;
1215                         l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
1216                         udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
1217                                 l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
1218                         udev_device_add_property(udev_device, "DEVLINKS", symlinks);
1219                 }
1220         }
1221         if (!udev_device->tags_uptodate) {
1222                 udev_device->tags_uptodate = true;
1223                 if (udev_device_get_tags_list_entry(udev_device) != NULL) {
1224                         char tags[UTIL_PATH_SIZE];
1225                         struct udev_list_entry *list_entry;
1226                         char *s;
1227                         size_t l;
1228
1229                         s = tags;
1230                         l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
1231                         udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
1232                                 l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
1233                         udev_device_add_property(udev_device, "TAGS", tags);
1234                 }
1235         }
1236         return udev_list_get_entry(&udev_device->properties_list);
1237 }
1238
1239 /**
1240  * udev_device_get_action:
1241  * @udev_device: udev device
1242  *
1243  * This is only valid if the device was received through a monitor. Devices read from
1244  * sys do not have an action string. Usual actions are: add, remove, change, online,
1245  * offline.
1246  *
1247  * Returns: the kernel action value, or #NULL if there is no action value available.
1248  **/
1249 _public_ const char *udev_device_get_action(struct udev_device *udev_device)
1250 {
1251         if (udev_device == NULL)
1252                 return NULL;
1253         return udev_device->action;
1254 }
1255
1256 /**
1257  * udev_device_get_usec_since_initialized:
1258  * @udev_device: udev device
1259  *
1260  * Return the number of microseconds passed since udev set up the
1261  * device for the first time.
1262  *
1263  * This is only implemented for devices with need to store properties
1264  * in the udev database. All other devices return 0 here.
1265  *
1266  * Returns: the number of microseconds since the device was first seen.
1267  **/
1268 _public_ unsigned long long int udev_device_get_usec_since_initialized(struct udev_device *udev_device)
1269 {
1270         usec_t now_ts;
1271
1272         if (udev_device == NULL)
1273                 return 0;
1274         if (!udev_device->info_loaded)
1275                 udev_device_read_db(udev_device, NULL);
1276         if (udev_device->usec_initialized == 0)
1277                 return 0;
1278         now_ts = now(CLOCK_MONOTONIC);
1279         if (now_ts == 0)
1280                 return 0;
1281         return now_ts - udev_device->usec_initialized;
1282 }
1283
1284 usec_t udev_device_get_usec_initialized(struct udev_device *udev_device)
1285 {
1286         return udev_device->usec_initialized;
1287 }
1288
1289 void udev_device_set_usec_initialized(struct udev_device *udev_device, usec_t usec_initialized)
1290 {
1291         char num[32];
1292
1293         udev_device->usec_initialized = usec_initialized;
1294         snprintf(num, sizeof(num), "%llu", (unsigned long long)usec_initialized);
1295         udev_device_add_property(udev_device, "USEC_INITIALIZED", num);
1296 }
1297
1298 /**
1299  * udev_device_get_sysattr_value:
1300  * @udev_device: udev device
1301  * @sysattr: attribute name
1302  *
1303  * The retrieved value is cached in the device. Repeated calls will return the same
1304  * value and not open the attribute again.
1305  *
1306  * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
1307  **/
1308 _public_ const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
1309 {
1310         struct udev_list_entry *list_entry;
1311         char path[UTIL_PATH_SIZE];
1312         char value[4096];
1313         struct stat statbuf;
1314         int fd;
1315         ssize_t size;
1316         const char *val = NULL;
1317
1318         if (udev_device == NULL)
1319                 return NULL;
1320         if (sysattr == NULL)
1321                 return NULL;
1322
1323         /* look for possibly already cached result */
1324         list_entry = udev_list_get_entry(&udev_device->sysattr_value_list);
1325         list_entry = udev_list_entry_get_by_name(list_entry, sysattr);
1326         if (list_entry != NULL)
1327                 return udev_list_entry_get_value(list_entry);
1328
1329         util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
1330         if (lstat(path, &statbuf) != 0) {
1331                 udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, NULL);
1332                 goto out;
1333         }
1334
1335         if (S_ISLNK(statbuf.st_mode)) {
1336                 struct udev_device *dev;
1337
1338                 /*
1339                  * Some core links return only the last element of the target path,
1340                  * these are just values, the paths should not be exposed.
1341                  */
1342                 if (streq(sysattr, "driver") ||
1343                     streq(sysattr, "subsystem") ||
1344                     streq(sysattr, "module")) {
1345                         if (util_get_sys_core_link_value(udev_device->udev, sysattr,
1346                                                          udev_device->syspath, value, sizeof(value)) < 0)
1347                                 return NULL;
1348                         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
1349                         val = udev_list_entry_get_value(list_entry);
1350                         goto out;
1351                 }
1352
1353                 /* resolve link to a device and return its syspath */
1354                 util_strscpyl(path, sizeof(path), udev_device->syspath, "/", sysattr, NULL);
1355                 dev = udev_device_new_from_syspath(udev_device->udev, path);
1356                 if (dev != NULL) {
1357                         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr,
1358                                                          udev_device_get_syspath(dev));
1359                         val = udev_list_entry_get_value(list_entry);
1360                         udev_device_unref(dev);
1361                 }
1362
1363                 goto out;
1364         }
1365
1366         /* skip directories */
1367         if (S_ISDIR(statbuf.st_mode))
1368                 goto out;
1369
1370         /* skip non-readable files */
1371         if ((statbuf.st_mode & S_IRUSR) == 0)
1372                 goto out;
1373
1374         /* read attribute value */
1375         fd = open(path, O_RDONLY|O_CLOEXEC);
1376         if (fd < 0)
1377                 goto out;
1378         size = read(fd, value, sizeof(value));
1379         close(fd);
1380         if (size < 0)
1381                 goto out;
1382         if (size == sizeof(value))
1383                 goto out;
1384
1385         /* got a valid value, store it in cache and return it */
1386         value[size] = '\0';
1387         util_remove_trailing_chars(value, '\n');
1388         list_entry = udev_list_entry_add(&udev_device->sysattr_value_list, sysattr, value);
1389         val = udev_list_entry_get_value(list_entry);
1390 out:
1391         return val;
1392 }
1393
1394 static int udev_device_sysattr_list_read(struct udev_device *udev_device)
1395 {
1396         struct dirent *dent;
1397         DIR *dir;
1398         int num = 0;
1399
1400         if (udev_device == NULL)
1401                 return -1;
1402         if (udev_device->sysattr_list_read)
1403                 return 0;
1404
1405         dir = opendir(udev_device_get_syspath(udev_device));
1406         if (!dir)
1407                 return -1;
1408
1409         for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
1410                 char path[UTIL_PATH_SIZE];
1411                 struct stat statbuf;
1412
1413                 /* only handle symlinks and regular files */
1414                 if (dent->d_type != DT_LNK && dent->d_type != DT_REG)
1415                         continue;
1416
1417                 util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", dent->d_name, NULL);
1418                 if (lstat(path, &statbuf) != 0)
1419                         continue;
1420                 if ((statbuf.st_mode & S_IRUSR) == 0)
1421                         continue;
1422
1423                 udev_list_entry_add(&udev_device->sysattr_list, dent->d_name, NULL);
1424                 num++;
1425         }
1426
1427         closedir(dir);
1428         udev_device->sysattr_list_read = true;
1429
1430         return num;
1431 }
1432
1433 /**
1434  * udev_device_get_sysattr_list_entry:
1435  * @udev_device: udev device
1436  *
1437  * Retrieve the list of available sysattrs, with value being empty;
1438  * This just return all available sysfs attributes for a particular
1439  * device without reading their values.
1440  *
1441  * Returns: the first entry of the property list
1442  **/
1443 _public_ struct udev_list_entry *udev_device_get_sysattr_list_entry(struct udev_device *udev_device)
1444 {
1445         if (!udev_device->sysattr_list_read) {
1446                 int ret;
1447                 ret = udev_device_sysattr_list_read(udev_device);
1448                 if (0 > ret)
1449                         return NULL;
1450         }
1451
1452         return udev_list_get_entry(&udev_device->sysattr_list);
1453 }
1454
1455 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
1456 {
1457         const char *pos;
1458         size_t len;
1459
1460         free(udev_device->syspath);
1461         udev_device->syspath = strdup(syspath);
1462         if (udev_device->syspath ==  NULL)
1463                 return -ENOMEM;
1464         udev_device->devpath = udev_device->syspath + strlen("/sys");
1465         udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath);
1466
1467         pos = strrchr(udev_device->syspath, '/');
1468         if (pos == NULL)
1469                 return -EINVAL;
1470         udev_device->sysname = strdup(&pos[1]);
1471         if (udev_device->sysname == NULL)
1472                 return -ENOMEM;
1473
1474         /* some devices have '!' in their name, change that to '/' */
1475         len = 0;
1476         while (udev_device->sysname[len] != '\0') {
1477                 if (udev_device->sysname[len] == '!')
1478                         udev_device->sysname[len] = '/';
1479                 len++;
1480         }
1481
1482         /* trailing number */
1483         while (len > 0 && isdigit(udev_device->sysname[--len]))
1484                 udev_device->sysnum = &udev_device->sysname[len];
1485
1486         /* sysname is completely numeric */
1487         if (len == 0)
1488                 udev_device->sysnum = NULL;
1489
1490         return 0;
1491 }
1492
1493 int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
1494 {
1495         free(udev_device->devnode);
1496         if (devnode[0] != '/') {
1497                 if (asprintf(&udev_device->devnode, "/dev/%s", devnode) < 0)
1498                         udev_device->devnode = NULL;
1499         } else {
1500                 udev_device->devnode = strdup(devnode);
1501         }
1502         if (udev_device->devnode == NULL)
1503                 return -ENOMEM;
1504         udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);
1505         return 0;
1506 }
1507
1508 int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink)
1509 {
1510         struct udev_list_entry *list_entry;
1511
1512         udev_device->devlinks_uptodate = false;
1513         list_entry = udev_list_entry_add(&udev_device->devlinks_list, devlink, NULL);
1514         if (list_entry == NULL)
1515                 return -ENOMEM;
1516         return 0;
1517 }
1518
1519 const char *udev_device_get_id_filename(struct udev_device *udev_device)
1520 {
1521         if (udev_device->id_filename == NULL) {
1522                 if (udev_device_get_subsystem(udev_device) == NULL)
1523                         return NULL;
1524
1525                 if (major(udev_device_get_devnum(udev_device)) > 0) {
1526                         /* use dev_t -- b259:131072, c254:0 */
1527                         if (asprintf(&udev_device->id_filename, "%c%u:%u",
1528                                      streq(udev_device_get_subsystem(udev_device), "block") ? 'b' : 'c',
1529                                      major(udev_device_get_devnum(udev_device)),
1530                                      minor(udev_device_get_devnum(udev_device))) < 0)
1531                                 udev_device->id_filename = NULL;
1532                 } else if (udev_device_get_ifindex(udev_device) > 0) {
1533                         /* use netdev ifindex -- n3 */
1534                         if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0)
1535                                 udev_device->id_filename = NULL;
1536                 } else {
1537                         /*
1538                          * use $subsys:$syname -- pci:0000:00:1f.2
1539                          * sysname() has '!' translated, get it from devpath
1540                          */
1541                         const char *sysname;
1542                         sysname = strrchr(udev_device->devpath, '/');
1543                         if (sysname == NULL)
1544                                 return NULL;
1545                         sysname = &sysname[1];
1546                         if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
1547                                 udev_device->id_filename = NULL;
1548                 }
1549         }
1550         return udev_device->id_filename;
1551 }
1552
1553 /**
1554  * udev_device_get_is_initialized:
1555  * @udev_device: udev device
1556  *
1557  * Check if udev has already handled the device and has set up
1558  * device node permissions and context, or has renamed a network
1559  * device.
1560  *
1561  * This is only implemented for devices with a device node
1562  * or network interfaces. All other devices return 1 here.
1563  *
1564  * Returns: 1 if the device is set up. 0 otherwise.
1565  **/
1566 _public_ int udev_device_get_is_initialized(struct udev_device *udev_device)
1567 {
1568         if (!udev_device->info_loaded)
1569                 udev_device_read_db(udev_device, NULL);
1570         return udev_device->is_initialized;
1571 }
1572
1573 void udev_device_set_is_initialized(struct udev_device *udev_device)
1574 {
1575         udev_device->is_initialized = true;
1576 }
1577
1578 int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
1579 {
1580         if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
1581                 return -EINVAL;
1582         udev_device->tags_uptodate = false;
1583         if (udev_list_entry_add(&udev_device->tags_list, tag, NULL) != NULL)
1584                 return 0;
1585         return -ENOMEM;
1586 }
1587
1588 void udev_device_cleanup_tags_list(struct udev_device *udev_device)
1589 {
1590         udev_device->tags_uptodate = false;
1591         udev_list_cleanup(&udev_device->tags_list);
1592 }
1593
1594 /**
1595  * udev_device_get_tags_list_entry:
1596  * @udev_device: udev device
1597  *
1598  * Retrieve the list of tags attached to the udev device. The next
1599  * list entry can be retrieved with udev_list_entry_get_next(),
1600  * which returns #NULL if no more entries exist. The tag string
1601  * can be retrieved from the list entry by udev_list_entry_get_name().
1602  *
1603  * Returns: the first entry of the tag list
1604  **/
1605 _public_ struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
1606 {
1607         if (udev_device == NULL)
1608                 return NULL;
1609         if (!udev_device->info_loaded)
1610                 udev_device_read_db(udev_device, NULL);
1611         return udev_list_get_entry(&udev_device->tags_list);
1612 }
1613
1614 /**
1615  * udev_device_has_tag:
1616  * @udev_device: udev device
1617  * @tag: tag name
1618  *
1619  * Check if a given device has a certain tag associated.
1620  *
1621  * Returns: 1 if the tag is found. 0 otherwise.
1622  **/
1623 _public_ int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
1624 {
1625         struct udev_list_entry *list_entry;
1626
1627         if (udev_device == NULL)
1628                 return false;
1629         if (!udev_device->info_loaded)
1630                 udev_device_read_db(udev_device, NULL);
1631         list_entry = udev_device_get_tags_list_entry(udev_device);
1632         if (udev_list_entry_get_by_name(list_entry, tag) != NULL)
1633                 return true;
1634         return false;
1635 }
1636
1637 #define ENVP_SIZE                        128
1638 #define MONITOR_BUF_SIZE                4096
1639 static int update_envp_monitor_buf(struct udev_device *udev_device)
1640 {
1641         struct udev_list_entry *list_entry;
1642         char *s;
1643         size_t l;
1644         unsigned int i;
1645
1646         /* monitor buffer of property strings */
1647         free(udev_device->monitor_buf);
1648         udev_device->monitor_buf_len = 0;
1649         udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE);
1650         if (udev_device->monitor_buf == NULL)
1651                 return -ENOMEM;
1652
1653         /* envp array, strings will point into monitor buffer */
1654         if (udev_device->envp == NULL)
1655                 udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE);
1656         if (udev_device->envp == NULL)
1657                 return -ENOMEM;
1658
1659         i = 0;
1660         s = udev_device->monitor_buf;
1661         l = MONITOR_BUF_SIZE;
1662         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
1663                 const char *key;
1664
1665                 key = udev_list_entry_get_name(list_entry);
1666                 /* skip private variables */
1667                 if (key[0] == '.')
1668                         continue;
1669
1670                 /* add string to envp array */
1671                 udev_device->envp[i++] = s;
1672                 if (i+1 >= ENVP_SIZE)
1673                         return -EINVAL;
1674
1675                 /* add property string to monitor buffer */
1676                 l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
1677                 if (l == 0)
1678                         return -EINVAL;
1679                 /* advance past the trailing '\0' that util_strpcpyl() guarantees */
1680                 s++;
1681                 l--;
1682         }
1683         udev_device->envp[i] = NULL;
1684         udev_device->monitor_buf_len = s - udev_device->monitor_buf;
1685         udev_device->envp_uptodate = true;
1686         return 0;
1687 }
1688
1689 char **udev_device_get_properties_envp(struct udev_device *udev_device)
1690 {
1691         if (!udev_device->envp_uptodate)
1692                 if (update_envp_monitor_buf(udev_device) != 0)
1693                         return NULL;
1694         return udev_device->envp;
1695 }
1696
1697 ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf)
1698 {
1699         if (!udev_device->envp_uptodate)
1700                 if (update_envp_monitor_buf(udev_device) != 0)
1701                         return -EINVAL;
1702         *buf = udev_device->monitor_buf;
1703         return udev_device->monitor_buf_len;
1704 }
1705
1706 int udev_device_set_action(struct udev_device *udev_device, const char *action)
1707 {
1708         free(udev_device->action);
1709         udev_device->action = strdup(action);
1710         if (udev_device->action == NULL)
1711                 return -ENOMEM;
1712         udev_device_add_property(udev_device, "ACTION", udev_device->action);
1713         return 0;
1714 }
1715
1716 int udev_device_get_devlink_priority(struct udev_device *udev_device)
1717 {
1718         if (!udev_device->info_loaded)
1719                 udev_device_read_db(udev_device, NULL);
1720         return udev_device->devlink_priority;
1721 }
1722
1723 int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio)
1724 {
1725          udev_device->devlink_priority = prio;
1726         return 0;
1727 }
1728
1729 int udev_device_get_watch_handle(struct udev_device *udev_device)
1730 {
1731         if (!udev_device->info_loaded)
1732                 udev_device_read_db(udev_device, NULL);
1733         return udev_device->watch_handle;
1734 }
1735
1736 int udev_device_set_watch_handle(struct udev_device *udev_device, int handle)
1737 {
1738         udev_device->watch_handle = handle;
1739         return 0;
1740 }
1741
1742 bool udev_device_get_db_persist(struct udev_device *udev_device)
1743 {
1744         return udev_device->db_persist;
1745 }
1746
1747 void udev_device_set_db_persist(struct udev_device *udev_device)
1748 {
1749         udev_device->db_persist = true;
1750 }