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