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