diff options
author | rsc <devnull@localhost> | 2005-02-11 19:41:16 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-02-11 19:41:16 +0000 |
commit | d957951b75df08a9bb0293e3e13ff87759afbb92 (patch) | |
tree | 4d7868b0d223956217cbc8819d7afb3bec532cca /src/libndb/ndbopen.c | |
parent | ad017cfbf5530cfc3ae2fafd723cdade2a4405f6 (diff) | |
download | plan9port-d957951b75df08a9bb0293e3e13ff87759afbb92.tar.gz plan9port-d957951b75df08a9bb0293e3e13ff87759afbb92.tar.bz2 plan9port-d957951b75df08a9bb0293e3e13ff87759afbb92.zip |
new
Diffstat (limited to 'src/libndb/ndbopen.c')
-rw-r--r-- | src/libndb/ndbopen.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/libndb/ndbopen.c b/src/libndb/ndbopen.c new file mode 100644 index 00000000..d504702e --- /dev/null +++ b/src/libndb/ndbopen.c @@ -0,0 +1,174 @@ +#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; + } + ndbfree(t); + 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; + Binit(&db->b, fd, OREAD); + 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; +} |