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