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