]> git.ipfire.org Git - thirdparty/systemd.git/blame - udevdb.c
[PATCH] udevdb prototype
[thirdparty/systemd.git] / udevdb.c
CommitLineData
8e41d35d
DS
1/*
2 * udev database library
3 */
4#include <stdlib.h>
5#include <stdio.h>
6#include <fcntl.h>
7#include <string.h>
8#include <sys/stat.h>
9#include <errno.h>
10
11#include "udevdb.h"
12#include "tdb.h"
13
14static TDB_CONTEXT *busdb;
15static TDB_CONTEXT *classdb;
16static TDB_CONTEXT *namedb;
17
18/**
19 * busdb_record - bus and id are keys to look up name of device
20 */
21struct busdb_record {
22 char name[NAME_SIZE];
23};
24
25/**
26 * classdb_record - class name and class device name used as keys to find
27 * device name.
28 */
29struct classdb_record {
30 char name[NAME_SIZE];
31};
32
33/**
34 * namedb_record - device name is key, remaining udevice info stored here.
35 */
36struct namedb_record {
37 char sysfs_path[PATH_SIZE];
38 char class_dev_name[NAME_SIZE];
39 char class_name[NAME_SIZE];
40 char bus[BUS_SIZE];
41 char id[ID_SIZE];
42 char driver[NAME_SIZE];
43 char type;
44 int major;
45 int minor;
46 int mode;
47};
48
49/**
50 * busdb_close: close busdb database
51 */
52static void busdb_close(void)
53{
54 if (busdb != NULL) {
55 tdb_close(busdb);
56 busdb = NULL;
57 }
58}
59
60/**
61 * classdb_close: close classdb database
62 */
63static void classdb_close(void)
64{
65 if (classdb != NULL) {
66 tdb_close(classdb);
67 classdb = NULL;
68 }
69}
70
71/**
72 * namedb_close: close name database
73 */
74static void namedb_close(void)
75{
76 if (namedb != NULL) {
77 tdb_close(namedb);
78 namedb = NULL;
79 }
80}
81
82/**
83 * busdb_open: open busdb's database
84 */
85static int busdb_open(void)
86{
87 busdb = tdb_open(BUS_DB, 0, 0, O_RDWR | O_CREAT, 0644);
88 if (busdb == NULL)
89 return -1;
90 return 0;
91}
92
93/**
94 * classdb_open: open classdb's database
95 */
96static int classdb_open(void)
97{
98 classdb = tdb_open(CLASS_DB, 0, 0, O_RDWR | O_CREAT, 0644);
99 if (classdb == NULL)
100 return -1;
101 return 0;
102}
103
104/**
105 * namedb_open: open name database
106 */
107static int namedb_open(void)
108{
109 namedb = tdb_open(NAME_DB, 0, 0, O_RDWR | O_CREAT, 0644);
110 if (namedb == NULL)
111 return -1;
112 return 0;
113}
114
115/**
116 * busdb_fetch
117 */
118static struct busdb_record *busdb_fetch(const char *bus, const char *id)
119{
120 TDB_DATA key, data;
121 char keystr[BUS_SIZE+ID_SIZE+2];
122 struct busdb_record *rec = NULL;
123
124 if (bus == NULL || id == NULL)
125 return NULL;
126 if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE)
127 return NULL;
128
129 if ((busdb_open()) != 0)
130 return NULL;
131
132 memset(keystr, 0, (BUS_SIZE+ID_SIZE+2));
133 strcpy(keystr, bus);
134 strcat(keystr, UDEVDB_DEL);
135 strcat(keystr, id);
136
137 key.dptr = (void *)keystr;
138 key.dsize = strlen(keystr) + 1;
139
140 data = tdb_fetch(busdb, key);
141 busdb_close();
142 if (data.dptr == NULL || data.dsize == 0)
143 return NULL;
144
145 rec = (struct busdb_record *)malloc(sizeof(struct busdb_record));
146 if (rec == NULL) {
147 free(data.dptr);
148 return NULL;
149 }
150
151 memcpy(rec, data.dptr, sizeof(struct busdb_record));
152 free(data.dptr);
153
154 return rec;
155}
156
157/**
158 * classdb_fetch
159 */
160static struct classdb_record *classdb_fetch(const char *cls,
161 const char *cls_dev)
162{
163 TDB_DATA key, data;
164 char keystr[NAME_SIZE+NAME_SIZE+2];
165 struct classdb_record *rec = NULL;
166
167 if (cls == NULL || cls_dev == NULL)
168 return NULL;
169 if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE)
170 return NULL;
171
172 if ((classdb_open()) != 0)
173 return NULL;
174
175 memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2));
176 strcpy(keystr, cls);
177 strcat(keystr, UDEVDB_DEL);
178 strcat(keystr, cls_dev);
179
180 key.dptr = (void *)keystr;
181 key.dsize = strlen(keystr) + 1;
182
183 data = tdb_fetch(classdb, key);
184 classdb_close();
185 if (data.dptr == NULL || data.dsize == 0)
186 return NULL;
187
188 rec = (struct classdb_record *)malloc(sizeof(struct classdb_record));
189 if (rec == NULL) {
190 free(data.dptr);
191 return NULL;
192 }
193
194 memcpy(rec, data.dptr, sizeof(struct classdb_record));
195 free(data.dptr);
196
197 return rec;
198}
199
200/**
201 * namedb_fetch
202 */
203static struct namedb_record *namedb_fetch(const char *name)
204{
205 TDB_DATA key, data;
206 char nm_keystr[NAME_SIZE];
207 struct namedb_record *nrec = NULL;
208
209 if (name == NULL)
210 return NULL;
211 if (strlen(name) >= NAME_SIZE)
212 return NULL;
213
214 if ((namedb_open()) != 0)
215 return NULL;
216
217 memset(nm_keystr, 0, NAME_SIZE);
218 strcpy(nm_keystr, name);
219
220 key.dptr = (void *)nm_keystr;
221 key.dsize = strlen(nm_keystr) + 1;
222
223 data = tdb_fetch(namedb, key);
224 namedb_close();
225
226 if (data.dptr == NULL || data.dsize == 0)
227 return NULL;
228
229 nrec = (struct namedb_record *)malloc(sizeof(struct namedb_record));
230 if (nrec == NULL) {
231 free(data.dptr);
232 return NULL;
233 }
234
235 memcpy(nrec, data.dptr, sizeof(struct namedb_record));
236 free(data.dptr);
237
238 return nrec;
239}
240
241/**
242 * busdb_store
243 */
244static int busdb_store(const struct udevice *dev)
245{
246 TDB_DATA key, data;
247 char keystr[BUS_SIZE+ID_SIZE+2];
248 struct busdb_record rec;
249 int retval = 0;
250
251 if (dev == NULL)
252 return -1;
253
254 if ((retval = busdb_open()) != 0)
255 return -1;
256
257 memset(keystr, 0, (BUS_SIZE+ID_SIZE+2));
258 strcpy(keystr, dev->bus_name);
259 strcat(keystr, UDEVDB_DEL);
260 strcat(keystr, dev->bus_id);
261
262 key.dptr = (void *)keystr;
263 key.dsize = strlen(keystr) + 1;
264
265 strcpy(rec.name, dev->name);
266
267 data.dptr = (void *) &rec;
268 data.dsize = sizeof(rec);
269
270 retval = tdb_store(busdb, key, data, TDB_REPLACE);
271
272 busdb_close();
273 return retval;
274}
275
276/**
277 * classdb_store
278 */
279static int classdb_store(const struct udevice *dev)
280{
281 TDB_DATA key, data;
282 char keystr[NAME_SIZE+NAME_SIZE+2];
283 struct classdb_record rec;
284 int retval = 0;
285
286 if (dev == NULL)
287 return -1;
288
289 if ((retval = classdb_open()) != 0)
290 return -1;
291
292 memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2));
293 strcpy(keystr, dev->class_name);
294 strcat(keystr, UDEVDB_DEL);
295 strcat(keystr, dev->class_dev_name);
296
297 key.dptr = (void *)keystr;
298 key.dsize = strlen(keystr) + 1;
299
300 strcpy(rec.name, dev->name);
301
302 data.dptr = (void *) &rec;
303 data.dsize = sizeof(rec);
304
305 retval = tdb_store(classdb, key, data, TDB_REPLACE);
306
307 classdb_close();
308 return retval;
309}
310
311/**
312 * namedb_store
313 */
314static int namedb_store(const struct udevice *dev)
315{
316 TDB_DATA key, data;
317 char keystr[NAME_SIZE];
318 struct namedb_record rec;
319 int retval = 0;
320
321 if (dev == NULL)
322 return -1;
323
324 if ((retval = namedb_open()) != 0)
325 return -1;
326
327 memset(keystr, 0, NAME_SIZE);
328 strcpy(keystr, dev->name);
329
330 key.dptr = (void *)keystr;
331 key.dsize = strlen(keystr) + 1;
332
333 strcpy(rec.sysfs_path, dev->sysfs_path);
334 strcpy(rec.bus, dev->bus_name);
335 strcpy(rec.id, dev->bus_id);
336 strcpy(rec.class_dev_name, dev->class_dev_name);
337 strcpy(rec.class_name, dev->class_name);
338 strcpy(rec.driver, dev->driver);
339 rec.type = dev->type;
340 rec.major = dev->major;
341 rec.minor = dev->minor;
342 rec.mode = dev->mode;
343
344 data.dptr = (void *) &rec;
345 data.dsize = sizeof(rec);
346
347 retval = tdb_store(namedb, key, data, TDB_REPLACE);
348
349 namedb_close();
350 return retval;
351}
352
353/**
354 * busdb_delete
355 */
356static int busdb_delete(const char *bus, const char *id)
357{
358 TDB_DATA key;
359 char keystr[BUS_SIZE+ID_SIZE+2];
360 int retval = 0;
361
362 if (bus == NULL || id == NULL)
363 return -1;
364 if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE)
365 return -1;
366
367 if ((busdb_open()) != 0)
368 return -1;
369
370 memset(keystr, 0, (BUS_SIZE+ID_SIZE+2));
371 strcpy(keystr, bus);
372 strcat(keystr, UDEVDB_DEL);
373 strcat(keystr, id);
374
375 key.dptr = (void *)keystr;
376 key.dsize = strlen(keystr) + 1;
377
378 retval = tdb_delete(busdb, key);
379 busdb_close();
380
381 return retval;
382}
383
384/**
385 * classdb_delete
386 */
387static int classdb_delete(const char *cls, const char *cls_dev)
388{
389 TDB_DATA key;
390 char keystr[NAME_SIZE+NAME_SIZE+2];
391 int retval = 0;
392
393 if (cls == NULL || cls_dev == NULL)
394 return -1;
395 if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE)
396 return -1;
397
398 if ((classdb_open()) != 0)
399 return -1;
400
401 memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2));
402 strcpy(keystr, cls);
403 strcat(keystr, UDEVDB_DEL);
404 strcat(keystr, cls_dev);
405
406 key.dptr = (void *)keystr;
407 key.dsize = strlen(keystr) + 1;
408
409 retval = tdb_delete(classdb, key);
410 classdb_close();
411
412 return retval;
413}
414
415/**
416 * namedb_delete
417 */
418static int namedb_delete(const char *name)
419{
420 TDB_DATA key;
421 char keystr[NAME_SIZE];
422 int retval = 0;
423
424 if (name == NULL)
425 return -1;
426 if (strlen(name) >= NAME_SIZE)
427 return -1;
428
429 if ((namedb_open()) != 0)
430 return -1;
431
432 memset(keystr, 0, NAME_SIZE);
433 strcpy(keystr, name);
434
435 key.dptr = (void *)keystr;
436 key.dsize = strlen(keystr) + 1;
437
438 retval = tdb_delete(namedb, key);
439 namedb_close();
440
441 return retval;
442}
443
444/**
445 * namedb_exists
446 */
447static int namedb_exists(const char *name)
448{
449 TDB_DATA key;
450 char keystr[NAME_SIZE];
451 int retval = 0;
452
453 if (name == NULL)
454 return retval;
455 if (strlen(name) >= NAME_SIZE)
456 return retval;
457
458 if ((namedb_open()) != 0)
459 return retval;
460
461 memset(keystr, 0, NAME_SIZE);
462 strcpy(keystr, name);
463
464 key.dptr = (void *)keystr;
465 key.dsize = strlen(keystr) + 1;
466
467 retval = tdb_exists(namedb, key);
468 namedb_close();
469
470 return retval;
471}
472
473/**
474 * udevdb_delete_udevice
475 */
476int udevdb_delete_udevice(const char *name)
477{
478 struct namedb_record *nrec = NULL;
479
480 if (name == NULL)
481 return -1;
482
483 nrec = namedb_fetch(name);
484 if (nrec == NULL)
485 return -1;
486
487 busdb_delete(nrec->bus, nrec->id);
488 classdb_delete(nrec->class_name, nrec->class_dev_name);
489 namedb_delete(name);
490 free(nrec);
491
492 return 0;
493}
494
495/**
496 * udevdb_add_udevice: adds udevice to database
497 */
498int udevdb_add_udevice(const struct udevice *dev)
499{
500 if (dev == NULL)
501 return -1;
502
503 if ((busdb_store(dev)) != 0)
504 return -1;
505 if ((classdb_store(dev)) != 0)
506 return -1;
507 if ((namedb_store(dev)) != 0)
508 return -1;
509
510 return 0;
511}
512
513/**
514 * udevdb_get_device: grab's device by name
515 */
516struct udevice *udevdb_get_udevice(const char *name)
517{
518 struct namedb_record *nrec = NULL;
519 struct udevice *dev = NULL;
520
521 if (name == NULL)
522 return NULL;
523
524 nrec = namedb_fetch(name);
525 if (nrec == NULL)
526 return NULL;
527
528 dev = (struct udevice *)malloc(sizeof(struct udevice));
529 if (dev == NULL) {
530 free(nrec);
531 return NULL;
532 }
533
534 strcpy(dev->name, name);
535 strcpy(dev->sysfs_path, nrec->sysfs_path);
536 strcpy(dev->class_dev_name, nrec->class_dev_name);
537 strcpy(dev->class_name, nrec->class_name);
538 strcpy(dev->bus_name, nrec->bus);
539 strcpy(dev->bus_id, nrec->id);
540 dev->type = nrec->type;
541 dev->major = nrec->major;
542 dev->minor = nrec->minor;
543 dev->mode = nrec->mode;
544
545 free(nrec);
546
547 return dev;
548}
549
550/**
551 * udevdb_get_device_by_bus
552 */
553struct udevice *udevdb_get_udevice_by_bus(const char *bus, const char *id)
554{
555 struct busdb_record *brec = NULL;
556 struct udevice *dev = NULL;
557
558 if (bus == NULL || id == NULL)
559 return NULL;
560
561 brec = busdb_fetch(bus, id);
562 if (brec == NULL)
563 return NULL;
564
565 dev = udevdb_get_udevice(brec->name);
566 free(brec);
567
568 return dev;
569}
570
571/**
572 * udevdb_get_udevice_by_class
573 */
574struct udevice *udevdb_get_udevice_by_class(const char *cls,
575 const char *cls_dev)
576{
577 struct classdb_record *crec = NULL;
578 struct udevice *dev = NULL;
579
580 if (cls == NULL || cls_dev == NULL)
581 return NULL;
582
583 crec = classdb_fetch(cls, cls_dev);
584 if (crec == NULL)
585 return NULL;
586
587 dev = udevdb_get_udevice(crec->name);
588 free(crec);
589
590 return dev;
591}