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 size_t 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 strlcat(filename
, devpath
, len
);
44 return path_encode(&filename
[start
], len
- start
);
47 /* reverse mapping from the device file name to the devpath */
48 static int name_index(const char *devpath
, const char *name
, int add
)
50 char device
[PATH_SIZE
];
51 char filename
[PATH_SIZE
* 2];
55 /* directory with device name */
56 strlcpy(filename
, udev_root
, sizeof(filename
));
57 start
= strlcat(filename
, "/"DB_NAME_INDEX_DIR
"/", sizeof(filename
));
58 strlcat(filename
, name
, sizeof(filename
));
59 path_encode(&filename
[start
], sizeof(filename
) - start
);
60 /* entry with the devpath */
61 strlcpy(device
, devpath
, sizeof(device
));
62 path_encode(device
, sizeof(device
));
63 strlcat(filename
, "/", sizeof(filename
));
64 strlcat(filename
, device
, sizeof(filename
));
67 info("creating index: '%s'", filename
);
68 create_path(filename
);
69 fd
= open(filename
, O_WRONLY
|O_TRUNC
|O_CREAT
, 0644);
73 info("removing index: '%s'", filename
);
75 delete_path(filename
);
80 int udev_db_get_devices_by_name(const char *name
, struct list_head
*name_list
)
82 char dirname
[PATH_MAX
];
87 strlcpy(dirname
, udev_root
, sizeof(dirname
));
88 start
= strlcat(dirname
, "/"DB_NAME_INDEX_DIR
"/", sizeof(dirname
));
89 strlcat(dirname
, name
, sizeof(dirname
));
90 path_encode(&dirname
[start
], sizeof(dirname
) - start
);
92 dir
= opendir(dirname
);
94 info("no index directory '%s': %s", dirname
, strerror(errno
));
99 info("found index directory '%s'", dirname
);
102 char device
[PATH_SIZE
];
105 if (ent
== NULL
|| ent
->d_name
[0] == '\0')
107 if (ent
->d_name
[0] == '.')
110 strlcpy(device
, ent
->d_name
, sizeof(device
));
112 name_list_add(name_list
, device
, 0);
120 int udev_db_add_device(struct udevice
*udev
)
122 char filename
[PATH_SIZE
];
127 devpath_to_db_path(udev
->dev
->devpath
, filename
, sizeof(filename
));
128 create_path(filename
);
132 * don't waste tmpfs memory pages, if we don't have any data to store
133 * create fake db-file; store the node-name in a symlink target
135 if (list_empty(&udev
->symlink_list
) && list_empty(&udev
->env_list
) &&
136 !udev
->partitions
&& !udev
->ignore_remove
) {
137 dbg("nothing interesting to store, create symlink");
138 if (symlink(udev
->name
, filename
) != 0) {
139 err("unable to create db link '%s': %s", filename
, strerror(errno
));
144 struct name_entry
*name_loop
;
146 f
= fopen(filename
, "w");
148 err("unable to create db file '%s': %s", filename
, strerror(errno
));
151 dbg("storing data for device '%s' in '%s'", udev
->dev
->devpath
, filename
);
153 fprintf(f
, "N:%s\n", udev
->name
);
154 list_for_each_entry(name_loop
, &udev
->symlink_list
, node
) {
155 fprintf(f
, "S:%s\n", name_loop
->name
);
156 /* add symlink-name to index */
157 name_index(udev
->dev
->devpath
, name_loop
->name
, 1);
159 fprintf(f
, "M:%u:%u\n", major(udev
->devt
), minor(udev
->devt
));
160 if (udev
->link_priority
!= 0)
161 fprintf(f
, "L:%u\n", udev
->link_priority
);
162 if (udev
->partitions
!= 0)
163 fprintf(f
, "A:%u\n", udev
->partitions
);
164 if (udev
->ignore_remove
)
165 fprintf(f
, "R:%u\n", udev
->ignore_remove
);
166 list_for_each_entry(name_loop
, &udev
->env_list
, node
)
167 fprintf(f
, "E:%s\n", name_loop
->name
);
171 /* add name to index */
172 name_index(udev
->dev
->devpath
, udev
->name
, 1);
177 int udev_db_get_device(struct udevice
*udev
, const char *devpath
)
180 char filename
[PATH_SIZE
];
181 char line
[PATH_SIZE
];
182 unsigned int maj
, min
;
189 sysfs_device_set_values(udev
->dev
, devpath
, NULL
, NULL
);
190 devpath_to_db_path(devpath
, filename
, sizeof(filename
));
192 if (lstat(filename
, &stats
) != 0) {
193 info("no db file to read %s: %s", filename
, strerror(errno
));
196 if ((stats
.st_mode
& S_IFMT
) == S_IFLNK
) {
197 char target
[NAME_SIZE
];
200 info("found a symlink as db file");
201 target_len
= readlink(filename
, target
, sizeof(target
));
203 target
[target_len
] = '\0';
205 info("error reading db link %s: %s", filename
, strerror(errno
));
208 dbg("db link points to '%s'", target
);
209 strlcpy(udev
->name
, target
, sizeof(udev
->name
));
213 if (file_map(filename
, &buf
, &bufsize
) != 0) {
214 info("error reading db file %s: %s", filename
, strerror(errno
));
219 while (cur
< bufsize
) {
220 count
= buf_get_line(buf
, bufsize
, cur
);
226 if (count
> sizeof(udev
->name
))
227 count
= sizeof(udev
->name
);
228 memcpy(udev
->name
, &bufline
[2], count
-2);
229 udev
->name
[count
-2] = '\0';
232 if (count
> sizeof(line
))
233 count
= sizeof(line
);
234 memcpy(line
, &bufline
[2], count
-2);
235 line
[count
-2] = '\0';
236 sscanf(line
, "%u:%u", &maj
, &min
);
237 udev
->devt
= makedev(maj
, min
);
240 if (count
> sizeof(line
))
241 count
= sizeof(line
);
242 memcpy(line
, &bufline
[2], count
-2);
243 line
[count
-2] = '\0';
244 name_list_add(&udev
->symlink_list
, line
, 0);
247 if (count
> sizeof(line
))
248 count
= sizeof(line
);
249 memcpy(line
, &bufline
[2], count
-2);
250 line
[count
-2] = '\0';
251 udev
->link_priority
= atoi(line
);
254 if (count
> sizeof(line
))
255 count
= sizeof(line
);
256 memcpy(line
, &bufline
[2], count
-2);
257 line
[count
-2] = '\0';
258 udev
->partitions
= atoi(line
);
261 if (count
> sizeof(line
))
262 count
= sizeof(line
);
263 memcpy(line
, &bufline
[2], count
-2);
264 line
[count
-2] = '\0';
265 udev
->ignore_remove
= atoi(line
);
268 if (count
> sizeof(line
))
269 count
= sizeof(line
);
270 memcpy(line
, &bufline
[2], count
-2);
271 line
[count
-2] = '\0';
272 name_list_add(&udev
->env_list
, line
, 0);
276 file_unmap(buf
, bufsize
);
278 if (udev
->name
[0] == '\0')
284 int udev_db_delete_device(struct udevice
*udev
)
286 char filename
[PATH_SIZE
];
287 struct name_entry
*name_loop
;
292 devpath_to_db_path(udev
->dev
->devpath
, filename
, sizeof(filename
));
295 name_index(udev
->dev
->devpath
, udev
->name
, 0);
296 list_for_each_entry(name_loop
, &udev
->symlink_list
, node
)
297 name_index(udev
->dev
->devpath
, name_loop
->name
, 0);
302 int udev_db_get_all_entries(struct list_head
*name_list
)
304 char dbpath
[PATH_MAX
];
307 strlcpy(dbpath
, udev_root
, sizeof(dbpath
));
308 strlcat(dbpath
, "/"DB_DIR
, sizeof(dbpath
));
309 dir
= opendir(dbpath
);
311 info("no udev_db available '%s': %s", dbpath
, strerror(errno
));
317 char device
[PATH_SIZE
];
320 if (ent
== NULL
|| ent
->d_name
[0] == '\0')
322 if (ent
->d_name
[0] == '.')
325 strlcpy(device
, ent
->d_name
, sizeof(device
));
327 name_list_add(name_list
, device
, 1);
328 dbg("added '%s'", device
);