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