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