]>
Commit | Line | Data |
---|---|---|
88a6477e KS |
1 | /*** |
2 | This file is part of systemd. | |
3 | ||
25e773ee | 4 | Copyright 2008-2014 Kay Sievers <kay@vrfy.org> |
88a6477e KS |
5 | |
6 | systemd is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU Lesser General Public License as published by | |
8 | the Free Software Foundation; either version 2.1 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | systemd 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 | Lesser General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU Lesser General Public License | |
17 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
18 | ***/ | |
33a5cc29 | 19 | |
33a5cc29 KS |
20 | #include <stdio.h> |
21 | #include <stdlib.h> | |
22 | #include <stddef.h> | |
4cf23685 | 23 | #include <stdarg.h> |
33a5cc29 KS |
24 | #include <unistd.h> |
25 | #include <errno.h> | |
26 | #include <string.h> | |
7d563a17 | 27 | #include <ctype.h> |
4f1795cc | 28 | #include <time.h> |
33a5cc29 KS |
29 | |
30 | #include "libudev.h" | |
31 | #include "libudev-private.h" | |
4db17f29 | 32 | #include "missing.h" |
33a5cc29 | 33 | |
ce1d6d7f KS |
34 | /** |
35 | * SECTION:libudev | |
36 | * @short_description: libudev context | |
37 | * | |
38 | * The context contains the default values read from the udev config file, | |
39 | * and is passed to all library operations. | |
40 | */ | |
41 | ||
1e511322 KS |
42 | /** |
43 | * udev: | |
44 | * | |
ce1d6d7f | 45 | * Opaque object representing the library context. |
1e511322 | 46 | */ |
ba6929f6 | 47 | struct udev { |
912541b0 KS |
48 | int refcount; |
49 | void (*log_fn)(struct udev *udev, | |
50 | int priority, const char *file, int line, const char *fn, | |
51 | const char *format, va_list args); | |
52 | void *userdata; | |
912541b0 | 53 | struct udev_list properties_list; |
ba6929f6 KS |
54 | }; |
55 | ||
1e511322 KS |
56 | /** |
57 | * udev_get_userdata: | |
58 | * @udev: udev library context | |
59 | * | |
60 | * Retrieve stored data pointer from library context. This might be useful | |
25e773ee | 61 | * to access from callbacks. |
1e511322 KS |
62 | * |
63 | * Returns: stored userdata | |
64 | **/ | |
25e773ee | 65 | _public_ void *udev_get_userdata(struct udev *udev) { |
912541b0 KS |
66 | if (udev == NULL) |
67 | return NULL; | |
68 | return udev->userdata; | |
c8e32461 KS |
69 | } |
70 | ||
1e511322 KS |
71 | /** |
72 | * udev_set_userdata: | |
73 | * @udev: udev library context | |
74 | * @userdata: data pointer | |
75 | * | |
76 | * Store custom @userdata in the library context. | |
77 | **/ | |
25e773ee | 78 | _public_ void udev_set_userdata(struct udev *udev, void *userdata) { |
912541b0 KS |
79 | if (udev == NULL) |
80 | return; | |
81 | udev->userdata = userdata; | |
c8e32461 KS |
82 | } |
83 | ||
33a5cc29 KS |
84 | /** |
85 | * udev_new: | |
86 | * | |
1e511322 KS |
87 | * Create udev library context. This reads the udev configuration |
88 | * file, and fills in the default values. | |
33a5cc29 KS |
89 | * |
90 | * The initial refcount is 1, and needs to be decremented to | |
be7de409 | 91 | * release the resources of the udev library context. |
33a5cc29 KS |
92 | * |
93 | * Returns: a new udev library context | |
94 | **/ | |
25e773ee | 95 | _public_ struct udev *udev_new(void) { |
912541b0 | 96 | struct udev *udev; |
ea55caa6 | 97 | _cleanup_fclose_ FILE *f = NULL; |
912541b0 | 98 | |
955d98c9 | 99 | udev = new0(struct udev, 1); |
912541b0 KS |
100 | if (udev == NULL) |
101 | return NULL; | |
102 | udev->refcount = 1; | |
912541b0 KS |
103 | udev_list_init(udev, &udev->properties_list, true); |
104 | ||
ff944daa | 105 | f = fopen("/etc/udev/udev.conf", "re"); |
912541b0 KS |
106 | if (f != NULL) { |
107 | char line[UTIL_LINE_SIZE]; | |
fe756ed9 | 108 | unsigned line_nr = 0; |
912541b0 KS |
109 | |
110 | while (fgets(line, sizeof(line), f)) { | |
111 | size_t len; | |
112 | char *key; | |
113 | char *val; | |
114 | ||
115 | line_nr++; | |
116 | ||
117 | /* find key */ | |
118 | key = line; | |
119 | while (isspace(key[0])) | |
120 | key++; | |
121 | ||
122 | /* comment or empty line */ | |
123 | if (key[0] == '#' || key[0] == '\0') | |
124 | continue; | |
125 | ||
126 | /* split key/value */ | |
127 | val = strchr(key, '='); | |
128 | if (val == NULL) { | |
25e773ee | 129 | log_debug("/etc/udev/udev.conf:%u: missing assignment, skipping line.\n", line_nr); |
912541b0 KS |
130 | continue; |
131 | } | |
132 | val[0] = '\0'; | |
133 | val++; | |
134 | ||
135 | /* find value */ | |
136 | while (isspace(val[0])) | |
137 | val++; | |
138 | ||
139 | /* terminate key */ | |
140 | len = strlen(key); | |
141 | if (len == 0) | |
142 | continue; | |
143 | while (isspace(key[len-1])) | |
144 | len--; | |
145 | key[len] = '\0'; | |
146 | ||
147 | /* terminate value */ | |
148 | len = strlen(val); | |
149 | if (len == 0) | |
150 | continue; | |
151 | while (isspace(val[len-1])) | |
152 | len--; | |
153 | val[len] = '\0'; | |
154 | ||
155 | if (len == 0) | |
156 | continue; | |
157 | ||
158 | /* unquote */ | |
159 | if (val[0] == '"' || val[0] == '\'') { | |
160 | if (val[len-1] != val[0]) { | |
25e773ee | 161 | log_debug("/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.\n", line_nr); |
912541b0 KS |
162 | continue; |
163 | } | |
164 | val[len-1] = '\0'; | |
165 | val++; | |
166 | } | |
167 | ||
090be865 | 168 | if (streq(key, "udev_log")) { |
ee7122c0 ZJS |
169 | int prio; |
170 | ||
171 | prio = util_log_priority(val); | |
172 | if (prio < 0) | |
25e773ee | 173 | log_debug("/etc/udev/udev.conf:%u: invalid log level '%s', ignoring.\n", line_nr, val); |
ee7122c0 | 174 | else |
25e773ee | 175 | log_set_max_level(prio); |
912541b0 KS |
176 | continue; |
177 | } | |
912541b0 | 178 | } |
912541b0 KS |
179 | } |
180 | ||
912541b0 | 181 | return udev; |
33a5cc29 KS |
182 | } |
183 | ||
184 | /** | |
185 | * udev_ref: | |
186 | * @udev: udev library context | |
187 | * | |
188 | * Take a reference of the udev library context. | |
189 | * | |
190 | * Returns: the passed udev library context | |
191 | **/ | |
25e773ee | 192 | _public_ struct udev *udev_ref(struct udev *udev) { |
912541b0 KS |
193 | if (udev == NULL) |
194 | return NULL; | |
195 | udev->refcount++; | |
196 | return udev; | |
33a5cc29 KS |
197 | } |
198 | ||
199 | /** | |
200 | * udev_unref: | |
201 | * @udev: udev library context | |
202 | * | |
203 | * Drop a reference of the udev library context. If the refcount | |
be7de409 | 204 | * reaches zero, the resources of the context will be released. |
33a5cc29 | 205 | * |
c1959569 | 206 | * Returns: the passed udev library context if it has still an active reference, or #NULL otherwise. |
33a5cc29 | 207 | **/ |
25e773ee | 208 | _public_ struct udev *udev_unref(struct udev *udev) { |
912541b0 | 209 | if (udev == NULL) |
20bbd54f | 210 | return NULL; |
912541b0 KS |
211 | udev->refcount--; |
212 | if (udev->refcount > 0) | |
20bbd54f | 213 | return udev; |
912541b0 | 214 | udev_list_cleanup(&udev->properties_list); |
912541b0 | 215 | free(udev); |
20bbd54f | 216 | return NULL; |
33a5cc29 KS |
217 | } |
218 | ||
219 | /** | |
220 | * udev_set_log_fn: | |
221 | * @udev: udev library context | |
f47ad593 | 222 | * @log_fn: function to be called for log messages |
33a5cc29 | 223 | * |
25e773ee | 224 | * This function is deprecated. |
33a5cc29 KS |
225 | * |
226 | **/ | |
54cf0b7f | 227 | _public_ void udev_set_log_fn(struct udev *udev, |
912541b0 KS |
228 | void (*log_fn)(struct udev *udev, |
229 | int priority, const char *file, int line, const char *fn, | |
25e773ee KS |
230 | const char *format, va_list args)) { |
231 | return; | |
7d563a17 KS |
232 | } |
233 | ||
1e511322 KS |
234 | /** |
235 | * udev_get_log_priority: | |
236 | * @udev: udev library context | |
237 | * | |
25e773ee | 238 | * This function is deprecated. |
1e511322 | 239 | * |
1e511322 | 240 | **/ |
25e773ee KS |
241 | _public_ int udev_get_log_priority(struct udev *udev) { |
242 | return log_get_max_level(); | |
7d563a17 KS |
243 | } |
244 | ||
1e511322 KS |
245 | /** |
246 | * udev_set_log_priority: | |
247 | * @udev: udev library context | |
f47ad593 | 248 | * @priority: the new log priority |
1e511322 | 249 | * |
25e773ee KS |
250 | * This function is deprecated. |
251 | * | |
1e511322 | 252 | **/ |
25e773ee KS |
253 | _public_ void udev_set_log_priority(struct udev *udev, int priority) { |
254 | log_set_max_level(priority); | |
7d563a17 KS |
255 | } |
256 | ||
25e773ee | 257 | struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value) { |
912541b0 KS |
258 | if (value == NULL) { |
259 | struct udev_list_entry *list_entry; | |
260 | ||
261 | list_entry = udev_get_properties_list_entry(udev); | |
262 | list_entry = udev_list_entry_get_by_name(list_entry, key); | |
263 | if (list_entry != NULL) | |
264 | udev_list_entry_delete(list_entry); | |
265 | return NULL; | |
266 | } | |
267 | return udev_list_entry_add(&udev->properties_list, key, value); | |
f183b6ed KS |
268 | } |
269 | ||
25e773ee | 270 | struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev) { |
912541b0 | 271 | return udev_list_get_entry(&udev->properties_list); |
f183b6ed | 272 | } |