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