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;
97 f = fopen(filename, "w");
99 err("unable to create db file '%s': %s", filename, strerror(errno));
102 dbg("storing data for device '%s' in '%s'", udev->dev->devpath, filename);
104 fprintf(f, "N:%s\n", udev->name);
105 list_for_each_entry(name_loop, &udev->symlink_list, node)
106 fprintf(f, "S:%s\n", name_loop->name);
107 fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt));
108 if (udev->partitions)
109 fprintf(f, "A:%u\n", udev->partitions);
110 if (udev->ignore_remove)
111 fprintf(f, "R:%u\n", udev->ignore_remove);
112 list_for_each_entry(name_loop, &udev->env_list, node)
113 fprintf(f, "E:%s\n", name_loop->name);
119 int udev_db_get_device(struct udevice *udev, const char *devpath)
122 char filename[PATH_SIZE];
123 char line[PATH_SIZE];
124 unsigned int maj, min;
131 strlcpy(udev->dev->devpath, devpath, sizeof(udev->dev->devpath));
132 devpath_to_db_path(devpath, filename, sizeof(filename));
134 if (lstat(filename, &stats) != 0) {
135 info("no db file to read %s: %s", filename, strerror(errno));
138 if ((stats.st_mode & S_IFMT) == S_IFLNK) {
139 char target[NAME_SIZE];
142 info("found a symlink as db file");
143 target_len = readlink(filename, target, sizeof(target));
145 target[target_len] = '\0';
147 info("error reading db link %s: %s", filename, strerror(errno));
150 dbg("db link points to '%s'", target);
151 strlcpy(udev->name, target, sizeof(udev->name));
155 if (file_map(filename, &buf, &bufsize) != 0) {
156 info("error reading db file %s: %s", filename, strerror(errno));
161 while (cur < bufsize) {
162 count = buf_get_line(buf, bufsize, cur);
168 if (count > sizeof(udev->name))
169 count = sizeof(udev->name);
170 memcpy(udev->name, &bufline[2], count-2);
171 udev->name[count-2] = '\0';
174 if (count > sizeof(line))
175 count = sizeof(line);
176 memcpy(line, &bufline[2], count-2);
177 line[count-2] = '\0';
178 sscanf(line, "%u:%u", &maj, &min);
179 udev->devt = makedev(maj, min);
182 if (count > sizeof(line))
183 count = sizeof(line);
184 memcpy(line, &bufline[2], count-2);
185 line[count-2] = '\0';
186 name_list_add(&udev->symlink_list, line, 0);
189 if (count > sizeof(line))
190 count = sizeof(line);
191 memcpy(line, &bufline[2], count-2);
192 line[count-2] = '\0';
193 udev->partitions = atoi(line);
196 if (count > sizeof(line))
197 count = sizeof(line);
198 memcpy(line, &bufline[2], count-2);
199 line[count-2] = '\0';
200 udev->ignore_remove = atoi(line);
203 if (count > sizeof(line))
204 count = sizeof(line);
205 memcpy(line, &bufline[2], count-2);
206 line[count-2] = '\0';
207 name_list_add(&udev->env_list, line, 0);
211 file_unmap(buf, bufsize);
213 if (udev->name[0] == '\0')
219 int udev_db_delete_device(struct udevice *udev)
221 char filename[PATH_SIZE];
223 devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename));
229 int udev_db_lookup_name(const char *name, char *devpath, size_t len)
231 char dbpath[PATH_MAX];
235 strlcpy(dbpath, udev_root, sizeof(dbpath));
236 strlcat(dbpath, "/"DB_DIR, sizeof(dbpath));
237 dir = opendir(dbpath);
239 info("no udev_db available '%s': %s", dbpath, strerror(errno));
245 char filename[PATH_SIZE];
246 char nodename[PATH_SIZE];
255 if (ent == NULL || ent->d_name[0] == '\0')
257 if (ent->d_name[0] == '.')
260 snprintf(filename, sizeof(filename), "%s/%s", dbpath, ent->d_name);
261 filename[sizeof(filename)-1] = '\0';
262 dbg("looking at '%s'", filename);
264 if (lstat(filename, &stats) != 0) {
265 info("unable to read %s: %s", filename, strerror(errno));
268 if ((stats.st_mode & S_IFMT) == S_IFLNK) {
269 char target[NAME_SIZE];
272 info("found a symlink as db file");
273 target_len = readlink(filename, target, sizeof(target));
275 target[target_len] = '\0';
277 info("error reading db link %s: %s", filename, strerror(errno));
280 dbg("db link points to '%s'", target);
281 if (strcmp(name, target) == 0) {
282 db_file_to_devpath(ent->d_name, devpath, len);
288 if (file_map(filename, &buf, &bufsize) != 0) {
289 info("unable to read db file '%s': %s", filename, strerror(errno));
294 while (cur < bufsize && !found) {
295 count = buf_get_line(buf, bufsize, cur);
302 if (count > sizeof(nodename))
303 count = sizeof(nodename);
304 memcpy(nodename, &bufline[2], count-2);
305 nodename[count-2] = '\0';
306 dbg("compare '%s' '%s'", nodename, name);
307 if (strcmp(nodename, name) == 0) {
308 db_file_to_devpath(ent->d_name, devpath, len);
316 file_unmap(buf, bufsize);
326 int udev_db_get_all_entries(struct list_head *name_list)
328 char dbpath[PATH_MAX];
331 strlcpy(dbpath, udev_root, sizeof(dbpath));
332 strlcat(dbpath, "/"DB_DIR, sizeof(dbpath));
333 dir = opendir(dbpath);
335 info("no udev_db available '%s': %s", dbpath, strerror(errno));
341 char filename[PATH_SIZE] = "/";
345 if (ent == NULL || ent->d_name[0] == '\0')
347 if (ent->d_name[0] == '.')
350 end = strlcat(filename, ent->d_name, sizeof(filename));
351 for (i = 1; i < end; i++)
352 if (filename[i] == PATH_TO_NAME_CHAR)
354 name_list_add(name_list, filename, 1);
355 dbg("added '%s'", filename);