chiark / gitweb /
let udevmonitor show the possibly renamed devpath
[elogind.git] / udev_config.c
1 /*
2  * udev_config.c
3  *
4  * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
5  * Copyright (C) 2004, 2005 Kay Sievers <kay.sievers@vrfy.org>
6  *
7  *      This program is free software; you can redistribute it and/or modify it
8  *      under the terms of the GNU General Public License as published by the
9  *      Free Software Foundation version 2 of the License.
10  * 
11  *      This program is distributed in the hope that it will be useful, but
12  *      WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *      General Public License for more details.
15  * 
16  *      You should have received a copy of the GNU General Public License along
17  *      with this program; if not, write to the Free Software Foundation, Inc.,
18  *      675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <ctype.h>
29 #include <syslog.h>
30
31 #include "udev.h"
32
33 /* global variables */
34 char udev_root[PATH_SIZE];
35 char udev_config_filename[PATH_SIZE];
36 char udev_rules_filename[PATH_SIZE];
37 int udev_log_priority;
38 int udev_run;
39
40 static int get_key(char **line, char **key, char **value)
41 {
42         char *linepos;
43         char *temp;
44
45         linepos = *line;
46         if (!linepos)
47                 return -1;
48
49         /* skip whitespace */
50         while (isspace(linepos[0]))
51                 linepos++;
52
53         /* get the key */
54         *key = linepos;
55         while (1) {
56                 linepos++;
57                 if (linepos[0] == '\0')
58                         return -1;
59                 if (isspace(linepos[0]))
60                         break;
61                 if (linepos[0] == '=')
62                         break;
63         }
64
65         /* terminate key */
66         linepos[0] = '\0';
67         linepos++;
68
69         /* skip whitespace */
70         while (isspace(linepos[0]))
71                 linepos++;
72
73         /* get the value*/
74         if (linepos[0] == '"')
75                 linepos++;
76         else
77                 return -1;
78         *value = linepos;
79
80         temp = strchr(linepos, '"');
81         if (!temp)
82                 return -1;
83         temp[0] = '\0';
84
85         return 0;
86 }
87
88 static int parse_config_file(void)
89 {
90         char line[LINE_SIZE];
91         char *bufline;
92         char *linepos;
93         char *variable;
94         char *value;
95         char *buf;
96         size_t bufsize;
97         size_t cur;
98         size_t count;
99         int lineno;
100         int retval = 0;
101
102         if (file_map(udev_config_filename, &buf, &bufsize) != 0) {
103                 err("can't open '%s' as config file: %s", udev_config_filename, strerror(errno));
104                 return -ENODEV;
105         }
106
107         /* loop through the whole file */
108         lineno = 0;
109         cur = 0;
110         while (cur < bufsize) {
111                 count = buf_get_line(buf, bufsize, cur);
112                 bufline = &buf[cur];
113                 cur += count+1;
114                 lineno++;
115
116                 if (count >= sizeof(line)) {
117                         err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno);
118                         continue;
119                 }
120
121                 /* eat the whitespace */
122                 while ((count > 0) && isspace(bufline[0])) {
123                         bufline++;
124                         count--;
125                 }
126                 if (count == 0)
127                         continue;
128
129                 /* see if this is a comment */
130                 if (bufline[0] == COMMENT_CHARACTER)
131                         continue;
132
133                 memcpy(line, bufline, count);
134                 line[count] = '\0';
135
136                 linepos = line;
137                 retval = get_key(&linepos, &variable, &value);
138                 if (retval != 0) {
139                         err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int)(linepos-line));
140                         continue;
141                 }
142
143                 if (strcasecmp(variable, "udev_root") == 0) {
144                         strlcpy(udev_root, value, sizeof(udev_root));
145                         remove_trailing_chars(udev_root, '/');
146                         continue;
147                 }
148
149                 if (strcasecmp(variable, "udev_rules") == 0) {
150                         strlcpy(udev_rules_filename, value, sizeof(udev_rules_filename));
151                         remove_trailing_chars(udev_rules_filename, '/');
152                         continue;
153                 }
154
155                 if (strcasecmp(variable, "udev_log") == 0) {
156                         udev_log_priority = log_priority(value);
157                         continue;
158                 }
159         }
160
161         file_unmap(buf, bufsize);
162         return retval;
163 }
164
165 void udev_config_init(void)
166 {
167         const char *env;
168
169         strcpy(udev_root, UDEV_ROOT);
170         strcpy(udev_config_filename, UDEV_CONFIG_FILE);
171         strcpy(udev_rules_filename, UDEV_RULES_FILE);
172         udev_log_priority = LOG_ERR;
173         udev_run = 1;
174
175         /* disable RUN key execution */
176         env = getenv("UDEV_RUN");
177         if (env && !string_is_true(env))
178                 udev_run = 0;
179
180         env = getenv("UDEV_CONFIG_FILE");
181         if (env) {
182                 strlcpy(udev_config_filename, env, sizeof(udev_config_filename));
183                 remove_trailing_chars(udev_config_filename, '/');
184         }
185
186         parse_config_file();
187
188         env = getenv("UDEV_ROOT");
189         if (env) {
190                 strlcpy(udev_root, env, sizeof(udev_root));
191                 remove_trailing_chars(udev_root, '/');
192         }
193
194         env = getenv("UDEV_LOG");
195         if (env)
196                 udev_log_priority = log_priority(env);
197
198         dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename);
199         dbg("udev_root='%s'", udev_root);
200         dbg("udev_rules='%s'", udev_rules_filename);
201         dbg("udev_log=%d", udev_log_priority);
202 }