aboutsummaryrefslogtreecommitdiff
path: root/src/libndb/ndbopen.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-02-11 19:41:16 +0000
committerrsc <devnull@localhost>2005-02-11 19:41:16 +0000
commitd957951b75df08a9bb0293e3e13ff87759afbb92 (patch)
tree4d7868b0d223956217cbc8819d7afb3bec532cca /src/libndb/ndbopen.c
parentad017cfbf5530cfc3ae2fafd723cdade2a4405f6 (diff)
downloadplan9port-d957951b75df08a9bb0293e3e13ff87759afbb92.tar.gz
plan9port-d957951b75df08a9bb0293e3e13ff87759afbb92.tar.bz2
plan9port-d957951b75df08a9bb0293e3e13ff87759afbb92.zip
new
Diffstat (limited to 'src/libndb/ndbopen.c')
-rw-r--r--src/libndb/ndbopen.c174
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;
+}