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