chiark / gitweb /
udevd: switch to common id_filename functions
[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 struct udev_device *udev_device_new_from_id_filename(struct udev *udev, char *id)
479 {
480         char type;
481         int maj, min;
482         char subsys[UTIL_PATH_SIZE];
483         char *sysname;
484
485         switch(id[0]) {
486         case 'b':
487         case 'c':
488                 if (sscanf(id, "%c%i:%i", &type, &maj, &min) != 3)
489                         return NULL;
490                 return udev_device_new_from_devnum(udev, type, makedev(maj, min));
491         case '+':
492                 util_strscpy(subsys, sizeof(subsys), &id[1]);
493                 sysname = strchr(subsys, ':');
494                 if (sysname == NULL)
495                         return NULL;
496                 sysname[0] = '\0';
497                 sysname = &sysname[1];
498                 return udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
499         default:
500                 return NULL;
501         }
502 }
503
504 /**
505  * udev_device_new_from_subsystem_sysname:
506  * @udev: udev library context
507  * @subsystem: the subsystem of the device
508  * @sysname: the name of the device
509  *
510  * Create new udev device, and fill in information from the sys device
511  * and the udev database entry. The device is looked up by the subsystem
512  * and name string of the device, like "mem" / "zero", or "block" / "sda".
513  *
514  * The initial refcount is 1, and needs to be decremented to
515  * release the resources of the udev device.
516  *
517  * Returns: a new udev device, or #NULL, if it does not exist
518  **/
519 struct udev_device *udev_device_new_from_subsystem_sysname(struct udev *udev, const char *subsystem, const char *sysname)
520 {
521         char path_full[UTIL_PATH_SIZE];
522         char *path;
523         size_t l;
524         struct stat statbuf;
525
526         path = path_full;
527         l = util_strpcpyl(&path, sizeof(path_full), udev_get_sys_path(udev), NULL);
528
529         if (strcmp(subsystem, "subsystem") == 0) {
530                 util_strscpyl(path, l, "/subsystem/", sysname, NULL);
531                 if (stat(path_full, &statbuf) == 0)
532                         goto found;
533
534                 util_strscpyl(path, l, "/bus/", sysname, NULL);
535                 if (stat(path_full, &statbuf) == 0)
536                         goto found;
537
538                 util_strscpyl(path, l, "/class/", sysname, NULL);
539                 if (stat(path_full, &statbuf) == 0)
540                         goto found;
541                 goto out;
542         }
543
544         if (strcmp(subsystem, "module") == 0) {
545                 util_strscpyl(path, l, "/module/", sysname, NULL);
546                 if (stat(path_full, &statbuf) == 0)
547                         goto found;
548                 goto out;
549         }
550
551         if (strcmp(subsystem, "drivers") == 0) {
552                 char subsys[UTIL_NAME_SIZE];
553                 char *driver;
554
555                 util_strscpy(subsys, sizeof(subsys), sysname);
556                 driver = strchr(subsys, ':');
557                 if (driver != NULL) {
558                         driver[0] = '\0';
559                         driver = &driver[1];
560
561                         util_strscpyl(path, l, "/subsystem/", subsys, "/drivers/", driver, NULL);
562                         if (stat(path_full, &statbuf) == 0)
563                                 goto found;
564
565                         util_strscpyl(path, l, "/bus/", subsys, "/drivers/", driver, NULL);
566                         if (stat(path_full, &statbuf) == 0)
567                                 goto found;
568                 }
569                 goto out;
570         }
571
572         util_strscpyl(path, l, "/subsystem/", subsystem, "/devices/", sysname, NULL);
573         if (stat(path_full, &statbuf) == 0)
574                 goto found;
575
576         util_strscpyl(path, l, "/bus/", subsystem, "/devices/", sysname, NULL);
577         if (stat(path_full, &statbuf) == 0)
578                 goto found;
579
580         util_strscpyl(path, l, "/class/", subsystem, "/", sysname, NULL);
581         if (stat(path_full, &statbuf) == 0)
582                 goto found;
583 out:
584         return NULL;
585 found:
586         return udev_device_new_from_syspath(udev, path_full);
587 }
588
589 /**
590  * udev_device_new_from_environment
591  * @udev: udev library context
592  *
593  * Create new udev device, and fill in information from the
594  * current process environment. This only works reliable if
595  * the process is called from a udev rule. It is usually used
596  * for tools executed from IMPORT= rules.
597  *
598  * The initial refcount is 1, and needs to be decremented to
599  * release the resources of the udev device.
600  *
601  * Returns: a new udev device, or #NULL, if it does not exist
602  **/
603 struct udev_device *udev_device_new_from_environment(struct udev *udev)
604 {
605         int i;
606         struct udev_device *udev_device;
607
608         udev_device = udev_device_new(udev);
609         if (udev_device == NULL)
610                 return NULL;
611         udev_device_set_info_loaded(udev_device);
612
613         for (i = 0; environ[i] != NULL; i++)
614                 udev_device_add_property_from_string_parse(udev_device, environ[i]);
615
616         if (udev_device_add_property_from_string_parse_finish(udev_device) < 0) {
617                 info(udev, "missing values, invalid device\n");
618                 udev_device_unref(udev_device);
619                 udev_device = NULL;
620         }
621
622         return udev_device;
623 }
624
625 static struct udev_device *device_new_from_parent(struct udev_device *udev_device)
626 {
627         struct udev_device *udev_device_parent = NULL;
628         char path[UTIL_PATH_SIZE];
629         const char *subdir;
630
631         util_strscpy(path, sizeof(path), udev_device->syspath);
632         subdir = &path[strlen(udev_get_sys_path(udev_device->udev))+1];
633         for (;;) {
634                 char *pos;
635
636                 pos = strrchr(subdir, '/');
637                 if (pos == NULL || pos < &subdir[2])
638                         break;
639                 pos[0] = '\0';
640                 udev_device_parent = udev_device_new_from_syspath(udev_device->udev, path);
641                 if (udev_device_parent != NULL)
642                         return udev_device_parent;
643         }
644         return NULL;
645 }
646
647 /**
648  * udev_device_get_parent:
649  * @udev_device: the device to start searching from
650  *
651  * Find the next parent device, and fill in information from the sys
652  * device and the udev database entry.
653  *
654  * The returned the device is not referenced. It is attached to the
655  * child device, and will be cleaned up when the child device
656  * is cleaned up.
657  *
658  * It is not necessarily just the upper level directory, empty or not
659  * recognized sys directories are ignored.
660  *
661  * It can be called as many times as needed, without caring about
662  * references.
663  *
664  * Returns: a new udev device, or #NULL, if it no parent exist.
665  **/
666 struct udev_device *udev_device_get_parent(struct udev_device *udev_device)
667 {
668         if (udev_device == NULL)
669                 return NULL;
670         if (!udev_device->parent_set) {
671                 udev_device->parent_set = true;
672                 udev_device->parent_device = device_new_from_parent(udev_device);
673         }
674         if (udev_device->parent_device != NULL)
675                 dbg(udev_device->udev, "returning existing parent %p\n", udev_device->parent_device);
676         return udev_device->parent_device;
677 }
678
679 /**
680  * udev_device_get_parent_with_subsystem_devtype:
681  * @udev_device: udev device to start searching from
682  * @subsystem: the subsystem of the device
683  * @devtype: the type (DEVTYPE) of the device
684  *
685  * Find the next parent device, with a matching subsystem and devtype
686  * value, and fill in information from the sys device and the udev
687  * database entry.
688  *
689  * If devtype is #NULL, only subsystem is checked, and any devtype will
690  * match.
691  *
692  * The returned the device is not referenced. It is attached to the
693  * child device, and will be cleaned up when the child device
694  * is cleaned up.
695  *
696  * It can be called as many times as needed, without caring about
697  * references.
698  *
699  * Returns: a new udev device, or #NULL if no matching parent exists.
700  **/
701 struct udev_device *udev_device_get_parent_with_subsystem_devtype(struct udev_device *udev_device, const char *subsystem, const char *devtype)
702 {
703         struct udev_device *parent;
704
705         if (subsystem == NULL)
706                 return NULL;
707
708         parent = udev_device_get_parent(udev_device);
709         while (parent != NULL) {
710                 const char *parent_subsystem;
711                 const char *parent_devtype;
712
713                 parent_subsystem = udev_device_get_subsystem(parent);
714                 if (parent_subsystem != NULL && strcmp(parent_subsystem, subsystem) == 0) {
715                         if (devtype == NULL)
716                                 break;
717                         parent_devtype = udev_device_get_devtype(parent);
718                         if (parent_devtype != NULL && strcmp(parent_devtype, devtype) == 0)
719                                 break;
720                 }
721                 parent = udev_device_get_parent(parent);
722         }
723         return parent;
724 }
725
726 /**
727  * udev_device_get_udev:
728  * @udev_device: udev device
729  *
730  * Retrieve the udev library context the device was created with.
731  *
732  * Returns: the udev library context
733  **/
734 struct udev *udev_device_get_udev(struct udev_device *udev_device)
735 {
736         if (udev_device == NULL)
737                 return NULL;
738         return udev_device->udev;
739 }
740
741 /**
742  * udev_device_ref:
743  * @udev_device: udev device
744  *
745  * Take a reference of a udev device.
746  *
747  * Returns: the passed udev device
748  **/
749 struct udev_device *udev_device_ref(struct udev_device *udev_device)
750 {
751         if (udev_device == NULL)
752                 return NULL;
753         udev_device->refcount++;
754         return udev_device;
755 }
756
757 /**
758  * udev_device_unref:
759  * @udev_device: udev device
760  *
761  * Drop a reference of a udev device. If the refcount reaches zero,
762  * the resources of the device will be released.
763  *
764  **/
765 void udev_device_unref(struct udev_device *udev_device)
766 {
767         if (udev_device == NULL)
768                 return;
769         udev_device->refcount--;
770         if (udev_device->refcount > 0)
771                 return;
772         if (udev_device->parent_device != NULL)
773                 udev_device_unref(udev_device->parent_device);
774         free(udev_device->syspath);
775         free(udev_device->sysname);
776         free(udev_device->devnode);
777         free(udev_device->subsystem);
778         free(udev_device->devtype);
779         udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
780         udev_list_cleanup_entries(udev_device->udev, &udev_device->properties_list);
781         udev_list_cleanup_entries(udev_device->udev, &udev_device->sysattr_list);
782         udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
783         free(udev_device->action);
784         free(udev_device->driver);
785         free(udev_device->devpath_old);
786         free(udev_device->sysname_old);
787         free(udev_device->knodename);
788         free(udev_device->id_filename);
789         free(udev_device->envp);
790         free(udev_device->monitor_buf);
791         dbg(udev_device->udev, "udev_device: %p released\n", udev_device);
792         free(udev_device);
793 }
794
795 /**
796  * udev_device_get_devpath:
797  * @udev_device: udev device
798  *
799  * Retrieve the kernel devpath value of the udev device. The path
800  * does not contain the sys mount point, and starts with a '/'.
801  *
802  * Returns: the devpath of the udev device
803  **/
804 const char *udev_device_get_devpath(struct udev_device *udev_device)
805 {
806         if (udev_device == NULL)
807                 return NULL;
808         return udev_device->devpath;
809 }
810
811 /**
812  * udev_device_get_syspath:
813  * @udev_device: udev device
814  *
815  * Retrieve the sys path of the udev device. The path is an
816  * absolute path and starts with the sys mount point.
817  *
818  * Returns: the sys path of the udev device
819  **/
820 const char *udev_device_get_syspath(struct udev_device *udev_device)
821 {
822         if (udev_device == NULL)
823                 return NULL;
824         return udev_device->syspath;
825 }
826
827 /**
828  * udev_device_get_sysname:
829  * @udev_device: udev device
830  *
831  * Returns: the sys name of the device device
832  **/
833 const char *udev_device_get_sysname(struct udev_device *udev_device)
834 {
835         if (udev_device == NULL)
836                 return NULL;
837         return udev_device->sysname;
838 }
839
840 /**
841  * udev_device_get_sysnum:
842  * @udev_device: udev device
843  *
844  * Returns: the trailing number of of the device name
845  **/
846 const char *udev_device_get_sysnum(struct udev_device *udev_device)
847 {
848         if (udev_device == NULL)
849                 return NULL;
850         return udev_device->sysnum;
851 }
852
853 /**
854  * udev_device_get_devnode:
855  * @udev_device: udev device
856  *
857  * Retrieve the device node file name belonging to the udev device.
858  * The path is an absolute path, and starts with the device directory.
859  *
860  * Returns: the device node file name of the udev device, or #NULL if no device node exists
861  **/
862 const char *udev_device_get_devnode(struct udev_device *udev_device)
863 {
864         if (udev_device == NULL)
865                 return NULL;
866         if (!udev_device->info_loaded) {
867                 udev_device_read_uevent_file(udev_device);
868                 udev_device_read_db(udev_device);
869         }
870
871         /* we might get called before we handled an event and have a db, use the kernel-provided name */
872         if (udev_device->devnode == NULL && udev_device_get_knodename(udev_device) != NULL) {
873                 char filename[UTIL_NAME_SIZE];
874
875                 util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev_device->udev), "/",
876                               udev_device_get_knodename(udev_device), NULL);
877                 udev_device_set_devnode(udev_device, filename);
878                 return udev_device->devnode;
879         }
880
881         return udev_device->devnode;
882 }
883
884 /**
885  * udev_device_get_subsystem:
886  * @udev_device: udev device
887  *
888  * Retrieve the subsystem string of the udev device. The string does not
889  * contain any "/".
890  *
891  * Returns: the subsystem name of the udev device, or #NULL if it can not be determined
892  **/
893 const char *udev_device_get_subsystem(struct udev_device *udev_device)
894 {
895         char subsystem[UTIL_NAME_SIZE];
896
897         if (udev_device == NULL)
898                 return NULL;
899         if (!udev_device->subsystem_set) {
900                 udev_device->subsystem_set = true;
901                 /* read "subsystem" link */
902                 if (util_get_sys_subsystem(udev_device->udev, udev_device->syspath, subsystem, sizeof(subsystem)) > 0) {
903                         udev_device_set_subsystem(udev_device, subsystem);
904                         return udev_device->subsystem;
905                 }
906                 /* implicit names */
907                 if (strncmp(udev_device->devpath, "/module/", 8) == 0) {
908                         udev_device_set_subsystem(udev_device, "module");
909                         return udev_device->subsystem;
910                 }
911                 if (strstr(udev_device->devpath, "/drivers/") != NULL) {
912                         udev_device_set_subsystem(udev_device, "drivers");
913                         return udev_device->subsystem;
914                 }
915                 if (strncmp(udev_device->devpath, "/subsystem/", 11) == 0 ||
916                     strncmp(udev_device->devpath, "/class/", 7) == 0 ||
917                     strncmp(udev_device->devpath, "/bus/", 5) == 0) {
918                         udev_device_set_subsystem(udev_device, "subsystem");
919                         return udev_device->subsystem;
920                 }
921         }
922         return udev_device->subsystem;
923 }
924
925 /**
926  * udev_device_get_devtype:
927  * @udev_device: udev device
928  *
929  * Retrieve the devtype string of the udev device.
930  *
931  * Returns: the devtype name of the udev device, or #NULL if it can not be determined
932  **/
933 const char *udev_device_get_devtype(struct udev_device *udev_device)
934 {
935         if (udev_device == NULL)
936                 return NULL;
937         if (!udev_device->devtype_set) {
938                 udev_device->devtype_set = true;
939                 udev_device_read_uevent_file(udev_device);
940         }
941         return udev_device->devtype;
942 }
943
944 /**
945  * udev_device_get_devlinks_list_entry:
946  * @udev_device: udev device
947  *
948  * Retrieve the list of device links pointing to the device file of
949  * the udev device. The next list entry can be retrieved with
950  * udev_list_entry_next(), which returns #NULL if no more entries exist.
951  * The devlink path can be retrieved from the list entry by
952  * udev_list_entry_get_name(). The path is an absolute path, and starts with
953  * the device directory.
954  *
955  * Returns: the first entry of the device node link list
956  **/
957 struct udev_list_entry *udev_device_get_devlinks_list_entry(struct udev_device *udev_device)
958 {
959         if (udev_device == NULL)
960                 return NULL;
961         if (!udev_device->info_loaded)
962                 udev_device_read_db(udev_device);
963         return udev_list_get_entry(&udev_device->devlinks_list);
964 }
965
966 void udev_device_cleanup_devlinks_list(struct udev_device *udev_device)
967 {
968         udev_device->devlinks_uptodate = false;
969         udev_list_cleanup_entries(udev_device->udev, &udev_device->devlinks_list);
970 }
971
972 /**
973  * udev_device_get_properties_list_entry:
974  * @udev_device: udev device
975  *
976  * Retrieve the list of key/value device properties of the udev
977  * device. The next list entry can be retrieved with udev_list_entry_next(),
978  * which returns #NULL if no more entries exist. The property name
979  * can be retrieved from the list entry by udev_list_get_name(),
980  * the property value by udev_list_get_value().
981  *
982  * Returns: the first entry of the property list
983  **/
984 struct udev_list_entry *udev_device_get_properties_list_entry(struct udev_device *udev_device)
985 {
986         if (udev_device == NULL)
987                 return NULL;
988         if (!udev_device->info_loaded) {
989                 udev_device_read_uevent_file(udev_device);
990                 udev_device_read_db(udev_device);
991         }
992         if (!udev_device->devlinks_uptodate) {
993                 char symlinks[UTIL_PATH_SIZE];
994                 struct udev_list_entry *list_entry;
995
996                 udev_device->devlinks_uptodate = true;
997                 list_entry = udev_device_get_devlinks_list_entry(udev_device);
998                 if (list_entry != NULL) {
999                         char *s;
1000                         size_t l;
1001
1002                         s = symlinks;
1003                         l = util_strpcpyl(&s, sizeof(symlinks), udev_list_entry_get_name(list_entry), NULL);
1004                         udev_list_entry_foreach(list_entry, udev_list_entry_get_next(list_entry))
1005                                 l = util_strpcpyl(&s, l, " ", udev_list_entry_get_name(list_entry), NULL);
1006                         udev_device_add_property(udev_device, "DEVLINKS", symlinks);
1007                 }
1008         }
1009         if (!udev_device->tags_uptodate) {
1010                 udev_device->tags_uptodate = true;
1011                 if (udev_device_get_tags_list_entry(udev_device) != NULL) {
1012                         char tags[UTIL_PATH_SIZE];
1013                         struct udev_list_entry *list_entry;
1014                         char *s;
1015                         size_t l;
1016
1017                         s = tags;
1018                         l = util_strpcpyl(&s, sizeof(tags), ":", NULL);
1019                         udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(udev_device))
1020                                 l = util_strpcpyl(&s, l, udev_list_entry_get_name(list_entry), ":", NULL);
1021                         udev_device_add_property(udev_device, "TAGS", tags);
1022                 }
1023         }
1024         return udev_list_get_entry(&udev_device->properties_list);
1025 }
1026
1027 /**
1028  * udev_device_get_driver:
1029  * @udev_device: udev device
1030  *
1031  * Returns: the driver string, or #NULL if there is no driver attached.
1032  **/
1033 const char *udev_device_get_driver(struct udev_device *udev_device)
1034 {
1035         char driver[UTIL_NAME_SIZE];
1036
1037         if (udev_device == NULL)
1038                 return NULL;
1039         if (!udev_device->driver_set) {
1040                 udev_device->driver_set = true;
1041                 if (util_get_sys_driver(udev_device->udev, udev_device->syspath, driver, sizeof(driver)) > 0)
1042                         udev_device->driver = strdup(driver);
1043         }
1044         return udev_device->driver;
1045 }
1046
1047 /**
1048  * udev_device_get_devnum:
1049  * @udev_device: udev device
1050  *
1051  * Returns: the device major/minor number.
1052  **/
1053 dev_t udev_device_get_devnum(struct udev_device *udev_device)
1054 {
1055         if (udev_device == NULL)
1056                 return makedev(0, 0);
1057         if (!udev_device->info_loaded)
1058                 udev_device_read_uevent_file(udev_device);
1059         return udev_device->devnum;
1060 }
1061
1062 /**
1063  * udev_device_get_action:
1064  * @udev_device: udev device
1065  *
1066  * This is only valid if the device was received through a monitor. Devices read from
1067  * sys do not have an action string. Usual actions are: add, remove, change, online,
1068  * offline.
1069  *
1070  * Returns: the kernel action value, or #NULL if there is no action value available.
1071  **/
1072 const char *udev_device_get_action(struct udev_device *udev_device)
1073 {
1074         if (udev_device == NULL)
1075                 return NULL;
1076         return udev_device->action;
1077 }
1078
1079 /**
1080  * udev_device_get_devnum:
1081  * @udev_device: udev device
1082  *
1083  * This is only valid if the device was received through a monitor. Devices read from
1084  * sys do not have a sequence number.
1085  *
1086  * Returns: the kernel event sequence number, or 0 if there is no sequence number available.
1087  **/
1088 unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device)
1089 {
1090         if (udev_device == NULL)
1091                 return 0;
1092         return udev_device->seqnum;
1093 }
1094
1095 /**
1096  * udev_device_get_sysattr_value:
1097  * @udev_device: udev device
1098  * @sysattr: attribute name
1099  *
1100  * The retrieved value is cached in the device. Repeated calls will return the same
1101  * value and not open the attribute again.
1102  *
1103  * Returns: the content of a sys attribute file, or #NULL if there is no sys attribute value.
1104  **/
1105 const char *udev_device_get_sysattr_value(struct udev_device *udev_device, const char *sysattr)
1106 {
1107         struct udev_list_entry *list_entry;
1108         char path[UTIL_PATH_SIZE];
1109         char value[4096];
1110         struct stat statbuf;
1111         int fd;
1112         ssize_t size;
1113         const char *val = NULL;
1114
1115         if (udev_device == NULL)
1116                 return NULL;
1117         if (sysattr == NULL)
1118                 return NULL;
1119
1120         /* look for possibly already cached result */
1121         udev_list_entry_foreach(list_entry, udev_list_get_entry(&udev_device->sysattr_list)) {
1122                 if (strcmp(udev_list_entry_get_name(list_entry), sysattr) == 0) {
1123                         dbg(udev_device->udev, "got '%s' (%s) from cache\n",
1124                             sysattr, udev_list_entry_get_value(list_entry));
1125                         return udev_list_entry_get_value(list_entry);
1126                 }
1127         }
1128
1129         util_strscpyl(path, sizeof(path), udev_device_get_syspath(udev_device), "/", sysattr, NULL);
1130         if (lstat(path, &statbuf) != 0) {
1131                 dbg(udev_device->udev, "no attribute '%s', keep negative entry\n", path);
1132                 udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, NULL, 0, 0);
1133                 goto out;
1134         }
1135
1136         if (S_ISLNK(statbuf.st_mode)) {
1137                 char target[UTIL_NAME_SIZE];
1138                 int len;
1139                 char *pos;
1140
1141                 /* some core links return the last element of the target path */
1142                 if (strcmp(sysattr, "driver") != 0 &&
1143                     strcmp(sysattr, "subsystem") != 0 &&
1144                     strcmp(sysattr, "module") != 0)
1145                         goto out;
1146
1147                 len = readlink(path, target, sizeof(target));
1148                 if (len <= 0 || len == sizeof(target))
1149                         goto out;
1150                 target[len] = '\0';
1151
1152                 pos = strrchr(target, '/');
1153                 if (pos != NULL) {
1154                         pos = &pos[1];
1155                         dbg(udev_device->udev, "cache '%s' with link value '%s'\n", sysattr, pos);
1156                         list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, pos, 0, 0);
1157                         val = udev_list_entry_get_value(list_entry);
1158                 }
1159
1160                 goto out;
1161         }
1162
1163         /* skip directories */
1164         if (S_ISDIR(statbuf.st_mode))
1165                 goto out;
1166
1167         /* skip non-readable files */
1168         if ((statbuf.st_mode & S_IRUSR) == 0)
1169                 goto out;
1170
1171         /* read attribute value */
1172         fd = open(path, O_RDONLY|O_CLOEXEC);
1173         if (fd < 0) {
1174                 dbg(udev_device->udev, "attribute '%s' can not be opened\n", path);
1175                 goto out;
1176         }
1177         size = read(fd, value, sizeof(value));
1178         close(fd);
1179         if (size < 0)
1180                 goto out;
1181         if (size == sizeof(value))
1182                 goto out;
1183
1184         /* got a valid value, store it in cache and return it */
1185         value[size] = '\0';
1186         util_remove_trailing_chars(value, '\n');
1187         dbg(udev_device->udev, "'%s' has attribute value '%s'\n", path, value);
1188         list_entry = udev_list_entry_add(udev_device->udev, &udev_device->sysattr_list, sysattr, value, 0, 0);
1189         val = udev_list_entry_get_value(list_entry);
1190 out:
1191         return val;
1192 }
1193
1194 int udev_device_set_syspath(struct udev_device *udev_device, const char *syspath)
1195 {
1196         const char *pos;
1197         size_t len;
1198
1199         free(udev_device->syspath);
1200         udev_device->syspath = strdup(syspath);
1201         if (udev_device->syspath ==  NULL)
1202                 return -ENOMEM;
1203         udev_device->devpath = &udev_device->syspath[strlen(udev_get_sys_path(udev_device->udev))];
1204         udev_device_add_property(udev_device, "DEVPATH", udev_device->devpath);
1205
1206         pos = strrchr(udev_device->syspath, '/');
1207         if (pos == NULL)
1208                 return -EINVAL;
1209         udev_device->sysname = strdup(&pos[1]);
1210         if (udev_device->sysname == NULL)
1211                 return -ENOMEM;
1212
1213         /* some devices have '!' in their name, change that to '/' */
1214         len = 0;
1215         while (udev_device->sysname[len] != '\0') {
1216                 if (udev_device->sysname[len] == '!')
1217                         udev_device->sysname[len] = '/';
1218                 len++;
1219         }
1220
1221         /* trailing number */
1222         while (len > 0 && isdigit(udev_device->sysname[--len]))
1223                 udev_device->sysnum = &udev_device->sysname[len];
1224
1225         /* sysname is completely numeric */
1226         if (len == 0)
1227                 udev_device->sysnum = NULL;
1228
1229         return 0;
1230 }
1231
1232 int udev_device_set_subsystem(struct udev_device *udev_device, const char *subsystem)
1233 {
1234         free(udev_device->subsystem);
1235         udev_device->subsystem = strdup(subsystem);
1236         if (udev_device->subsystem == NULL)
1237                 return -ENOMEM;
1238         udev_device->subsystem_set = true;
1239         udev_device_add_property(udev_device, "SUBSYSTEM", udev_device->subsystem);
1240         return 0;
1241 }
1242
1243 int udev_device_set_devtype(struct udev_device *udev_device, const char *devtype)
1244 {
1245         free(udev_device->devtype);
1246         udev_device->devtype = strdup(devtype);
1247         if (udev_device->devtype == NULL)
1248                 return -ENOMEM;
1249         udev_device->devtype_set = true;
1250         udev_device_add_property(udev_device, "DEVTYPE", udev_device->devtype);
1251         return 0;
1252 }
1253
1254 int udev_device_set_devnode(struct udev_device *udev_device, const char *devnode)
1255 {
1256         free(udev_device->devnode);
1257         udev_device->devnode = strdup(devnode);
1258         if (udev_device->devnode == NULL)
1259                 return -ENOMEM;
1260         udev_device_add_property(udev_device, "DEVNAME", udev_device->devnode);
1261         return 0;
1262 }
1263
1264 int udev_device_add_devlink(struct udev_device *udev_device, const char *devlink, int unique)
1265 {
1266         struct udev_list_entry *list_entry;
1267
1268         udev_device->devlinks_uptodate = false;
1269         list_entry = udev_list_entry_add(udev_device->udev, &udev_device->devlinks_list, devlink, NULL, 1, 0);
1270         if (list_entry == NULL)
1271                 return -ENOMEM;
1272         if (unique)
1273                 udev_list_entry_set_flags(list_entry, 1);
1274         return 0;
1275 }
1276
1277 const char *udev_device_get_id_filename(struct udev_device *udev_device)
1278 {
1279         if (udev_device->id_filename == NULL) {
1280                 if (udev_device_get_subsystem(udev_device) == NULL)
1281                         return NULL;
1282
1283                 if (major(udev_device_get_devnum(udev_device)) > 0) {
1284                         /* use dev_t -- b259:131072, c254:0 */
1285                         if (asprintf(&udev_device->id_filename, "%c%u:%u",
1286                                      strcmp(udev_device_get_subsystem(udev_device), "block") == 0 ? 'b' : 'c',
1287                                      major(udev_device_get_devnum(udev_device)),
1288                                      minor(udev_device_get_devnum(udev_device))) < 0)
1289                                 udev_device->id_filename = NULL;
1290                 } else if (strcmp(udev_device_get_subsystem(udev_device), "net") == 0) {
1291                         /* use netdev ifindex -- n3 */
1292                         if (asprintf(&udev_device->id_filename, "n%u", udev_device_get_ifindex(udev_device)) < 0)
1293                                 udev_device->id_filename = NULL;
1294                 } else {
1295                         /*
1296                          * use $subsys:$syname -- pci:0000:00:1f.2
1297                          * sysname() has '!' translated, get it from devpath
1298                          */
1299                         const char *sysname;
1300                         sysname = strrchr(udev_device->devpath, '/');
1301                         if (sysname == NULL)
1302                                 return NULL;
1303                         sysname = &sysname[1];
1304                         if (asprintf(&udev_device->id_filename, "+%s:%s", udev_device_get_subsystem(udev_device), sysname) < 0)
1305                                 udev_device->id_filename = NULL;
1306                 }
1307         }
1308         return udev_device->id_filename;
1309 }
1310
1311 int udev_device_add_tag(struct udev_device *udev_device, const char *tag)
1312 {
1313         if (strchr(tag, ':') != NULL || strchr(tag, ' ') != NULL)
1314                 return -EINVAL;
1315         udev_device->tags_uptodate = false;
1316         if (udev_list_entry_add(udev_device->udev, &udev_device->tags_list, tag, NULL, 1, 0) != NULL)
1317                 return 0;
1318         return -ENOMEM;
1319 }
1320
1321 void udev_device_cleanup_tags_list(struct udev_device *udev_device)
1322 {
1323         udev_device->tags_uptodate = false;
1324         udev_list_cleanup_entries(udev_device->udev, &udev_device->tags_list);
1325 }
1326
1327 /**
1328  * udev_device_get_tags_list_entry:
1329  * @udev_device: udev device
1330  *
1331  * Retrieve the list of tags attached to the udev device. The next
1332  * list entry can be retrieved with udev_list_entry_next(),
1333  * which returns #NULL if no more entries exist. The tag string
1334  * can be retrieved from the list entry by udev_list_get_name().
1335  *
1336  * Returns: the first entry of the tag list
1337  **/
1338 struct udev_list_entry *udev_device_get_tags_list_entry(struct udev_device *udev_device)
1339 {
1340         if (udev_device == NULL)
1341                 return NULL;
1342         return udev_list_get_entry(&udev_device->tags_list);
1343 }
1344
1345 int udev_device_has_tag(struct udev_device *udev_device, const char *tag)
1346 {
1347         struct udev_list_entry *list_entry;
1348
1349         if (!udev_device->info_loaded)
1350                 udev_device_read_db(udev_device);
1351         list_entry = udev_device_get_tags_list_entry(udev_device);
1352         list_entry =  udev_list_entry_get_by_name(list_entry, tag);
1353         if (list_entry != NULL)
1354                 return 1;
1355         return 0;
1356 }
1357
1358 #define ENVP_SIZE                       128
1359 #define MONITOR_BUF_SIZE                4096
1360 static int update_envp_monitor_buf(struct udev_device *udev_device)
1361 {
1362         struct udev_list_entry *list_entry;
1363         char *s;
1364         size_t l;
1365         unsigned int i;
1366
1367         /* monitor buffer of property strings */
1368         free(udev_device->monitor_buf);
1369         udev_device->monitor_buf_len = 0;
1370         udev_device->monitor_buf = malloc(MONITOR_BUF_SIZE);
1371         if (udev_device->monitor_buf == NULL)
1372                 return -ENOMEM;
1373
1374         /* envp array, strings will point into monitor buffer */
1375         if (udev_device->envp == NULL)
1376                 udev_device->envp = malloc(sizeof(char *) * ENVP_SIZE);
1377         if (udev_device->envp == NULL)
1378                 return -ENOMEM;
1379
1380         i = 0;
1381         s = udev_device->monitor_buf;
1382         l = MONITOR_BUF_SIZE;
1383         udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(udev_device)) {
1384                 const char *key;
1385
1386                 key = udev_list_entry_get_name(list_entry);
1387                 /* skip private variables */
1388                 if (key[0] == '.')
1389                         continue;
1390
1391                 /* add string to envp array */
1392                 udev_device->envp[i++] = s;
1393                 if (i+1 >= ENVP_SIZE)
1394                         return -EINVAL;
1395
1396                 /* add property string to monitor buffer */
1397                 l = util_strpcpyl(&s, l, key, "=", udev_list_entry_get_value(list_entry), NULL);
1398                 if (l == 0)
1399                         return -EINVAL;
1400                 /* advance past the trailing '\0' that util_strpcpyl() guarantees */
1401                 s++;
1402                 l--;
1403         }
1404         udev_device->envp[i] = NULL;
1405         udev_device->monitor_buf_len = s - udev_device->monitor_buf;
1406         udev_device->envp_uptodate = true;
1407         dbg(udev_device->udev, "filled envp/monitor buffer, %u properties, %zu bytes\n",
1408             i, udev_device->monitor_buf_len);
1409         return 0;
1410 }
1411
1412 char **udev_device_get_properties_envp(struct udev_device *udev_device)
1413 {
1414         if (!udev_device->envp_uptodate)
1415                 if (update_envp_monitor_buf(udev_device) != 0)
1416                         return NULL;
1417         return udev_device->envp;
1418 }
1419
1420 ssize_t udev_device_get_properties_monitor_buf(struct udev_device *udev_device, const char **buf)
1421 {
1422         if (!udev_device->envp_uptodate)
1423                 if (update_envp_monitor_buf(udev_device) != 0)
1424                         return -EINVAL;
1425         *buf = udev_device->monitor_buf;
1426         return udev_device->monitor_buf_len;
1427 }
1428
1429 int udev_device_set_action(struct udev_device *udev_device, const char *action)
1430 {
1431         free(udev_device->action);
1432         udev_device->action = strdup(action);
1433         if (udev_device->action == NULL)
1434                 return -ENOMEM;
1435         udev_device_add_property(udev_device, "ACTION", udev_device->action);
1436         return 0;
1437 }
1438
1439 int udev_device_set_driver(struct udev_device *udev_device, const char *driver)
1440 {
1441         free(udev_device->driver);
1442         udev_device->driver = strdup(driver);
1443         if (udev_device->driver == NULL)
1444                 return -ENOMEM;
1445         udev_device->driver_set = true;
1446         udev_device_add_property(udev_device, "DRIVER", udev_device->driver);
1447         return 0;
1448 }
1449
1450 const char *udev_device_get_devpath_old(struct udev_device *udev_device)
1451 {
1452         return udev_device->devpath_old;
1453 }
1454
1455 int udev_device_set_devpath_old(struct udev_device *udev_device, const char *devpath_old)
1456 {
1457         const char *pos;
1458         size_t len;
1459
1460         free(udev_device->devpath_old);
1461         udev_device->devpath_old = strdup(devpath_old);
1462         if (udev_device->devpath_old == NULL)
1463                 return -ENOMEM;
1464         udev_device_add_property(udev_device, "DEVPATH_OLD", udev_device->devpath_old);
1465
1466         pos = strrchr(udev_device->devpath_old, '/');
1467         if (pos == NULL)
1468                 return -EINVAL;
1469         udev_device->sysname_old = strdup(&pos[1]);
1470         if (udev_device->sysname_old == NULL)
1471                 return -ENOMEM;
1472
1473         /* some devices have '!' in their name, change that to '/' */
1474         len = 0;
1475         while (udev_device->sysname_old[len] != '\0') {
1476                 if (udev_device->sysname_old[len] == '!')
1477                         udev_device->sysname_old[len] = '/';
1478                 len++;
1479         }
1480         return 0;
1481 }
1482
1483 const char *udev_device_get_sysname_old(struct udev_device *udev_device)
1484 {
1485         if (udev_device == NULL)
1486                 return NULL;
1487         return udev_device->sysname_old;
1488 }
1489
1490 const char *udev_device_get_knodename(struct udev_device *udev_device)
1491 {
1492         return udev_device->knodename;
1493 }
1494
1495 int udev_device_set_knodename(struct udev_device *udev_device, const char *knodename)
1496 {
1497         free(udev_device->knodename);
1498         udev_device->knodename = strdup(knodename);
1499         if (udev_device->knodename == NULL)
1500                 return -ENOMEM;
1501         /* do not overwrite the udev property with the kernel property */
1502         if (udev_device->devnode == NULL)
1503                 udev_device_add_property(udev_device, "DEVNAME", udev_device->knodename);
1504         return 0;
1505 }
1506
1507 int udev_device_get_timeout(struct udev_device *udev_device)
1508 {
1509         return udev_device->timeout;
1510 }
1511
1512 int udev_device_set_timeout(struct udev_device *udev_device, int timeout)
1513 {
1514         udev_device->timeout = timeout;
1515         return 0;
1516 }
1517 int udev_device_get_event_timeout(struct udev_device *udev_device)
1518 {
1519         if (!udev_device->info_loaded)
1520                 udev_device_read_db(udev_device);
1521         return udev_device->event_timeout;
1522 }
1523
1524 int udev_device_set_event_timeout(struct udev_device *udev_device, int event_timeout)
1525 {
1526         char num[32];
1527
1528         udev_device->event_timeout = event_timeout;
1529         snprintf(num, sizeof(num), "%u", event_timeout);
1530         udev_device_add_property(udev_device, "TIMEOUT", num);
1531         return 0;
1532 }
1533
1534 int udev_device_set_seqnum(struct udev_device *udev_device, unsigned long long int seqnum)
1535 {
1536         char num[32];
1537
1538         udev_device->seqnum = seqnum;
1539         snprintf(num, sizeof(num), "%llu", seqnum);
1540         udev_device_add_property(udev_device, "SEQNUM", num);
1541         return 0;
1542 }
1543
1544 int udev_device_set_devnum(struct udev_device *udev_device, dev_t devnum)
1545 {
1546         char num[32];
1547
1548         udev_device->devnum = devnum;
1549
1550         snprintf(num, sizeof(num), "%u", major(devnum));
1551         udev_device_add_property(udev_device, "MAJOR", num);
1552         snprintf(num, sizeof(num), "%u", minor(devnum));
1553         udev_device_add_property(udev_device, "MINOR", num);
1554         return 0;
1555 }
1556
1557 int udev_device_get_devlink_priority(struct udev_device *udev_device)
1558 {
1559         if (!udev_device->info_loaded)
1560                 udev_device_read_db(udev_device);
1561         return udev_device->devlink_priority;
1562 }
1563
1564 int udev_device_set_devlink_priority(struct udev_device *udev_device, int prio)
1565 {
1566          udev_device->devlink_priority = prio;
1567         return 0;
1568 }
1569
1570 int udev_device_get_watch_handle(struct udev_device *udev_device)
1571 {
1572         if (!udev_device->info_loaded)
1573                 udev_device_read_db(udev_device);
1574         return udev_device->watch_handle;
1575 }
1576
1577 int udev_device_set_watch_handle(struct udev_device *udev_device, int handle)
1578 {
1579         udev_device->watch_handle = handle;
1580         return 0;
1581 }
1582
1583 int udev_device_get_ifindex(struct udev_device *udev_device)
1584 {
1585         return udev_device->ifindex;
1586 }
1587
1588 int udev_device_set_ifindex(struct udev_device *udev_device, int ifindex)
1589 {
1590         char num[32];
1591
1592         udev_device->ifindex = ifindex;
1593         snprintf(num, sizeof(num), "%u", ifindex);
1594         udev_device_add_property(udev_device, "IFINDEX", num);
1595         return 0;
1596 }