]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * udev_config.c | |
3 | * | |
4 | * Userspace devfs | |
5 | * | |
6 | * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com> | |
7 | * | |
8 | * | |
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. | |
12 | * | |
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. | |
17 | * | |
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. | |
21 | * | |
22 | */ | |
23 | ||
24 | /* define this to enable parsing debugging */ | |
25 | /* #define DEBUG_PARSER */ | |
26 | ||
27 | #include <stdlib.h> | |
28 | #include <string.h> | |
29 | #include <stdio.h> | |
30 | #include <fcntl.h> | |
31 | #include <unistd.h> | |
32 | #include <errno.h> | |
33 | #include <ctype.h> | |
34 | ||
35 | #include "libsysfs/sysfs/libsysfs.h" | |
36 | #include "udev.h" | |
37 | #include "udev_lib.h" | |
38 | #include "udev_version.h" | |
39 | #include "logging.h" | |
40 | #include "namedev.h" | |
41 | ||
42 | /* global variables */ | |
43 | char sysfs_path[SYSFS_PATH_MAX]; | |
44 | char udev_root[PATH_MAX]; | |
45 | char udev_db_filename[PATH_MAX+NAME_MAX]; | |
46 | char udev_permissions_filename[PATH_MAX+NAME_MAX]; | |
47 | char udev_rules_filename[PATH_MAX+NAME_MAX]; | |
48 | char udev_config_filename[PATH_MAX+NAME_MAX]; | |
49 | char default_mode_str[MODE_SIZE]; | |
50 | char default_owner_str[OWNER_SIZE]; | |
51 | char default_group_str[GROUP_SIZE]; | |
52 | int udev_log; | |
53 | int udev_dev_d; | |
54 | ||
55 | ||
56 | static int string_is_true(char *str) | |
57 | { | |
58 | if (strcasecmp(str, "true") == 0) | |
59 | return 1; | |
60 | if (strcasecmp(str, "yes") == 0) | |
61 | return 1; | |
62 | if (strcasecmp(str, "1") == 0) | |
63 | return 1; | |
64 | return 0; | |
65 | } | |
66 | ||
67 | static void init_variables(void) | |
68 | { | |
69 | char *env; | |
70 | ||
71 | /* fill up the defaults. | |
72 | * If any config values are specified, they will | |
73 | * override these values. */ | |
74 | strfieldcpy(udev_root, UDEV_ROOT); | |
75 | strfieldcpy(udev_db_filename, UDEV_DB); | |
76 | strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); | |
77 | strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); | |
78 | strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); | |
79 | udev_log = string_is_true(UDEV_LOG_DEFAULT); | |
80 | ||
81 | udev_dev_d = 1; | |
82 | env = getenv("UDEV_NO_DEVD"); | |
83 | if (env && string_is_true(env)) | |
84 | udev_dev_d = 0; | |
85 | } | |
86 | ||
87 | int parse_get_pair(char **orig_string, char **left, char **right) | |
88 | { | |
89 | char *temp; | |
90 | char *string = *orig_string; | |
91 | ||
92 | if (!string) | |
93 | return -ENODEV; | |
94 | ||
95 | /* eat any whitespace */ | |
96 | while (isspace(*string) || *string == ',') | |
97 | ++string; | |
98 | ||
99 | /* split based on '=' */ | |
100 | temp = strsep(&string, "="); | |
101 | *left = temp; | |
102 | if (!string) | |
103 | return -ENODEV; | |
104 | ||
105 | /* take the right side and strip off the '"' */ | |
106 | while (isspace(*string)) | |
107 | ++string; | |
108 | if (*string == '"') | |
109 | ++string; | |
110 | else | |
111 | return -ENODEV; | |
112 | ||
113 | temp = strsep(&string, "\""); | |
114 | if (!string || *temp == '\0') | |
115 | return -ENODEV; | |
116 | *right = temp; | |
117 | *orig_string = string; | |
118 | ||
119 | return 0; | |
120 | } | |
121 | ||
122 | static int parse_config_file(void) | |
123 | { | |
124 | char line[LINE_SIZE]; | |
125 | char *bufline; | |
126 | char *temp; | |
127 | char *variable; | |
128 | char *value; | |
129 | char *buf; | |
130 | size_t bufsize; | |
131 | size_t cur; | |
132 | size_t count; | |
133 | int lineno; | |
134 | int retval = 0; | |
135 | ||
136 | if (file_map(udev_config_filename, &buf, &bufsize) == 0) { | |
137 | dbg("reading '%s' as config file", udev_config_filename); | |
138 | } else { | |
139 | dbg("can't open '%s' as config file", udev_config_filename); | |
140 | return -ENODEV; | |
141 | } | |
142 | ||
143 | /* loop through the whole file */ | |
144 | lineno = 0; | |
145 | cur = 0; | |
146 | while (cur < bufsize) { | |
147 | count = buf_get_line(buf, bufsize, cur); | |
148 | bufline = &buf[cur]; | |
149 | cur += count+1; | |
150 | lineno++; | |
151 | ||
152 | if (count >= LINE_SIZE) { | |
153 | info("line too long, conf line skipped %s, line %d", | |
154 | udev_config_filename, lineno); | |
155 | continue; | |
156 | } | |
157 | ||
158 | /* eat the whitespace */ | |
159 | while ((count > 0) && isspace(bufline[0])) { | |
160 | bufline++; | |
161 | count--; | |
162 | } | |
163 | if (count == 0) | |
164 | continue; | |
165 | ||
166 | /* see if this is a comment */ | |
167 | if (bufline[0] == COMMENT_CHARACTER) | |
168 | continue; | |
169 | ||
170 | strncpy(line, bufline, count); | |
171 | line[count] = '\0'; | |
172 | temp = line; | |
173 | dbg_parse("read '%s'", temp); | |
174 | ||
175 | retval = parse_get_pair(&temp, &variable, &value); | |
176 | if (retval != 0) | |
177 | info("%s:%d:%Zd: error parsing '%s'", | |
178 | udev_config_filename, lineno, temp-line, temp); | |
179 | ||
180 | dbg_parse("variable='%s', value='%s'", variable, value); | |
181 | ||
182 | if (strcasecmp(variable, "udev_root") == 0) { | |
183 | strfieldcpy(udev_root, value); | |
184 | leading_slash(udev_root); | |
185 | continue; | |
186 | } | |
187 | ||
188 | if (strcasecmp(variable, "udev_db") == 0) { | |
189 | strfieldcpy(udev_db_filename, value); | |
190 | continue; | |
191 | } | |
192 | ||
193 | if (strcasecmp(variable, "udev_rules") == 0) { | |
194 | strfieldcpy(udev_rules_filename, value); | |
195 | no_leading_slash(udev_rules_filename); | |
196 | continue; | |
197 | } | |
198 | ||
199 | if (strcasecmp(variable, "udev_permissions") == 0) { | |
200 | strfieldcpy(udev_permissions_filename, value); | |
201 | no_leading_slash(udev_permissions_filename); | |
202 | continue; | |
203 | } | |
204 | ||
205 | if (strcasecmp(variable, "default_mode") == 0) { | |
206 | strfieldcpy(default_mode_str, value); | |
207 | continue; | |
208 | } | |
209 | ||
210 | if (strcasecmp(variable, "default_owner") == 0) { | |
211 | strfieldcpy(default_owner_str, value); | |
212 | continue; | |
213 | } | |
214 | ||
215 | if (strcasecmp(variable, "default_group") == 0) { | |
216 | strfieldcpy(default_group_str, value); | |
217 | continue; | |
218 | } | |
219 | ||
220 | if (strcasecmp(variable, "udev_log") == 0) { | |
221 | udev_log = string_is_true(value); | |
222 | continue; | |
223 | } | |
224 | ||
225 | info("%s:%d:%Zd: unknown key '%s'", | |
226 | udev_config_filename, lineno, temp-line, temp); | |
227 | } | |
228 | ||
229 | file_unmap(buf, bufsize); | |
230 | return retval; | |
231 | } | |
232 | ||
233 | static void get_dirs(void) | |
234 | { | |
235 | char *temp; | |
236 | int retval; | |
237 | ||
238 | retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); | |
239 | if (retval) | |
240 | dbg("sysfs_get_mnt_path failed"); | |
241 | ||
242 | /* see if we should try to override any of the default values */ | |
243 | if (getenv("UDEV_TEST") != NULL) { | |
244 | temp = getenv("SYSFS_PATH"); | |
245 | if (temp != NULL) { | |
246 | strfieldcpy(sysfs_path, temp); | |
247 | no_leading_slash(sysfs_path); | |
248 | } | |
249 | ||
250 | temp = getenv("UDEV_CONFIG_FILE"); | |
251 | if (temp != NULL) | |
252 | strfieldcpy(udev_config_filename, temp); | |
253 | } | |
254 | ||
255 | dbg("sysfs_path='%s'", sysfs_path); | |
256 | dbg_parse("udev_root = %s", udev_root); | |
257 | dbg_parse("udev_config_filename = %s", udev_config_filename); | |
258 | dbg_parse("udev_db_filename = %s", udev_db_filename); | |
259 | dbg_parse("udev_rules_filename = %s", udev_rules_filename); | |
260 | dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); | |
261 | dbg_parse("udev_log = %d", udev_log); | |
262 | ||
263 | parse_config_file(); | |
264 | ||
265 | dbg("udev_root = %s", udev_root); | |
266 | dbg("udev_config_filename = %s", udev_config_filename); | |
267 | dbg("udev_db_filename = %s", udev_db_filename); | |
268 | dbg("udev_rules_filename = %s", udev_rules_filename); | |
269 | dbg("udev_permissions_filename = %s", udev_permissions_filename); | |
270 | dbg("udev_log_str = %d", udev_log); | |
271 | } | |
272 | ||
273 | void udev_init_config(void) | |
274 | { | |
275 | init_variables(); | |
276 | get_dirs(); | |
277 | } |