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