2 * libudev - interface to udev device information
4 * Copyright (C) 2003-2009 Kay Sievers <kay.sievers@vrfy.org>
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.
22 #include <sys/param.h>
25 #include "libudev-private.h"
27 static int create_path(struct udev *udev, const char *path, bool selinux)
29 char p[UTIL_PATH_SIZE];
34 util_strscpy(p, sizeof(p), path);
35 pos = strrchr(p, '/');
38 while (pos != p && pos[-1] == '/')
44 dbg(udev, "stat '%s'\n", p);
45 if (stat(p, &stats) == 0) {
46 if ((stats.st_mode & S_IFMT) == S_IFDIR)
52 err = util_create_path(udev, p);
56 dbg(udev, "mkdir '%s'\n", p);
58 udev_selinux_setfscreatecon(udev, p, S_IFDIR|0755);
62 if (err == -EEXIST && stat(p, &stats) == 0) {
63 if ((stats.st_mode & S_IFMT) == S_IFDIR)
70 udev_selinux_resetfscreatecon(udev);
74 int util_create_path(struct udev *udev, const char *path)
76 return create_path(udev, path, false);
79 int util_create_path_selinux(struct udev *udev, const char *path)
81 return create_path(udev, path, true);
84 int util_delete_path(struct udev *udev, const char *path)
86 char p[UTIL_PATH_SIZE];
93 util_strscpy(p, sizeof(p), path);
94 pos = strrchr(p, '/');
95 if (pos == p || pos == NULL)
100 pos = strrchr(p, '/');
102 /* don't remove the last one */
103 if ((pos == p) || (pos == NULL))
116 /* Reset permissions on the device node, before unlinking it to make sure,
117 * that permissions of possible hard links will be removed too.
119 int util_unlink_secure(struct udev *udev, const char *filename)
123 chown(filename, 0, 0);
124 chmod(filename, 0000);
125 err = unlink(filename);
129 err(udev, "unlink(%s) failed: %m\n", filename);
133 uid_t util_lookup_user(struct udev *udev, const char *user)
136 size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
142 if (strcmp(user, "root") == 0)
144 uid = strtoul(user, &endptr, 10);
145 if (endptr[0] == '\0')
148 errno = getpwnam_r(user, &pwbuf, buf, buflen, &pw);
151 if (errno == 0 || errno == ENOENT || errno == ESRCH)
152 err(udev, "specified user '%s' unknown\n", user);
154 err(udev, "error resolving user '%s': %m\n", user);
158 gid_t util_lookup_group(struct udev *udev, const char *group)
161 size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
167 if (strcmp(group, "root") == 0)
169 gid = strtoul(group, &endptr, 10);
170 if (endptr[0] == '\0')
177 newbuf = realloc(buf, buflen);
181 errno = getgrnam_r(group, &grbuf, buf, buflen, &gr);
184 } else if (errno == ERANGE) {
187 } else if (errno == 0 || errno == ENOENT || errno == ESRCH) {
188 err(udev, "specified group '%s' unknown\n", group);
190 err(udev, "error resolving group '%s': %m\n", group);
198 /* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
199 int util_resolve_subsys_kernel(struct udev *udev, const char *string,
200 char *result, size_t maxsize, int read_value)
202 char temp[UTIL_PATH_SIZE];
205 struct udev_device *dev;
208 if (string[0] != '[')
211 util_strscpy(temp, sizeof(temp), string);
215 sysname = strchr(subsys, '/');
219 sysname = &sysname[1];
221 attr = strchr(sysname, ']');
231 if (read_value && attr == NULL)
234 dev = udev_device_new_from_subsystem_sysname(udev, subsys, sysname);
241 val = udev_device_get_sysattr_value(dev, attr);
243 util_strscpy(result, maxsize, val);
246 info(udev, "value '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result);
252 l = util_strpcpyl(&s, maxsize, udev_device_get_syspath(dev), NULL);
254 util_strpcpyl(&s, l, "/", attr, NULL);
255 info(udev, "path '[%s/%s]%s' is '%s'\n", subsys, sysname, attr, result);
257 udev_device_unref(dev);