chiark / gitweb /
b200f2f6edffd02853fa0b65609261b03418d56c
[elogind.git] / udevdb.c
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
14 static TDB_CONTEXT *busdb;
15 static TDB_CONTEXT *classdb;
16 static TDB_CONTEXT *namedb;
17
18 /**
19  * busdb_record - bus and id are keys to look up name of device
20  */
21 struct 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  */
29 struct classdb_record {
30         char name[NAME_SIZE];
31 };
32
33 /**
34  * namedb_record - device name is key, remaining udevice info stored here.
35  */
36 struct 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  */
52 static 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  */
63 static 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  */
74 static 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  */
85 static 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  */
96 static 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  */
107 static 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  */
118 static 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  */
160 static 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  */
203 static 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  */
244 static 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  */
279 static 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  */
314 static 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  */
356 static 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  */
387 static 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  */
418 static 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  */
447 static 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  */
476 int 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  */
498 int 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  */
516 struct 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  */
553 struct 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  */
574 struct 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 }