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