Line data Source code
1 : /***
2 : This file is part of systemd.
3 :
4 : Copyright 2008-2014 Kay Sievers <kay@vrfy.org>
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 : ***/
19 :
20 : #include <stdio.h>
21 : #include <stdlib.h>
22 : #include <stddef.h>
23 : #include <stdarg.h>
24 : #include <string.h>
25 : #include <ctype.h>
26 :
27 : #include "libudev.h"
28 : #include "libudev-private.h"
29 : #include "missing.h"
30 :
31 : /**
32 : * SECTION:libudev
33 : * @short_description: libudev context
34 : *
35 : * The context contains the default values read from the udev config file,
36 : * and is passed to all library operations.
37 : */
38 :
39 : /**
40 : * udev:
41 : *
42 : * Opaque object representing the library context.
43 : */
44 : struct udev {
45 : int refcount;
46 : void (*log_fn)(struct udev *udev,
47 : int priority, const char *file, int line, const char *fn,
48 : const char *format, va_list args);
49 : void *userdata;
50 : };
51 :
52 : /**
53 : * udev_get_userdata:
54 : * @udev: udev library context
55 : *
56 : * Retrieve stored data pointer from library context. This might be useful
57 : * to access from callbacks.
58 : *
59 : * Returns: stored userdata
60 : **/
61 0 : _public_ void *udev_get_userdata(struct udev *udev) {
62 0 : if (udev == NULL)
63 0 : return NULL;
64 0 : return udev->userdata;
65 : }
66 :
67 : /**
68 : * udev_set_userdata:
69 : * @udev: udev library context
70 : * @userdata: data pointer
71 : *
72 : * Store custom @userdata in the library context.
73 : **/
74 0 : _public_ void udev_set_userdata(struct udev *udev, void *userdata) {
75 0 : if (udev == NULL)
76 0 : return;
77 0 : udev->userdata = userdata;
78 : }
79 :
80 : /**
81 : * udev_new:
82 : *
83 : * Create udev library context. This reads the udev configuration
84 : * file, and fills in the default values.
85 : *
86 : * The initial refcount is 1, and needs to be decremented to
87 : * release the resources of the udev library context.
88 : *
89 : * Returns: a new udev library context
90 : **/
91 18 : _public_ struct udev *udev_new(void) {
92 : struct udev *udev;
93 36 : _cleanup_fclose_ FILE *f = NULL;
94 :
95 18 : udev = new0(struct udev, 1);
96 18 : if (udev == NULL)
97 0 : return NULL;
98 18 : udev->refcount = 1;
99 :
100 18 : f = fopen("/etc/udev/udev.conf", "re");
101 18 : if (f != NULL) {
102 : char line[UTIL_LINE_SIZE];
103 18 : unsigned line_nr = 0;
104 :
105 90 : while (fgets(line, sizeof(line), f)) {
106 : size_t len;
107 : char *key;
108 : char *val;
109 :
110 54 : line_nr++;
111 :
112 : /* find key */
113 54 : key = line;
114 126 : while (isspace(key[0]))
115 18 : key++;
116 :
117 : /* comment or empty line */
118 54 : if (key[0] == '#' || key[0] == '\0')
119 54 : continue;
120 :
121 : /* split key/value */
122 0 : val = strchr(key, '=');
123 0 : if (val == NULL) {
124 0 : log_debug("/etc/udev/udev.conf:%u: missing assignment, skipping line.", line_nr);
125 0 : continue;
126 : }
127 0 : val[0] = '\0';
128 0 : val++;
129 :
130 : /* find value */
131 0 : while (isspace(val[0]))
132 0 : val++;
133 :
134 : /* terminate key */
135 0 : len = strlen(key);
136 0 : if (len == 0)
137 0 : continue;
138 0 : while (isspace(key[len-1]))
139 0 : len--;
140 0 : key[len] = '\0';
141 :
142 : /* terminate value */
143 0 : len = strlen(val);
144 0 : if (len == 0)
145 0 : continue;
146 0 : while (isspace(val[len-1]))
147 0 : len--;
148 0 : val[len] = '\0';
149 :
150 0 : if (len == 0)
151 0 : continue;
152 :
153 : /* unquote */
154 0 : if (val[0] == '"' || val[0] == '\'') {
155 0 : if (val[len-1] != val[0]) {
156 0 : log_debug("/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.", line_nr);
157 0 : continue;
158 : }
159 0 : val[len-1] = '\0';
160 0 : val++;
161 : }
162 :
163 0 : if (streq(key, "udev_log")) {
164 : int prio;
165 :
166 0 : prio = util_log_priority(val);
167 0 : if (prio < 0)
168 0 : log_debug("/etc/udev/udev.conf:%u: invalid log level '%s', ignoring.", line_nr, val);
169 : else
170 0 : log_set_max_level(prio);
171 0 : continue;
172 : }
173 : }
174 : }
175 :
176 18 : return udev;
177 : }
178 :
179 : /**
180 : * udev_ref:
181 : * @udev: udev library context
182 : *
183 : * Take a reference of the udev library context.
184 : *
185 : * Returns: the passed udev library context
186 : **/
187 0 : _public_ struct udev *udev_ref(struct udev *udev) {
188 0 : if (udev == NULL)
189 0 : return NULL;
190 0 : udev->refcount++;
191 0 : return udev;
192 : }
193 :
194 : /**
195 : * udev_unref:
196 : * @udev: udev library context
197 : *
198 : * Drop a reference of the udev library context. If the refcount
199 : * reaches zero, the resources of the context will be released.
200 : *
201 : * Returns: the passed udev library context if it has still an active reference, or #NULL otherwise.
202 : **/
203 18 : _public_ struct udev *udev_unref(struct udev *udev) {
204 18 : if (udev == NULL)
205 0 : return NULL;
206 18 : udev->refcount--;
207 18 : if (udev->refcount > 0)
208 0 : return udev;
209 18 : free(udev);
210 18 : return NULL;
211 : }
212 :
213 : /**
214 : * udev_set_log_fn:
215 : * @udev: udev library context
216 : * @log_fn: function to be called for log messages
217 : *
218 : * This function is deprecated.
219 : *
220 : **/
221 0 : _public_ void udev_set_log_fn(struct udev *udev,
222 : void (*log_fn)(struct udev *udev,
223 : int priority, const char *file, int line, const char *fn,
224 : const char *format, va_list args)) {
225 0 : return;
226 : }
227 :
228 : /**
229 : * udev_get_log_priority:
230 : * @udev: udev library context
231 : *
232 : * This function is deprecated.
233 : *
234 : **/
235 0 : _public_ int udev_get_log_priority(struct udev *udev) {
236 0 : return log_get_max_level();
237 : }
238 :
239 : /**
240 : * udev_set_log_priority:
241 : * @udev: udev library context
242 : * @priority: the new log priority
243 : *
244 : * This function is deprecated.
245 : *
246 : **/
247 0 : _public_ void udev_set_log_priority(struct udev *udev, int priority) {
248 0 : log_set_max_level(priority);
249 0 : }
|