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