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