xref: /plan9/sys/src/libndb/ndbopen.c (revision 853458f38e7eb3a48cfa3a36aefdb799375e398a)
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