Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ctype.h>
5 #include <ndb.h>
6 #include "ndbhf.h"
8 static Ndb* doopen(char*);
9 static void hffree(Ndb*);
11 static char *deffile = "/lib/ndb/local";
13 /*
14 * the database entry in 'file' indicates the list of files
15 * that makeup the database. Open each one and search in
16 * the same order.
17 */
18 Ndb*
19 ndbopen(char *file)
20 {
21 Ndb *db, *first, *last;
22 Ndbs s;
23 Ndbtuple *t, *nt;
25 if(file == 0)
26 file = deffile;
27 db = doopen(file);
28 if(db == 0)
29 return 0;
30 first = last = db;
31 t = ndbsearch(db, &s, "database", "");
32 Bseek(&db->b, 0, 0);
33 if(t == 0)
34 return db;
35 for(nt = t; nt; nt = nt->entry){
36 if(strcmp(nt->attr, "file") != 0)
37 continue;
38 if(strcmp(nt->val, file) == 0){
39 /* default file can be reordered in the list */
40 if(first->next == 0)
41 continue;
42 if(strcmp(first->file, file) == 0){
43 db = first;
44 first = first->next;
45 last->next = db;
46 db->next = 0;
47 last = db;
48 }
49 continue;
50 }
51 db = doopen(nt->val);
52 if(db == 0)
53 continue;
54 last->next = db;
55 last = db;
56 }
57 ndbfree(t);
58 return first;
59 }
61 /*
62 * open a single file
63 */
64 static Ndb*
65 doopen(char *file)
66 {
67 Ndb *db;
69 db = (Ndb*)malloc(sizeof(Ndb));
70 if(db == 0)
71 return 0;
72 memset(db, 0, sizeof(Ndb));
73 strncpy(db->file, file, sizeof(db->file)-1);
75 if(ndbreopen(db) < 0){
76 free(db);
77 return 0;
78 }
80 return db;
81 }
83 /*
84 * dump any cached information, forget the hash tables, and reopen a single file
85 */
86 int
87 ndbreopen(Ndb *db)
88 {
89 int fd;
90 Dir *d;
92 /* forget what we know about the open files */
93 if(db->mtime){
94 _ndbcacheflush(db);
95 hffree(db);
96 close(Bfildes(&db->b));
97 Bterm(&db->b);
98 db->mtime = 0;
99 }
101 /* try the open again */
102 fd = open(db->file, OREAD);
103 if(fd < 0)
104 return -1;
105 d = dirfstat(fd);
106 if(d == nil){
107 close(fd);
108 return -1;
111 db->qid = d->qid;
112 db->mtime = d->mtime;
113 db->length = d->length;
114 Binit(&db->b, fd, OREAD);
115 free(d);
116 return 0;
119 /*
120 * close the database files
121 */
122 void
123 ndbclose(Ndb *db)
125 Ndb *nextdb;
127 for(; db; db = nextdb){
128 nextdb = db->next;
129 _ndbcacheflush(db);
130 hffree(db);
131 close(Bfildes(&db->b));
132 Bterm(&db->b);
133 free(db);
137 /*
138 * free the hash files belonging to a db
139 */
140 static void
141 hffree(Ndb *db)
143 Ndbhf *hf, *next;
145 for(hf = db->hf; hf; hf = next){
146 next = hf->next;
147 close(hf->fd);
148 free(hf);
150 db->hf = 0;
153 /*
154 * return true if any part of the database has changed
155 */
156 int
157 ndbchanged(Ndb *db)
159 Ndb *ndb;
160 Dir *d;
162 for(ndb = db; ndb != nil; ndb = ndb->next){
163 d = dirfstat(Bfildes(&db->b));
164 if(d == nil)
165 continue;
166 if(ndb->qid.path != d->qid.path
167 || ndb->qid.vers != d->qid.vers){
168 free(d);
169 return 1;
171 free(d);
173 return 0;