17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier #include <ctype.h>
57dd7cddfSDavid du Colombier #include <ndb.h>
67dd7cddfSDavid du Colombier #include "ndbhf.h"
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier static Ndb* doopen(char*);
97dd7cddfSDavid du Colombier static void hffree(Ndb*);
107dd7cddfSDavid du Colombier
117dd7cddfSDavid du Colombier static char *deffile = "/lib/ndb/local";
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier /*
147dd7cddfSDavid du Colombier * the database entry in 'file' indicates the list of files
157dd7cddfSDavid du Colombier * that makeup the database. Open each one and search in
167dd7cddfSDavid du Colombier * the same order.
177dd7cddfSDavid du Colombier */
187dd7cddfSDavid du Colombier Ndb*
ndbopen(char * file)197dd7cddfSDavid du Colombier ndbopen(char *file)
207dd7cddfSDavid du Colombier {
217dd7cddfSDavid du Colombier Ndb *db, *first, *last;
227dd7cddfSDavid du Colombier Ndbs s;
237dd7cddfSDavid du Colombier Ndbtuple *t, *nt;
247dd7cddfSDavid du Colombier
25*853458f3SDavid du Colombier if(file == nil && (file = getenv("NDBFILE")) == nil)
267dd7cddfSDavid du Colombier file = deffile;
277dd7cddfSDavid du Colombier db = doopen(file);
287dd7cddfSDavid du Colombier if(db == 0)
297dd7cddfSDavid du Colombier return 0;
307dd7cddfSDavid du Colombier first = last = db;
317dd7cddfSDavid du Colombier t = ndbsearch(db, &s, "database", "");
327dd7cddfSDavid du Colombier Bseek(&db->b, 0, 0);
337dd7cddfSDavid du Colombier if(t == 0)
347dd7cddfSDavid du Colombier return db;
357dd7cddfSDavid du Colombier for(nt = t; nt; nt = nt->entry){
367dd7cddfSDavid du Colombier if(strcmp(nt->attr, "file") != 0)
377dd7cddfSDavid du Colombier continue;
387dd7cddfSDavid du Colombier if(strcmp(nt->val, file) == 0){
397dd7cddfSDavid du Colombier /* default file can be reordered in the list */
407dd7cddfSDavid du Colombier if(first->next == 0)
417dd7cddfSDavid du Colombier continue;
427dd7cddfSDavid du Colombier if(strcmp(first->file, file) == 0){
437dd7cddfSDavid du Colombier db = first;
447dd7cddfSDavid du Colombier first = first->next;
457dd7cddfSDavid du Colombier last->next = db;
467dd7cddfSDavid du Colombier db->next = 0;
477dd7cddfSDavid du Colombier last = db;
487dd7cddfSDavid du Colombier }
497dd7cddfSDavid du Colombier continue;
507dd7cddfSDavid du Colombier }
517dd7cddfSDavid du Colombier db = doopen(nt->val);
527dd7cddfSDavid du Colombier if(db == 0)
537dd7cddfSDavid du Colombier continue;
547dd7cddfSDavid du Colombier last->next = db;
557dd7cddfSDavid du Colombier last = db;
567dd7cddfSDavid du Colombier }
57a9f680aeSDavid du Colombier ndbfree(t);
587dd7cddfSDavid du Colombier return first;
597dd7cddfSDavid du Colombier }
607dd7cddfSDavid du Colombier
617dd7cddfSDavid du Colombier /*
627dd7cddfSDavid du Colombier * open a single file
637dd7cddfSDavid du Colombier */
647dd7cddfSDavid du Colombier static Ndb*
doopen(char * file)657dd7cddfSDavid du Colombier doopen(char *file)
667dd7cddfSDavid du Colombier {
677dd7cddfSDavid du Colombier Ndb *db;
687dd7cddfSDavid du Colombier
697dd7cddfSDavid du Colombier db = (Ndb*)malloc(sizeof(Ndb));
707dd7cddfSDavid du Colombier if(db == 0)
717dd7cddfSDavid du Colombier return 0;
727dd7cddfSDavid du Colombier memset(db, 0, sizeof(Ndb));
737dd7cddfSDavid du Colombier strncpy(db->file, file, sizeof(db->file)-1);
747dd7cddfSDavid du Colombier
757dd7cddfSDavid du Colombier if(ndbreopen(db) < 0){
767dd7cddfSDavid du Colombier free(db);
777dd7cddfSDavid du Colombier return 0;
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier return db;
817dd7cddfSDavid du Colombier }
827dd7cddfSDavid du Colombier
837dd7cddfSDavid du Colombier /*
847dd7cddfSDavid du Colombier * dump any cached information, forget the hash tables, and reopen a single file
857dd7cddfSDavid du Colombier */
867dd7cddfSDavid du Colombier int
ndbreopen(Ndb * db)877dd7cddfSDavid du Colombier ndbreopen(Ndb *db)
887dd7cddfSDavid du Colombier {
897dd7cddfSDavid du Colombier int fd;
909a747e4fSDavid du Colombier Dir *d;
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier /* forget what we know about the open files */
937dd7cddfSDavid du Colombier if(db->mtime){
949a747e4fSDavid du Colombier _ndbcacheflush(db);
957dd7cddfSDavid du Colombier hffree(db);
967dd7cddfSDavid du Colombier close(Bfildes(&db->b));
977dd7cddfSDavid du Colombier Bterm(&db->b);
987dd7cddfSDavid du Colombier db->mtime = 0;
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier
1017dd7cddfSDavid du Colombier /* try the open again */
1027dd7cddfSDavid du Colombier fd = open(db->file, OREAD);
1037dd7cddfSDavid du Colombier if(fd < 0)
1047dd7cddfSDavid du Colombier return -1;
1059a747e4fSDavid du Colombier d = dirfstat(fd);
1069a747e4fSDavid du Colombier if(d == nil){
1077dd7cddfSDavid du Colombier close(fd);
1087dd7cddfSDavid du Colombier return -1;
1097dd7cddfSDavid du Colombier }
1107dd7cddfSDavid du Colombier
1119a747e4fSDavid du Colombier db->qid = d->qid;
1129a747e4fSDavid du Colombier db->mtime = d->mtime;
1139a747e4fSDavid du Colombier db->length = d->length;
1147dd7cddfSDavid du Colombier Binits(&db->b, fd, OREAD, db->buf, sizeof(db->buf));
1159a747e4fSDavid du Colombier free(d);
1167dd7cddfSDavid du Colombier return 0;
1177dd7cddfSDavid du Colombier }
1187dd7cddfSDavid du Colombier
1197dd7cddfSDavid du Colombier /*
1207dd7cddfSDavid du Colombier * close the database files
1217dd7cddfSDavid du Colombier */
1227dd7cddfSDavid du Colombier void
ndbclose(Ndb * db)1237dd7cddfSDavid du Colombier ndbclose(Ndb *db)
1247dd7cddfSDavid du Colombier {
1257dd7cddfSDavid du Colombier Ndb *nextdb;
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier for(; db; db = nextdb){
1287dd7cddfSDavid du Colombier nextdb = db->next;
1299a747e4fSDavid du Colombier _ndbcacheflush(db);
1307dd7cddfSDavid du Colombier hffree(db);
1317dd7cddfSDavid du Colombier close(Bfildes(&db->b));
1327dd7cddfSDavid du Colombier Bterm(&db->b);
1337dd7cddfSDavid du Colombier free(db);
1347dd7cddfSDavid du Colombier }
1357dd7cddfSDavid du Colombier }
1367dd7cddfSDavid du Colombier
1377dd7cddfSDavid du Colombier /*
1387dd7cddfSDavid du Colombier * free the hash files belonging to a db
1397dd7cddfSDavid du Colombier */
1407dd7cddfSDavid du Colombier static void
hffree(Ndb * db)1417dd7cddfSDavid du Colombier hffree(Ndb *db)
1427dd7cddfSDavid du Colombier {
1437dd7cddfSDavid du Colombier Ndbhf *hf, *next;
1447dd7cddfSDavid du Colombier
1457dd7cddfSDavid du Colombier for(hf = db->hf; hf; hf = next){
1467dd7cddfSDavid du Colombier next = hf->next;
1477dd7cddfSDavid du Colombier close(hf->fd);
1487dd7cddfSDavid du Colombier free(hf);
1497dd7cddfSDavid du Colombier }
1507dd7cddfSDavid du Colombier db->hf = 0;
1517dd7cddfSDavid du Colombier }
1523ff48bf5SDavid du Colombier
1533ff48bf5SDavid du Colombier /*
1543ff48bf5SDavid du Colombier * return true if any part of the database has changed
1553ff48bf5SDavid du Colombier */
1563ff48bf5SDavid du Colombier int
ndbchanged(Ndb * db)1573ff48bf5SDavid du Colombier ndbchanged(Ndb *db)
1583ff48bf5SDavid du Colombier {
1593ff48bf5SDavid du Colombier Ndb *ndb;
1603ff48bf5SDavid du Colombier Dir *d;
1613ff48bf5SDavid du Colombier
1623ff48bf5SDavid du Colombier for(ndb = db; ndb != nil; ndb = ndb->next){
1636b0d5c8bSDavid du Colombier d = dirfstat(Bfildes(&ndb->b));
1643ff48bf5SDavid du Colombier if(d == nil)
1653ff48bf5SDavid du Colombier continue;
1663ff48bf5SDavid du Colombier if(ndb->qid.path != d->qid.path
1673ff48bf5SDavid du Colombier || ndb->qid.vers != d->qid.vers){
1683ff48bf5SDavid du Colombier free(d);
1693ff48bf5SDavid du Colombier return 1;
1703ff48bf5SDavid du Colombier }
1713ff48bf5SDavid du Colombier free(d);
1723ff48bf5SDavid du Colombier }
1733ff48bf5SDavid du Colombier return 0;
1743ff48bf5SDavid du Colombier }
175