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