6 * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
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.
35 #include "udev_version.h"
38 #define TYPE_LABEL "LABEL"
39 #define TYPE_NUMBER "NUMBER"
40 #define TYPE_TOPOLOGY "TOPOLOGY"
41 #define TYPE_REPLACE "REPLACE"
44 KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */
53 #define VALUE_SIZE 100
61 struct config_device {
62 struct list_head node;
64 enum config_type type;
67 char sysfs_file[FILE_SIZE];
68 char sysfs_value[VALUE_SIZE];
70 char place[PLACE_SIZE];
71 char kernel_name[NAME_SIZE];
73 /* what to set the device to */
76 char owner[OWNER_SIZE];
77 char group[GROUP_SIZE];
81 static LIST_HEAD(config_device_list);
83 #define copy_var(a, b, var) \
87 #define copy_string(a, b, var) \
89 strcpy(b->var, a->var);
91 static int add_dev(struct config_device *new_dev)
93 struct list_head *tmp;
94 struct config_device *tmp_dev;
96 /* loop through the whole list of devices to see if we already have
98 list_for_each(tmp, &config_device_list) {
99 struct config_device *dev = list_entry(tmp, struct config_device, node);
100 if (strcmp(dev->name, new_dev->name) == 0) {
101 /* the same, copy the new info into this structure */
102 copy_var(new_dev, dev, type);
103 copy_var(new_dev, dev, mode);
104 copy_string(new_dev, dev, bus);
105 copy_string(new_dev, dev, sysfs_file);
106 copy_string(new_dev, dev, sysfs_value);
107 copy_string(new_dev, dev, id);
108 copy_string(new_dev, dev, place);
109 copy_string(new_dev, dev, kernel_name);
110 copy_string(new_dev, dev, owner);
111 copy_string(new_dev, dev, group);
116 /* not found, lets create a new structure, and add it to the list */
117 tmp_dev = malloc(sizeof(*tmp_dev));
120 memcpy(tmp_dev, new_dev, sizeof(*tmp_dev));
121 list_add(&tmp_dev->node, &config_device_list);
125 static int get_value(const char *left, char **orig_string, char **ret_string)
128 char *string = *orig_string;
130 /* eat any whitespace */
131 while (isspace(*string))
134 /* split based on '=' */
135 temp = strsep(&string, "=");
136 if (strcasecmp(temp, left) == 0) {
137 /* got it, now strip off the '"' */
138 while (isspace(*string))
142 temp = strsep(&string, "\"");
144 *orig_string = string;
151 static int namedev_init_config(void)
160 struct config_device dev;
162 strcpy(filename, NAMEDEV_CONFIG_ROOT NAMEDEV_CONFIG_FILE);
163 dbg("opening %s to read as permissions config", filename);
164 fd = fopen(filename, "r");
166 dbg("Can't open %s", filename);
170 /* loop through the whole file */
173 temp = fgets(line, sizeof(line), fd);
177 dbg("read %s", temp);
179 /* eat the whitespace at the beginning of the line */
180 while (isspace(*temp))
187 /* see if this is a comment */
188 if (*temp == COMMENT_CHARACTER)
191 memset(&dev, 0x00, sizeof(dev));
194 temp2 = strsep(&temp, ",");
195 if (strcasecmp(temp2, TYPE_LABEL) == 0) {
200 retval = get_value("BUS", &temp, &temp3);
203 strcpy(dev.bus, temp3);
204 dbg("LABEL name = %s, bus = %s", dev.name, dev.bus);
207 if (strcasecmp(temp2, TYPE_NUMBER) == 0) {
212 retval = get_value("BUS", &temp, &temp3);
215 strcpy(dev.bus, temp3);
216 dbg("NUMBER name = %s, bus = %s", dev.name, dev.bus);
219 if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) {
224 retval = get_value("BUS", &temp, &temp3);
227 strcpy(dev.bus, temp3);
228 dbg("TOPOLOGY name = %s, bus = %s", dev.name, dev.bus);
231 if (strcasecmp(temp2, TYPE_REPLACE) == 0) {
235 /* KERNEL="kernel_name" */
236 retval = get_value("KERNEL", &temp, &temp3);
239 strcpy(dev.kernel_name, temp3);
241 /* NAME="new_name" */
242 temp2 = strsep(&temp, ",");
243 retval = get_value("NAME", &temp, &temp3);
246 strcpy(dev.name, temp3);
247 dbg("REPLACE name = %s, kernel_name = %s", dev.name, dev.kernel_name);
250 retval = add_dev(&dev);
252 dbg("add_dev returned with error %d", retval);
263 static int namedev_init_permissions(void)
271 struct config_device dev;
273 strcpy(filename, NAMEDEV_CONFIG_ROOT NAMEDEV_CONFIG_PERMISSION_FILE);
274 dbg("opening %s to read as permissions config", filename);
275 fd = fopen(filename, "r");
277 dbg("Can't open %s", filename);
281 /* loop through the whole file */
284 temp = fgets(line, sizeof(line), fd);
288 dbg("read %s", temp);
290 /* eat the whitespace at the beginning of the line */
291 while (isspace(*temp))
298 /* see if this is a comment */
299 if (*temp == COMMENT_CHARACTER)
302 memset(&dev, 0x00, sizeof(dev));
305 temp2 = strsep(&temp, ":");
306 strncpy(dev.name, temp2, sizeof(dev.name));
308 temp2 = strsep(&temp, ":");
309 strncpy(dev.owner, temp2, sizeof(dev.owner));
311 temp2 = strsep(&temp, ":");
312 strncpy(dev.group, temp2, sizeof(dev.owner));
314 dev.mode = strtol(temp, NULL, 8);
316 dbg("name = %s, owner = %s, group = %s, mode = %x", dev.name, dev.owner, dev.group, dev.mode);
317 retval = add_dev(&dev);
319 dbg("add_dev returned with error %d", retval);
331 int namedev_init(void)
335 retval = namedev_init_config();
339 retval = namedev_init_permissions();