2 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
3 * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation version 2 of the License.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 #include <sys/types.h>
36 static int devpath_to_db_path(const char *devpath, char *filename, size_t len)
40 /* add location of db files */
41 strlcpy(filename, udev_root, len);
42 start = strlcat(filename, "/"DB_DIR, len);
43 end = strlcat(filename, devpath, len);
47 /* replace '/' to transform path into a filename */
48 for (i = start+1; i < end; i++)
49 if (filename[i] == '/')
50 filename[i] = PATH_TO_NAME_CHAR;
55 static int db_file_to_devpath(const char *filename, char *devpath, size_t len)
59 strlcpy(devpath, "/", len);
60 end = strlcat(devpath, filename, len);
62 /* replace PATH_TO_NAME_CHAR to transform name into devpath */
63 for (i = 1; i < end; i++)
64 if (devpath[i] == PATH_TO_NAME_CHAR)
70 int udev_db_add_device(struct udevice *udev)
72 char filename[PATH_SIZE];
77 devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
78 create_path(filename);
81 * create only a symlink with the name as the target
82 * if we don't have any interesting data to remember
84 if (list_empty(&udev->symlink_list) && list_empty(&udev->env_list) &&
85 !udev->partitions && !udev->ignore_remove) {
86 dbg("nothing interesting to store, create symlink");
88 if (symlink(udev->name, filename) != 0) {
89 err("unable to create db link '%s': %s", filename, strerror(errno));
93 struct name_entry *name_loop;
96 f = fopen(filename, "w");
98 err("unable to create db file '%s': %s", filename, strerror(errno));
101 dbg("storing data for device '%s' in '%s'", udev->dev->devpath, filename);
103 fprintf(f, "N:%s\n", udev->name);
104 list_for_each_entry(name_loop, &udev->symlink_list, node)
105 fprintf(f, "S:%s\n", name_loop->name);
106 fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt));
107 if (udev->partitions)
108 fprintf(f, "A:%u\n", udev->partitions);
109 if (udev->ignore_remove)
110 fprintf(f, "R:%u\n", udev->ignore_remove);
111 list_for_each_entry(name_loop, &udev->env_list, node)
112 fprintf(f, "E:%s\n", name_loop->name);
118 int udev_db_get_device(struct udevice *udev, const char *devpath)
121 char filename[PATH_SIZE];
122 char line[PATH_SIZE];
123 unsigned int maj, min;
130 strlcpy(udev->dev->devpath, devpath, sizeof(udev->dev->devpath));
131 devpath_to_db_path(devpath, filename, sizeof(filename));
133 if (lstat(filename, &stats) != 0) {
134 info("no db file to read %s: %s", filename, strerror(errno));
137 if ((stats.st_mode & S_IFMT) == S_IFLNK) {
138 char target[NAME_SIZE];
141 info("found a symlink as db file");
142 target_len = readlink(filename, target, sizeof(target));
144 target[target_len] = '\0';
146 info("error reading db link %s: %s", filename, strerror(errno));
149 dbg("db link points to '%s'", target);
150 strlcpy(udev->name, target, sizeof(udev->name));
154 if (file_map(filename, &buf, &bufsize) != 0) {
155 info("error reading db file %s: %s", filename, strerror(errno));
160 while (cur < bufsize) {
161 count = buf_get_line(buf, bufsize, cur);
167 if (count > sizeof(udev->name))
168 count = sizeof(udev->name);
169 memcpy(udev->name, &bufline[2], count-2);
170 udev->name[count-2] = '\0';
173 if (count > sizeof(line))
174 count = sizeof(line);
175 memcpy(line, &bufline[2], count-2);
176 line[count-2] = '\0';
177 sscanf(line, "%u:%u", &maj, &min);
178 udev->devt = makedev(maj, min);
181 if (count > sizeof(line))
182 count = sizeof(line);
183 memcpy(line, &bufline[2], count-2);
184 line[count-2] = '\0';
185 name_list_add(&udev->symlink_list, line, 0);
188 if (count > sizeof(line))
189 count = sizeof(line);
190 memcpy(line, &bufline[2], count-2);
191 line[count-2] = '\0';
192 udev->partitions = atoi(line);
195 if (count > sizeof(line))
196 count = sizeof(line);
197 memcpy(line, &bufline[2], count-2);
198 line[count-2] = '\0';
199 udev->ignore_remove = atoi(line);
202 if (count > sizeof(line))
203 count = sizeof(line);
204 memcpy(line, &bufline[2], count-2);
205 line[count-2] = '\0';
206 name_list_add(&udev->env_list, line, 0);
210 file_unmap(buf, bufsize);
212 if (udev->name[0] == '\0')
218 int udev_db_delete_device(struct udevice *udev)
220 char filename[PATH_SIZE];
222 devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
228 int udev_db_lookup_name(const char *name, char *devpath, size_t len)
230 char dbpath[PATH_MAX];
234 strlcpy(dbpath, udev_root, sizeof(dbpath));
235 strlcat(dbpath, "/"DB_DIR, sizeof(dbpath));
236 dir = opendir(dbpath);
238 info("no udev_db available '%s': %s", dbpath, strerror(errno));
244 char filename[PATH_SIZE];
245 char nodename[PATH_SIZE];
254 if (ent == NULL || ent->d_name[0] == '\0')
256 if (ent->d_name[0] == '.')
259 snprintf(filename, sizeof(filename), "%s/%s", dbpath, ent->d_name);
260 filename[sizeof(filename)-1] = '\0';
261 dbg("looking at '%s'", filename);
263 if (lstat(filename, &stats) != 0) {
264 info("unable to read %s: %s", filename, strerror(errno));
267 if ((stats.st_mode & S_IFMT) == S_IFLNK) {
268 char target[NAME_SIZE];
271 info("found a symlink as db file");
272 target_len = readlink(filename, target, sizeof(target));
274 target[target_len] = '\0';
276 info("error reading db link %s: %s", filename, strerror(errno));
279 dbg("db link points to '%s'", target);
280 if (strcmp(name, target) == 0) {
281 db_file_to_devpath(ent->d_name, devpath, len);
287 if (file_map(filename, &buf, &bufsize) != 0) {
288 info("unable to read db file '%s': %s", filename, strerror(errno));
293 while (cur < bufsize && !found) {
294 count = buf_get_line(buf, bufsize, cur);
301 if (count > sizeof(nodename))
302 count = sizeof(nodename);
303 memcpy(nodename, &bufline[2], count-2);
304 nodename[count-2] = '\0';
305 dbg("compare '%s' '%s'", nodename, name);
306 if (strcmp(nodename, name) == 0) {
307 db_file_to_devpath(ent->d_name, devpath, len);
315 file_unmap(buf, bufsize);
325 int udev_db_get_all_entries(struct list_head *name_list)
327 char dbpath[PATH_MAX];
330 strlcpy(dbpath, udev_root, sizeof(dbpath));
331 strlcat(dbpath, "/"DB_DIR, sizeof(dbpath));
332 dir = opendir(dbpath);
334 info("no udev_db available '%s': %s", dbpath, strerror(errno));
340 char filename[PATH_SIZE] = "/";
344 if (ent == NULL || ent->d_name[0] == '\0')
346 if (ent->d_name[0] == '.')
349 end = strlcat(filename, ent->d_name, sizeof(filename));
350 for (i = 1; i < end; i++)
351 if (filename[i] == PATH_TO_NAME_CHAR)
353 name_list_add(name_list, filename, 1);
354 dbg("added '%s'", filename);