]>
Commit | Line | Data |
---|---|---|
e8baccca GKH |
1 | /* |
2 | * udev_config.c | |
3 | * | |
4 | * Userspace devfs | |
5 | * | |
274812b5 | 6 | * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com> |
e8baccca GKH |
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 | ||
e8baccca GKH |
24 | #include <stdlib.h> |
25 | #include <string.h> | |
26 | #include <stdio.h> | |
27 | #include <fcntl.h> | |
28 | #include <unistd.h> | |
29 | #include <errno.h> | |
30 | #include <ctype.h> | |
6b493a20 | 31 | #include <syslog.h> |
e8baccca | 32 | |
c80da508 | 33 | #include "libsysfs/sysfs/libsysfs.h" |
63f61c5c | 34 | #include "udev_libc_wrapper.h" |
e8baccca | 35 | #include "udev.h" |
9af5bb2f | 36 | #include "udev_utils.h" |
e8baccca | 37 | #include "udev_version.h" |
54988802 | 38 | #include "logging.h" |
e8baccca GKH |
39 | |
40 | /* global variables */ | |
63f61c5c KS |
41 | char sysfs_path[PATH_SIZE]; |
42 | char udev_root[PATH_SIZE]; | |
43 | char udev_db_path[PATH_SIZE]; | |
63f61c5c | 44 | char udev_config_filename[PATH_SIZE]; |
6b493a20 KS |
45 | char udev_rules_filename[PATH_SIZE]; |
46 | int udev_log_priority; | |
821d0ec8 | 47 | int udev_run; |
bbbe503e | 48 | int udev_dev_d; |
16ac31aa | 49 | int udev_hotplug_d; |
e8baccca | 50 | |
5f72c470 | 51 | static int string_is_true(const char *str) |
51a8bb2f GKH |
52 | { |
53 | if (strcasecmp(str, "true") == 0) | |
54 | return 1; | |
55 | if (strcasecmp(str, "yes") == 0) | |
56 | return 1; | |
c3335930 | 57 | if (strcasecmp(str, "1") == 0) |
58 | return 1; | |
51a8bb2f GKH |
59 | return 0; |
60 | } | |
61 | ||
6b493a20 KS |
62 | static int log_priority(const char *priority) |
63 | { | |
64 | char *endptr; | |
65 | int prio; | |
66 | ||
67 | prio = strtol(priority, &endptr, 10); | |
68 | if (endptr[0] == '\0') | |
69 | return prio; | |
70 | if (strncasecmp(priority, "err", 3) == 0) | |
71 | return LOG_ERR; | |
72 | if (strcasecmp(priority, "info") == 0) | |
73 | return LOG_INFO; | |
74 | if (strcasecmp(priority, "debug") == 0) | |
75 | return LOG_DEBUG; | |
76 | if (string_is_true(priority)) | |
77 | return LOG_ERR; | |
78 | ||
79 | return 0; | |
80 | } | |
81 | ||
28ce66de KS |
82 | static int get_key(char **line, char **key, char **value) |
83 | { | |
84 | char *linepos; | |
85 | char *temp; | |
86 | ||
87 | linepos = *line; | |
88 | if (!linepos) | |
89 | return -1; | |
90 | ||
91 | /* skip whitespace */ | |
92 | while (isspace(linepos[0])) | |
93 | linepos++; | |
94 | ||
95 | /* get the key */ | |
96 | *key = linepos; | |
97 | while (1) { | |
98 | linepos++; | |
99 | if (linepos[0] == '\0') | |
100 | return -1; | |
101 | if (isspace(linepos[0])) | |
102 | break; | |
103 | if (linepos[0] == '=') | |
104 | break; | |
105 | } | |
106 | ||
107 | /* terminate key */ | |
108 | linepos[0] = '\0'; | |
109 | linepos++; | |
110 | ||
111 | /* skip whitespace */ | |
112 | while (isspace(linepos[0])) | |
113 | linepos++; | |
114 | ||
115 | /* get the value*/ | |
116 | if (linepos[0] == '"') | |
117 | linepos++; | |
118 | else | |
119 | return -1; | |
120 | *value = linepos; | |
121 | ||
122 | temp = strchr(linepos, '"'); | |
123 | if (!temp) | |
124 | return -1; | |
125 | temp[0] = '\0'; | |
126 | ||
127 | return 0; | |
128 | } | |
129 | ||
e8baccca GKH |
130 | static int parse_config_file(void) |
131 | { | |
3e441450 | 132 | char line[LINE_SIZE]; |
133 | char *bufline; | |
28ce66de | 134 | char *linepos; |
e8baccca GKH |
135 | char *variable; |
136 | char *value; | |
c81b35c0 KS |
137 | char *buf; |
138 | size_t bufsize; | |
139 | size_t cur; | |
140 | size_t count; | |
141 | int lineno; | |
e8baccca | 142 | int retval = 0; |
c81b35c0 | 143 | |
63f61c5c | 144 | if (file_map(udev_config_filename, &buf, &bufsize) != 0) { |
6b493a20 | 145 | err("can't open '%s' as config file", udev_config_filename); |
e8baccca GKH |
146 | return -ENODEV; |
147 | } | |
148 | ||
149 | /* loop through the whole file */ | |
c81b35c0 KS |
150 | lineno = 0; |
151 | cur = 0; | |
3e441450 | 152 | while (cur < bufsize) { |
c81b35c0 | 153 | count = buf_get_line(buf, bufsize, cur); |
3e441450 | 154 | bufline = &buf[cur]; |
c81b35c0 | 155 | cur += count+1; |
3e441450 | 156 | lineno++; |
e8baccca | 157 | |
63f61c5c | 158 | if (count >= sizeof(line)) { |
6b493a20 | 159 | err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); |
3e441450 | 160 | continue; |
161 | } | |
e8baccca | 162 | |
3e441450 | 163 | /* eat the whitespace */ |
3db7fa27 | 164 | while ((count > 0) && isspace(bufline[0])) { |
3e441450 | 165 | bufline++; |
166 | count--; | |
167 | } | |
3db7fa27 KS |
168 | if (count == 0) |
169 | continue; | |
3e441450 | 170 | |
e8baccca | 171 | /* see if this is a comment */ |
3e441450 | 172 | if (bufline[0] == COMMENT_CHARACTER) |
e8baccca GKH |
173 | continue; |
174 | ||
8a4c0c32 | 175 | strlcpy(line, bufline, count+1); |
3e441450 | 176 | |
28ce66de KS |
177 | linepos = line; |
178 | retval = get_key(&linepos, &variable, &value); | |
179 | if (retval != 0) { | |
6b493a20 | 180 | err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int) (linepos-line)); |
28ce66de KS |
181 | continue; |
182 | } | |
aef6bb13 | 183 | |
aef6bb13 | 184 | if (strcasecmp(variable, "udev_root") == 0) { |
63f61c5c | 185 | strlcpy(udev_root, value, sizeof(udev_root)); |
18614ab2 | 186 | remove_trailing_char(udev_root, '/'); |
aef6bb13 KS |
187 | continue; |
188 | } | |
189 | ||
190 | if (strcasecmp(variable, "udev_db") == 0) { | |
63f61c5c | 191 | strlcpy(udev_db_path, value, sizeof(udev_db_path)); |
18614ab2 | 192 | remove_trailing_char(udev_db_path, '/'); |
aef6bb13 KS |
193 | continue; |
194 | } | |
195 | ||
196 | if (strcasecmp(variable, "udev_rules") == 0) { | |
63f61c5c | 197 | strlcpy(udev_rules_filename, value, sizeof(udev_rules_filename)); |
18614ab2 | 198 | remove_trailing_char(udev_rules_filename, '/'); |
aef6bb13 KS |
199 | continue; |
200 | } | |
201 | ||
aef6bb13 | 202 | if (strcasecmp(variable, "udev_log") == 0) { |
6b493a20 | 203 | udev_log_priority = log_priority(value); |
aef6bb13 KS |
204 | continue; |
205 | } | |
e8baccca | 206 | } |
c81b35c0 KS |
207 | |
208 | file_unmap(buf, bufsize); | |
e8baccca GKH |
209 | return retval; |
210 | } | |
211 | ||
28ce66de | 212 | void udev_init_config(void) |
e8baccca | 213 | { |
6b493a20 | 214 | const char *env; |
e8baccca | 215 | |
6b493a20 KS |
216 | strcpy(udev_root, UDEV_ROOT); |
217 | strcpy(udev_db_path, UDEV_DB); | |
218 | strcpy(udev_config_filename, UDEV_CONFIG_FILE); | |
219 | strcpy(udev_rules_filename, UDEV_RULES_FILE); | |
220 | udev_log_priority = LOG_ERR; | |
821d0ec8 | 221 | udev_run = 1; |
6b493a20 KS |
222 | udev_dev_d = 1; |
223 | udev_hotplug_d = 1; | |
28ce66de | 224 | sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); |
e8baccca | 225 | |
821d0ec8 KS |
226 | /* disable RUN key execution */ |
227 | env = getenv("UDEV_RUN"); | |
228 | if (env && !string_is_true(env)) | |
229 | udev_run = 0; | |
230 | ||
6b493a20 KS |
231 | env = getenv("UDEV_NO_DEVD"); |
232 | if (env && string_is_true(env)) | |
233 | udev_dev_d = 0; | |
234 | ||
235 | env = getenv("UDEV_NO_HOTPLUGD"); | |
236 | if (env && string_is_true(env)) | |
237 | udev_hotplug_d = 0; | |
238 | ||
239 | env = getenv("UDEV_CONFIG_FILE"); | |
240 | if (env) { | |
241 | strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); | |
18614ab2 | 242 | remove_trailing_char(udev_config_filename, '/'); |
6b493a20 | 243 | } |
e8baccca | 244 | |
e8baccca | 245 | parse_config_file(); |
6b493a20 KS |
246 | |
247 | env = getenv("UDEV_LOG"); | |
248 | if (env) | |
249 | udev_log_priority = log_priority(env); | |
250 | ||
9f8dfa19 | 251 | dbg("sysfs_path='%s'", sysfs_path); |
6b493a20 | 252 | dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename); |
9f8dfa19 | 253 | dbg("udev_root='%s'", udev_root); |
6b493a20 KS |
254 | dbg("udev_db='%s'", udev_db_path); |
255 | dbg("udev_rules='%s'", udev_rules_filename); | |
256 | dbg("udev_log=%d", udev_log_priority); | |
e8baccca | 257 | } |