8 static Ndb* doopen(char*, char*);
9 static void hffree(Ndb*);
11 static char *deffile = "#9/ndb/local";
14 * the database entry in 'file' indicates the list of files
15 * that makeup the database. Open each one and search in
21 Ndb *db, *first, *last;
26 file = unsharp(deffile);
27 db = doopen(file, nil);
31 t = ndbsearch(db, &s, "database", "");
35 for(nt = t; nt; nt = nt->entry){
36 if(strcmp(nt->attr, "file") != 0)
38 if(strcmp(nt->val, file) == 0){
39 /* default file can be reordered in the list */
42 if(strcmp(first->file, file) == 0){
51 db = doopen(nt->val, file);
65 doopen(char *file, char *rel)
70 db = (Ndb*)malloc(sizeof(Ndb));
74 memset(db, 0, sizeof(Ndb));
76 * Rooted paths are taken as is.
77 * Unrooted paths are taken relative to db we opened.
79 if(file[0]!='/' && rel && (p=strrchr(rel, '/'))!=nil)
80 snprint(db->file, sizeof(db->file), "%.*s/%s",
81 utfnlen(rel, p-rel), rel, file);
83 strncpy(db->file, file, sizeof(db->file)-1);
85 if(ndbreopen(db) < 0){
94 * dump any cached information, forget the hash tables, and reopen a single file
102 /* forget what we know about the open files */
106 close(Bfildes(&db->b));
111 /* try the open again */
112 fd = open(db->file, OREAD);
122 db->mtime = d->mtime;
123 db->length = d->length;
124 Binit(&db->b, fd, OREAD);
130 * close the database files
137 for(; db; db = nextdb){
141 close(Bfildes(&db->b));
148 * free the hash files belonging to a db
155 for(hf = db->hf; hf; hf = next){
164 * return true if any part of the database has changed
172 for(ndb = db; ndb != nil; ndb = ndb->next){
173 d = dirfstat(Bfildes(&db->b));
176 if(ndb->qid.path != d->qid.path
177 || ndb->qid.vers != d->qid.vers){