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