123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <ctype.h>
- #include <ndb.h>
- #include "ndbhf.h"
- static Ndb* doopen(char*);
- static void hffree(Ndb*);
- static char *deffile = "/lib/ndb/local";
- /*
- * the database entry in 'file' indicates the list of files
- * that makeup the database. Open each one and search in
- * the same order.
- */
- Ndb*
- ndbopen(char *file)
- {
- Ndb *db, *first, *last;
- Ndbs s;
- Ndbtuple *t, *nt;
- if(file == 0)
- file = deffile;
- db = doopen(file);
- if(db == 0)
- return 0;
- first = last = db;
- t = ndbsearch(db, &s, "database", "");
- Bseek(&db->b, 0, 0);
- if(t == 0)
- return db;
- for(nt = t; nt; nt = nt->entry){
- if(strcmp(nt->attr, "file") != 0)
- continue;
- if(strcmp(nt->val, file) == 0){
- /* default file can be reordered in the list */
- if(first->next == 0)
- continue;
- if(strcmp(first->file, file) == 0){
- db = first;
- first = first->next;
- last->next = db;
- db->next = 0;
- last = db;
- }
- continue;
- }
- db = doopen(nt->val);
- if(db == 0)
- continue;
- last->next = db;
- last = db;
- }
- return first;
- }
- /*
- * open a single file
- */
- static Ndb*
- doopen(char *file)
- {
- Ndb *db;
- db = (Ndb*)malloc(sizeof(Ndb));
- if(db == 0)
- return 0;
- memset(db, 0, sizeof(Ndb));
- strncpy(db->file, file, sizeof(db->file)-1);
- if(ndbreopen(db) < 0){
- free(db);
- return 0;
- }
- return db;
- }
- /*
- * dump any cached information, forget the hash tables, and reopen a single file
- */
- int
- ndbreopen(Ndb *db)
- {
- int fd;
- Dir *d;
- /* forget what we know about the open files */
- if(db->mtime){
- _ndbcacheflush(db);
- hffree(db);
- close(Bfildes(&db->b));
- Bterm(&db->b);
- db->mtime = 0;
- }
- /* try the open again */
- fd = open(db->file, OREAD);
- if(fd < 0)
- return -1;
- d = dirfstat(fd);
- if(d == nil){
- close(fd);
- return -1;
- }
- db->qid = d->qid;
- db->mtime = d->mtime;
- db->length = d->length;
- Binits(&db->b, fd, OREAD, db->buf, sizeof(db->buf));
- free(d);
- return 0;
- }
- /*
- * close the database files
- */
- void
- ndbclose(Ndb *db)
- {
- Ndb *nextdb;
- for(; db; db = nextdb){
- nextdb = db->next;
- _ndbcacheflush(db);
- hffree(db);
- close(Bfildes(&db->b));
- Bterm(&db->b);
- free(db);
- }
- }
- /*
- * free the hash files belonging to a db
- */
- static void
- hffree(Ndb *db)
- {
- Ndbhf *hf, *next;
- for(hf = db->hf; hf; hf = next){
- next = hf->next;
- close(hf->fd);
- free(hf);
- }
- db->hf = 0;
- }
- /*
- * return true if any part of the database has changed
- */
- int
- ndbchanged(Ndb *db)
- {
- Ndb *ndb;
- Dir *d;
- for(ndb = db; ndb != nil; ndb = ndb->next){
- d = dirfstat(Bfildes(&db->b));
- if(d == nil)
- continue;
- if(ndb->qid.path != d->qid.path
- || ndb->qid.vers != d->qid.vers){
- free(d);
- return 1;
- }
- free(d);
- }
- return 0;
- }
|