chiark / gitweb /
[PATCH] add get_devnode() helper to udev_lib for udev_dbus program
[elogind.git] / udev_config.c
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_sleep;
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         return 0;
63 }
64
65 static void init_variables(void)
66 {
67         /* fill up the defaults.  
68          * If any config values are specified, they will
69          * override these values. */
70         strfieldcpy(udev_root, UDEV_ROOT);
71         strfieldcpy(udev_db_filename, UDEV_DB);
72         strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE);
73         strfieldcpy(udev_rules_filename, UDEV_RULES_FILE);
74         strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE);
75         udev_log = string_is_true(UDEV_LOG_DEFAULT);
76
77         udev_sleep = 1;
78         if (getenv("UDEV_NO_SLEEP") != NULL)
79                 udev_sleep = 0;
80 }
81
82 #define set_var(_name, _var)                            \
83         if (strcasecmp(variable, _name) == 0) {         \
84                 dbg_parse("%s = '%s'", _name, value);   \
85                 strfieldcpymax(_var, value, sizeof(_var));\
86         }
87
88 #define set_bool(_name, _var)                           \
89         if (strcasecmp(variable, _name) == 0) {         \
90                 dbg_parse("%s = '%s'", _name, value);   \
91                 _var = string_is_true(value);           \
92         }
93
94 int parse_get_pair(char **orig_string, char **left, char **right)
95 {
96         char *temp;
97         char *string = *orig_string;
98
99         if (!string)
100                 return -ENODEV;
101
102         /* eat any whitespace */
103         while (isspace(*string) || *string == ',')
104                 ++string;
105
106         /* split based on '=' */
107         temp = strsep(&string, "=");
108         *left = temp;
109         if (!string)
110                 return -ENODEV;
111
112         /* take the right side and strip off the '"' */
113         while (isspace(*string))
114                 ++string;
115         if (*string == '"')
116                 ++string;
117         else
118                 return -ENODEV;
119
120         temp = strsep(&string, "\"");
121         if (!string || *temp == '\0')
122                 return -ENODEV;
123         *right = temp;
124         *orig_string = string;
125         
126         return 0;
127 }
128
129 static int parse_config_file(void)
130 {
131         char line[255];
132         char *temp;
133         char *variable;
134         char *value;
135         char *buf;
136         size_t bufsize;
137         size_t cur;
138         size_t count;
139         int lineno;
140         int retval = 0;
141
142         if (file_map(udev_config_filename, &buf, &bufsize) == 0) {
143                 dbg("reading '%s' as config file", udev_config_filename);
144         } else {
145                 dbg("can't open '%s' as config file", udev_config_filename);
146                 return -ENODEV;
147         }
148
149         /* loop through the whole file */
150         lineno = 0;
151         cur = 0;
152         while (1) {
153                 count = buf_get_line(buf, bufsize, cur);
154
155                 strncpy(line, buf + cur, count);
156                 line[count] = '\0';
157                 temp = line;
158                 lineno++;
159
160                 cur += count+1;
161                 if (cur > bufsize)
162                         break;
163
164                 dbg_parse("read '%s'", temp);
165
166                 /* eat the whitespace at the beginning of the line */
167                 while (isspace(*temp))
168                         ++temp;
169
170                 /* empty line? */
171                 if (*temp == 0x00)
172                         continue;
173
174                 /* see if this is a comment */
175                 if (*temp == COMMENT_CHARACTER)
176                         continue;
177
178                 retval = parse_get_pair(&temp, &variable, &value);
179                 if (retval)
180                         break;
181                 
182                 dbg_parse("variable = '%s', value = '%s'", variable, value);
183
184                 set_var("udev_root", udev_root);
185                 set_var("udev_db", udev_db_filename);
186                 set_var("udev_rules", udev_rules_filename);
187                 set_var("udev_permissions", udev_permissions_filename);
188                 set_var("default_mode", default_mode_str);
189                 set_var("default_owner", default_owner_str);
190                 set_var("default_group", default_group_str);
191                 set_bool("udev_log", udev_log);
192         }
193         dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename,
194                   lineno, temp - line, temp);
195
196         file_unmap(buf, bufsize);
197         return retval;
198 }
199
200 static void get_dirs(void)
201 {
202         char *temp;
203         int retval;
204
205         retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX);
206         if (retval)
207                 dbg("sysfs_get_mnt_path failed");
208
209         /* see if we should try to override any of the default values */
210         temp = getenv("UDEV_TEST");
211         if (temp != NULL) {
212                 /* hm testing is happening, use the specified values, if they are present */
213                 temp = getenv("SYSFS_PATH");
214                 if (temp)
215                         strfieldcpy(sysfs_path, temp);
216                 temp = getenv("UDEV_CONFIG_FILE");
217                 if (temp)
218                         strfieldcpy(udev_config_filename, temp);
219         }
220         dbg("sysfs_path='%s'", sysfs_path);
221
222         dbg_parse("udev_root = %s", udev_root);
223         dbg_parse("udev_config_filename = %s", udev_config_filename);
224         dbg_parse("udev_db_filename = %s", udev_db_filename);
225         dbg_parse("udev_rules_filename = %s", udev_rules_filename);
226         dbg_parse("udev_permissions_filename = %s", udev_permissions_filename);
227         dbg_parse("udev_log = %d", udev_log);
228         parse_config_file();
229
230         dbg_parse("udev_root = %s", udev_root);
231         dbg_parse("udev_config_filename = %s", udev_config_filename);
232         dbg_parse("udev_db_filename = %s", udev_db_filename);
233         dbg_parse("udev_rules_filename = %s", udev_rules_filename);
234         dbg_parse("udev_permissions_filename = %s", udev_permissions_filename);
235         dbg_parse("udev_log_str = %d", udev_log);
236 }
237
238 void udev_init_config(void)
239 {
240         init_variables();
241         get_dirs();
242 }
243
244