6 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
7 * Copyright (C) 2004-2005 Kay Sievers <kay.sievers@vrfy.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 675 Mass Ave, Cambridge, MA 02139, USA.
34 #include "libsysfs/sysfs/libsysfs.h"
36 #include "udev_utils.h"
40 #define PATH_TO_NAME_CHAR '@'
42 static int get_db_filename(const char *devpath, char *filename, int len)
44 char temp[SYSFS_PATH_MAX];
47 /* replace '/' to transform path into a filename */
48 strfieldcpy(temp, devpath);
49 pos = strchr(&temp[1], '/');
51 pos[0] = PATH_TO_NAME_CHAR;
52 pos = strchr(&pos[1], '/');
54 snprintf(filename, len, "%s%s", udev_db_path, temp);
55 filename[len-1] = '\0';
60 int udev_db_add_device(struct udevice *udev)
62 char filename[SYSFS_PATH_MAX];
63 struct name_entry *name_loop;
69 get_db_filename(udev->devpath, filename, SYSFS_PATH_MAX);
71 create_path(filename);
73 f = fopen(filename, "w");
75 dbg("unable to create db file '%s'", filename);
78 dbg("storing data for device '%s' in '%s'", udev->devpath, filename);
80 fprintf(f, "P:%s\n", udev->devpath);
81 fprintf(f, "N:%s\n", udev->name);
82 list_for_each_entry(name_loop, &udev->symlink_list, node)
83 fprintf(f, "S:%s\n", name_loop->name);
84 fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt));
85 fprintf(f, "A:%u\n", udev->partitions);
86 fprintf(f, "R:%u\n", udev->ignore_remove);
93 static int parse_db_file(struct udevice *udev, const char *filename)
97 unsigned int major, minor;
104 if (file_map(filename, &buf, &bufsize) != 0) {
105 dbg("unable to read db file '%s'", filename);
110 while (cur < bufsize) {
111 count = buf_get_line(buf, bufsize, cur);
117 if (count > DEVPATH_SIZE)
118 count = DEVPATH_SIZE-1;
119 strncpy(udev->devpath, &bufline[2], count-2);
120 udev->devpath[count-2] = '\0';
123 if (count > NAME_SIZE)
125 strncpy(udev->name, &bufline[2], count-2);
126 udev->name[count-2] = '\0';
129 if (count > NAME_SIZE)
131 strncpy(temp, &bufline[2], count-2);
132 temp[count-2] = '\0';
133 sscanf(temp, "%u:%u", &major, &minor);
134 udev->devt = makedev(major, minor);
137 if (count > NAME_SIZE)
139 strncpy(temp, &bufline[2], count-2);
140 temp[count-2] = '\0';
141 name_list_add(&udev->symlink_list, temp, 0);
144 if (count > NAME_SIZE)
146 strncpy(line, &bufline[2], count-2);
147 line[count-2] = '\0';
148 udev->partitions = atoi(line);
151 if (count > NAME_SIZE)
153 strncpy(line, &bufline[2], count-2);
154 line[count-2] = '\0';
155 udev->ignore_remove = atoi(line);
159 file_unmap(buf, bufsize);
161 if (udev->name[0] == '\0')
167 int udev_db_delete_device(struct udevice *udev)
169 char filename[SYSFS_PATH_MAX];
171 get_db_filename(udev->devpath, filename, SYSFS_PATH_MAX);
177 int udev_db_get_device(struct udevice *udev, const char *devpath)
179 char filename[SYSFS_PATH_MAX];
181 get_db_filename(devpath, filename, SYSFS_PATH_MAX);
183 if (parse_db_file(udev, filename) != 0)
189 int udev_db_search_name(char *devpath, size_t len, const char *name)
193 char filename[NAME_SIZE];
195 dir = opendir(udev_db_path);
197 dbg("unable to udev db '%s'", udev_db_path);
202 char path[DEVPATH_SIZE];
203 char nodename[NAME_SIZE];
211 if (ent == NULL || ent->d_name[0] == '\0')
214 if (ent->d_name[0] == '.')
217 snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name);
218 filename[NAME_SIZE-1] = '\0';
219 dbg("looking at '%s'", filename);
221 if (file_map(filename, &buf, &bufsize) != 0) {
222 dbg("unable to read db file '%s'", filename);
227 while (cur < bufsize) {
228 count = buf_get_line(buf, bufsize, cur);
234 if (count > DEVPATH_SIZE)
235 count = DEVPATH_SIZE-1;
236 strncpy(path, &bufline[2], count-2);
237 path[count-2] = '\0';
241 if (count > NAME_SIZE)
243 strncpy(nodename, &bufline[2], count-2);
244 nodename[count-2] = '\0';
245 dbg("compare '%s' '%s'", nodename, name);
246 if (strcmp(nodename, name) == 0) {
247 strncpy(devpath, path, len);
249 file_unmap(buf, bufsize);
258 file_unmap(buf, bufsize);
265 int udev_db_call_foreach(int (*handler_function)(struct udevice *udev))
269 char filename[NAME_SIZE];
270 struct udevice db_udev;
272 dir = opendir(udev_db_path);
274 dbg("unable to udev db '%s'", udev_db_path);
280 if (ent == NULL || ent->d_name[0] == '\0')
283 if (ent->d_name[0] == '.')
286 snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name);
287 filename[NAME_SIZE-1] = '\0';
289 dbg("found '%s'", filename);
291 udev_init_device(&db_udev, NULL, NULL);
292 if (parse_db_file(&db_udev, filename) == 0) {
293 if (handler_function(&db_udev) != 0)