]>
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 "udev.h" | |
36 | #include "udev_version.h" | |
37 | #include "logging.h" | |
38 | #include "namedev.h" | |
39 | #include "libsysfs/libsysfs.h" | |
40 | ||
41 | /* global variables */ | |
42 | char sysfs_path[SYSFS_PATH_MAX]; | |
43 | char udev_root[PATH_MAX]; | |
44 | char udev_db_filename[PATH_MAX+NAME_MAX]; | |
45 | char udev_permissions_filename[PATH_MAX+NAME_MAX]; | |
46 | char udev_rules_filename[PATH_MAX+NAME_MAX]; | |
47 | char udev_config_filename[PATH_MAX+NAME_MAX]; | |
48 | char default_mode_str[MODE_SIZE]; | |
49 | char default_owner_str[OWNER_SIZE]; | |
50 | char default_group_str[GROUP_SIZE]; | |
51 | ||
52 | ||
53 | static void init_variables(void) | |
54 | { | |
55 | /* fill up the defaults. | |
56 | * If any config values are specified, they will | |
57 | * override these values. */ | |
58 | strfieldcpy(udev_root, UDEV_ROOT); | |
59 | strfieldcpy(udev_db_filename, UDEV_DB); | |
60 | strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); | |
61 | strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); | |
62 | strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); | |
63 | } | |
64 | ||
65 | #define set_var(_name, _var) \ | |
66 | if (strcasecmp(variable, _name) == 0) { \ | |
67 | dbg_parse("%s = '%s'", _name, value); \ | |
68 | strncpy(_var, value, sizeof(_var)); \ | |
69 | } | |
70 | ||
71 | int parse_get_pair(char **orig_string, char **left, char **right) | |
72 | { | |
73 | char *temp; | |
74 | char *string = *orig_string; | |
75 | ||
76 | if (!string) | |
77 | return -ENODEV; | |
78 | ||
79 | /* eat any whitespace */ | |
80 | while (isspace(*string) || *string == ',') | |
81 | ++string; | |
82 | ||
83 | /* split based on '=' */ | |
84 | temp = strsep(&string, "="); | |
85 | *left = temp; | |
86 | if (!string) | |
87 | return -ENODEV; | |
88 | ||
89 | /* take the right side and strip off the '"' */ | |
90 | while (isspace(*string)) | |
91 | ++string; | |
92 | if (*string == '"') | |
93 | ++string; | |
94 | else | |
95 | return -ENODEV; | |
96 | ||
97 | temp = strsep(&string, "\""); | |
98 | if (!string || *temp == '\0') | |
99 | return -ENODEV; | |
100 | *right = temp; | |
101 | *orig_string = string; | |
102 | ||
103 | return 0; | |
104 | } | |
105 | ||
106 | static int parse_config_file(void) | |
107 | { | |
108 | char line[255]; | |
109 | char *temp; | |
110 | char *variable; | |
111 | char *value; | |
112 | FILE *fd; | |
113 | int lineno = 0; | |
114 | int retval = 0; | |
115 | ||
116 | fd = fopen(udev_config_filename, "r"); | |
117 | if (fd != NULL) { | |
118 | dbg("reading '%s' as config file", udev_config_filename); | |
119 | } else { | |
120 | dbg("can't open '%s' as config file", udev_config_filename); | |
121 | return -ENODEV; | |
122 | } | |
123 | ||
124 | /* loop through the whole file */ | |
125 | while (1) { | |
126 | /* get a line */ | |
127 | temp = fgets(line, sizeof(line), fd); | |
128 | if (temp == NULL) | |
129 | goto exit; | |
130 | lineno++; | |
131 | ||
132 | dbg_parse("read '%s'", temp); | |
133 | ||
134 | /* eat the whitespace at the beginning of the line */ | |
135 | while (isspace(*temp)) | |
136 | ++temp; | |
137 | ||
138 | /* empty line? */ | |
139 | if (*temp == 0x00) | |
140 | continue; | |
141 | ||
142 | /* see if this is a comment */ | |
143 | if (*temp == COMMENT_CHARACTER) | |
144 | continue; | |
145 | ||
146 | retval = parse_get_pair(&temp, &variable, &value); | |
147 | if (retval) | |
148 | break; | |
149 | ||
150 | dbg_parse("variable = '%s', value = '%s'", variable, value); | |
151 | ||
152 | set_var("udev_root", udev_root); | |
153 | set_var("udev_db", udev_db_filename); | |
154 | set_var("udev_rules", udev_rules_filename); | |
155 | set_var("udev_permissions", udev_permissions_filename); | |
156 | set_var("default_mode", default_mode_str); | |
157 | set_var("default_owner", default_owner_str); | |
158 | set_var("default_group", default_group_str); | |
159 | } | |
160 | dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, | |
161 | lineno, temp - line, temp); | |
162 | exit: | |
163 | fclose(fd); | |
164 | return retval; | |
165 | } | |
166 | ||
167 | static void get_dirs(void) | |
168 | { | |
169 | char *temp; | |
170 | int retval; | |
171 | ||
172 | retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); | |
173 | if (retval) | |
174 | dbg("sysfs_get_mnt_path failed"); | |
175 | ||
176 | /* see if we should try to override any of the default values */ | |
177 | temp = getenv("UDEV_TEST"); | |
178 | if (temp != NULL) { | |
179 | /* hm testing is happening, use the specified values, if they are present */ | |
180 | temp = getenv("SYSFS_PATH"); | |
181 | if (temp) | |
182 | strfieldcpy(sysfs_path, temp); | |
183 | temp = getenv("UDEV_CONFIG_FILE"); | |
184 | if (temp) | |
185 | strfieldcpy(udev_config_filename, temp); | |
186 | } | |
187 | dbg("sysfs_path='%s'", sysfs_path); | |
188 | ||
189 | dbg_parse("udev_root = %s", udev_root); | |
190 | dbg_parse("udev_config_filename = %s", udev_config_filename); | |
191 | dbg_parse("udev_db_filename = %s", udev_db_filename); | |
192 | dbg_parse("udev_rules_filename = %s", udev_rules_filename); | |
193 | dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); | |
194 | parse_config_file(); | |
195 | ||
196 | dbg_parse("udev_root = %s", udev_root); | |
197 | dbg_parse("udev_config_filename = %s", udev_config_filename); | |
198 | dbg_parse("udev_db_filename = %s", udev_db_filename); | |
199 | dbg_parse("udev_rules_filename = %s", udev_rules_filename); | |
200 | dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); | |
201 | } | |
202 | ||
203 | void udev_init_config(void) | |
204 | { | |
205 | init_variables(); | |
206 | get_dirs(); | |
207 | } | |
208 | ||
209 |