]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libudev/libudev.c
Merge pull request #1691 from poettering/util-lib-3
[thirdparty/systemd.git] / src / libudev / libudev.c
CommitLineData
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
07630cea
LP
20#include <ctype.h>
21#include <stdarg.h>
22#include <stddef.h>
33a5cc29
KS
23#include <stdio.h>
24#include <stdlib.h>
33a5cc29 25#include <string.h>
33a5cc29
KS
26
27#include "libudev.h"
07630cea 28
b5efdb8a 29#include "alloc-util.h"
3ffd4af2 30#include "fd-util.h"
33a5cc29 31#include "libudev-private.h"
4db17f29 32#include "missing.h"
07630cea 33#include "string-util.h"
33a5cc29 34
ce1d6d7f
KS
35/**
36 * SECTION:libudev
37 * @short_description: libudev context
38 *
39 * The context contains the default values read from the udev config file,
40 * and is passed to all library operations.
41 */
42
1e511322
KS
43/**
44 * udev:
45 *
ce1d6d7f 46 * Opaque object representing the library context.
1e511322 47 */
ba6929f6 48struct udev {
912541b0
KS
49 int refcount;
50 void (*log_fn)(struct udev *udev,
51 int priority, const char *file, int line, const char *fn,
52 const char *format, va_list args);
53 void *userdata;
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 103
ff944daa 104 f = fopen("/etc/udev/udev.conf", "re");
912541b0
KS
105 if (f != NULL) {
106 char line[UTIL_LINE_SIZE];
fe756ed9 107 unsigned line_nr = 0;
912541b0
KS
108
109 while (fgets(line, sizeof(line), f)) {
110 size_t len;
111 char *key;
112 char *val;
113
114 line_nr++;
115
116 /* find key */
117 key = line;
118 while (isspace(key[0]))
119 key++;
120
121 /* comment or empty line */
122 if (key[0] == '#' || key[0] == '\0')
123 continue;
124
125 /* split key/value */
126 val = strchr(key, '=');
127 if (val == NULL) {
ff49bc32 128 log_debug("/etc/udev/udev.conf:%u: missing assignment, skipping line.", line_nr);
912541b0
KS
129 continue;
130 }
131 val[0] = '\0';
132 val++;
133
134 /* find value */
135 while (isspace(val[0]))
136 val++;
137
138 /* terminate key */
139 len = strlen(key);
140 if (len == 0)
141 continue;
142 while (isspace(key[len-1]))
143 len--;
144 key[len] = '\0';
145
146 /* terminate value */
147 len = strlen(val);
148 if (len == 0)
149 continue;
150 while (isspace(val[len-1]))
151 len--;
152 val[len] = '\0';
153
154 if (len == 0)
155 continue;
156
157 /* unquote */
158 if (val[0] == '"' || val[0] == '\'') {
159 if (val[len-1] != val[0]) {
ff49bc32 160 log_debug("/etc/udev/udev.conf:%u: inconsistent quoting, skipping line.", line_nr);
912541b0
KS
161 continue;
162 }
163 val[len-1] = '\0';
164 val++;
165 }
166
090be865 167 if (streq(key, "udev_log")) {
ee7122c0
ZJS
168 int prio;
169
170 prio = util_log_priority(val);
171 if (prio < 0)
ff49bc32 172 log_debug("/etc/udev/udev.conf:%u: invalid log level '%s', ignoring.", line_nr, val);
ee7122c0 173 else
25e773ee 174 log_set_max_level(prio);
912541b0
KS
175 continue;
176 }
912541b0 177 }
912541b0
KS
178 }
179
912541b0 180 return udev;
33a5cc29
KS
181}
182
183/**
184 * udev_ref:
185 * @udev: udev library context
186 *
187 * Take a reference of the udev library context.
188 *
189 * Returns: the passed udev library context
190 **/
25e773ee 191_public_ struct udev *udev_ref(struct udev *udev) {
912541b0
KS
192 if (udev == NULL)
193 return NULL;
194 udev->refcount++;
195 return udev;
33a5cc29
KS
196}
197
198/**
199 * udev_unref:
200 * @udev: udev library context
201 *
202 * Drop a reference of the udev library context. If the refcount
be7de409 203 * reaches zero, the resources of the context will be released.
33a5cc29 204 *
c1959569 205 * Returns: the passed udev library context if it has still an active reference, or #NULL otherwise.
33a5cc29 206 **/
25e773ee 207_public_ struct udev *udev_unref(struct udev *udev) {
912541b0 208 if (udev == NULL)
20bbd54f 209 return NULL;
912541b0
KS
210 udev->refcount--;
211 if (udev->refcount > 0)
20bbd54f 212 return udev;
912541b0 213 free(udev);
20bbd54f 214 return NULL;
33a5cc29
KS
215}
216
217/**
218 * udev_set_log_fn:
219 * @udev: udev library context
f47ad593 220 * @log_fn: function to be called for log messages
33a5cc29 221 *
25e773ee 222 * This function is deprecated.
33a5cc29
KS
223 *
224 **/
54cf0b7f 225_public_ void udev_set_log_fn(struct udev *udev,
912541b0
KS
226 void (*log_fn)(struct udev *udev,
227 int priority, const char *file, int line, const char *fn,
25e773ee
KS
228 const char *format, va_list args)) {
229 return;
7d563a17
KS
230}
231
1e511322
KS
232/**
233 * udev_get_log_priority:
234 * @udev: udev library context
235 *
25e773ee 236 * This function is deprecated.
1e511322 237 *
1e511322 238 **/
25e773ee
KS
239_public_ int udev_get_log_priority(struct udev *udev) {
240 return log_get_max_level();
7d563a17
KS
241}
242
1e511322
KS
243/**
244 * udev_set_log_priority:
245 * @udev: udev library context
f47ad593 246 * @priority: the new log priority
1e511322 247 *
25e773ee
KS
248 * This function is deprecated.
249 *
1e511322 250 **/
25e773ee
KS
251_public_ void udev_set_log_priority(struct udev *udev, int priority) {
252 log_set_max_level(priority);
7d563a17 253}