xref: /plan9/sys/src/cmd/replica/db.c (revision 853458f38e7eb3a48cfa3a36aefdb799375e398a)
19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier 
39a747e4fSDavid du Colombier static Entry *fe;
49a747e4fSDavid du Colombier 
59a747e4fSDavid du Colombier static Entry*
allocentry(void)69a747e4fSDavid du Colombier allocentry(void)
79a747e4fSDavid du Colombier {
89a747e4fSDavid du Colombier 	int i;
99a747e4fSDavid du Colombier 	Entry *e;
109a747e4fSDavid du Colombier 
119a747e4fSDavid du Colombier 	if(fe == nil){
129a747e4fSDavid du Colombier 		fe = emalloc(128*sizeof(Entry));
139a747e4fSDavid du Colombier 		for(i=0; i<128-1; i++)
149a747e4fSDavid du Colombier 			fe[i].name = (char*)&fe[i+1];
159a747e4fSDavid du Colombier 		fe[i].name = nil;
169a747e4fSDavid du Colombier 	}
179a747e4fSDavid du Colombier 
189a747e4fSDavid du Colombier 	e = fe;
199a747e4fSDavid du Colombier 	fe = (Entry*)e->name;
209a747e4fSDavid du Colombier 	memset(e, 0, sizeof *e);
219a747e4fSDavid du Colombier 	return e;
229a747e4fSDavid du Colombier }
239a747e4fSDavid du Colombier 
249a747e4fSDavid du Colombier static void
freeentry(Entry * e)259a747e4fSDavid du Colombier freeentry(Entry *e)
269a747e4fSDavid du Colombier {
279a747e4fSDavid du Colombier 	e->name = (char*)fe;
289a747e4fSDavid du Colombier 	fe = e;
299a747e4fSDavid du Colombier }
309a747e4fSDavid du Colombier 
319a747e4fSDavid du Colombier static void
_removedb(Db * db,char * name)329a747e4fSDavid du Colombier _removedb(Db *db, char *name)
339a747e4fSDavid du Colombier {
349a747e4fSDavid du Colombier 	Entry *e, k;
359a747e4fSDavid du Colombier 
369a747e4fSDavid du Colombier 	memset(&k, 0, sizeof k);
379a747e4fSDavid du Colombier 	k.name = name;
389a747e4fSDavid du Colombier 	e = nil;
399a747e4fSDavid du Colombier 	deleteavl(db->avl, (Avl*)&k, (Avl**)&e);
409a747e4fSDavid du Colombier 	if(e)
419a747e4fSDavid du Colombier 		freeentry(e);
429a747e4fSDavid du Colombier }
439a747e4fSDavid du Colombier 
449a747e4fSDavid du Colombier static void
_insertdb(Db * db,Entry * e)459a747e4fSDavid du Colombier _insertdb(Db *db, Entry *e)
469a747e4fSDavid du Colombier {
479a747e4fSDavid du Colombier 	Entry *o, *ne;
489a747e4fSDavid du Colombier 
499a747e4fSDavid du Colombier 	ne = allocentry();
509a747e4fSDavid du Colombier 	*ne = *e;
519a747e4fSDavid du Colombier 	o = nil;
529a747e4fSDavid du Colombier 	insertavl(db->avl, (Avl*)ne, (Avl**)&o);
539a747e4fSDavid du Colombier 	if(o)
549a747e4fSDavid du Colombier 		freeentry(o);
559a747e4fSDavid du Colombier }
569a747e4fSDavid du Colombier 
579a747e4fSDavid du Colombier static int
entrycmp(Avl * a,Avl * b)589a747e4fSDavid du Colombier entrycmp(Avl *a, Avl *b)
599a747e4fSDavid du Colombier {
609a747e4fSDavid du Colombier 	Entry *ea, *eb;
61*853458f3SDavid du Colombier 	int r;
629a747e4fSDavid du Colombier 
639a747e4fSDavid du Colombier 	ea = (Entry*)a;
649a747e4fSDavid du Colombier 	eb = (Entry*)b;
65*853458f3SDavid du Colombier 	r = strcmp(ea->name, eb->name);
66*853458f3SDavid du Colombier 	return r > 0 ? 1 : r < 0 ? -1 : 0;
679a747e4fSDavid du Colombier }
689a747e4fSDavid du Colombier 
699a747e4fSDavid du Colombier Db*
opendb(char * file)709a747e4fSDavid du Colombier opendb(char *file)
719a747e4fSDavid du Colombier {
729a747e4fSDavid du Colombier 	char *f[10], *s, *t;
739a747e4fSDavid du Colombier 	int i, fd, nf;
749a747e4fSDavid du Colombier 	Biobuf b;
759a747e4fSDavid du Colombier 	Db *db;
769a747e4fSDavid du Colombier 	Entry e;
779a747e4fSDavid du Colombier 
789a747e4fSDavid du Colombier 	if(file == nil)
799a747e4fSDavid du Colombier 		fd = -1;
809a747e4fSDavid du Colombier 	else if((fd = open(file, ORDWR)) < 0)
819a747e4fSDavid du Colombier 		sysfatal("opendb %s: %r", file);
829a747e4fSDavid du Colombier 	db = emalloc(sizeof(Db));
839a747e4fSDavid du Colombier 	db->avl = mkavltree(entrycmp);
849a747e4fSDavid du Colombier 	db->fd = fd;
859a747e4fSDavid du Colombier 	if(fd < 0)
869a747e4fSDavid du Colombier 		return db;
879a747e4fSDavid du Colombier 	Binit(&b, fd, OREAD);
889a747e4fSDavid du Colombier 	i = 0;
899a747e4fSDavid du Colombier 	for(; s=Brdstr(&b, '\n', 1); free(s)){
909a747e4fSDavid du Colombier 		t = estrdup(s);
919a747e4fSDavid du Colombier 		nf = tokenize(s, f, nelem(f));
929a747e4fSDavid du Colombier 		if(nf != 7)
939a747e4fSDavid du Colombier 			sysfatal("bad database entry '%s'", t);
949a747e4fSDavid du Colombier 		free(t);
959a747e4fSDavid du Colombier 		if(strcmp(f[2], "REMOVED") == 0)
969a747e4fSDavid du Colombier 			_removedb(db, f[0]);
979a747e4fSDavid du Colombier 		else{
989a747e4fSDavid du Colombier 			memset(&e, 0, sizeof e);
999a747e4fSDavid du Colombier 			e.name = atom(f[0]);
1009a747e4fSDavid du Colombier 			e.d.name = atom(f[1]);
1019a747e4fSDavid du Colombier 			if(strcmp(e.d.name, "-")==0)
1029a747e4fSDavid du Colombier 				e.d.name = e.name;
1039a747e4fSDavid du Colombier 			e.d.mode = strtoul(f[2], 0, 8);
1049a747e4fSDavid du Colombier 			e.d.uid = atom(f[3]);
1059a747e4fSDavid du Colombier 			e.d.gid = atom(f[4]);
1069a747e4fSDavid du Colombier 			e.d.mtime = strtoul(f[5], 0, 10);
1079a747e4fSDavid du Colombier 			e.d.length = strtoll(f[6], 0, 10);
1089a747e4fSDavid du Colombier 			_insertdb(db, &e);
1099a747e4fSDavid du Colombier 			i++;
1109a747e4fSDavid du Colombier 		}
1119a747e4fSDavid du Colombier 	}
1129a747e4fSDavid du Colombier 	return db;
1139a747e4fSDavid du Colombier }
1149a747e4fSDavid du Colombier 
1159a747e4fSDavid du Colombier static int
_finddb(Db * db,char * name,Dir * d,int domark)1169a747e4fSDavid du Colombier _finddb(Db *db, char *name, Dir *d, int domark)
1179a747e4fSDavid du Colombier {
1189a747e4fSDavid du Colombier 	Entry *e, k;
1199a747e4fSDavid du Colombier 
1209a747e4fSDavid du Colombier 	memset(&k, 0, sizeof k);
1219a747e4fSDavid du Colombier 	k.name = name;
1229a747e4fSDavid du Colombier 
1239a747e4fSDavid du Colombier 	e = (Entry*)lookupavl(db->avl, (Avl*)&k);
1249a747e4fSDavid du Colombier 	if(e == nil)
1259a747e4fSDavid du Colombier 		return -1;
1269a747e4fSDavid du Colombier 	memset(d, 0, sizeof *d);
1279a747e4fSDavid du Colombier 	d->name = e->d.name;
1289a747e4fSDavid du Colombier 	d->uid = e->d.uid;
1299a747e4fSDavid du Colombier 	d->gid = e->d.gid;
1309a747e4fSDavid du Colombier 	d->mtime = e->d.mtime;
1319a747e4fSDavid du Colombier 	d->mode = e->d.mode;
1329a747e4fSDavid du Colombier 	d->length = e->d.length;
1339a747e4fSDavid du Colombier 	if(domark)
1349a747e4fSDavid du Colombier 		e->d.mark = 1;
1359a747e4fSDavid du Colombier 	return 0;
1369a747e4fSDavid du Colombier }
1379a747e4fSDavid du Colombier 
1389a747e4fSDavid du Colombier int
finddb(Db * db,char * name,Dir * d)1399a747e4fSDavid du Colombier finddb(Db *db, char *name, Dir *d)
1409a747e4fSDavid du Colombier {
1419a747e4fSDavid du Colombier 	return _finddb(db, name, d, 0);
1429a747e4fSDavid du Colombier }
1439a747e4fSDavid du Colombier 
1449a747e4fSDavid du Colombier int
markdb(Db * db,char * name,Dir * d)1459a747e4fSDavid du Colombier markdb(Db *db, char *name, Dir *d)
1469a747e4fSDavid du Colombier {
1479a747e4fSDavid du Colombier 	return _finddb(db, name, d, 1);
1489a747e4fSDavid du Colombier }
1499a747e4fSDavid du Colombier 
1509a747e4fSDavid du Colombier void
removedb(Db * db,char * name)1519a747e4fSDavid du Colombier removedb(Db *db, char *name)
1529a747e4fSDavid du Colombier {
1539a747e4fSDavid du Colombier 	if(db->fd>=0 && fprint(db->fd, "%q xxx REMOVED xxx xxx 0 0\n", name) < 0)
1549a747e4fSDavid du Colombier 		sysfatal("appending to db: %r");
1559a747e4fSDavid du Colombier 	_removedb(db, name);
1569a747e4fSDavid du Colombier }
1579a747e4fSDavid du Colombier 
1589a747e4fSDavid du Colombier void
insertdb(Db * db,char * name,Dir * d)1599a747e4fSDavid du Colombier insertdb(Db *db, char *name, Dir *d)
1609a747e4fSDavid du Colombier {
1619a747e4fSDavid du Colombier 	char *dname;
1629a747e4fSDavid du Colombier 	Entry e;
1639a747e4fSDavid du Colombier 
1649a747e4fSDavid du Colombier 	memset(&e, 0, sizeof e);
1659a747e4fSDavid du Colombier 	e.name = atom(name);
1669a747e4fSDavid du Colombier 	e.d.name = atom(d->name);
1679a747e4fSDavid du Colombier 	e.d.uid = atom(d->uid);
1689a747e4fSDavid du Colombier 	e.d.gid = atom(d->gid);
1699a747e4fSDavid du Colombier 	e.d.mtime = d->mtime;
1709a747e4fSDavid du Colombier 	e.d.mode = d->mode;
1719a747e4fSDavid du Colombier 	e.d.length = d->length;
1729a747e4fSDavid du Colombier 	e.d.mark = d->muid!=0;
1739a747e4fSDavid du Colombier 
1749a747e4fSDavid du Colombier 	dname = d->name;
1759a747e4fSDavid du Colombier 	if(strcmp(name, dname) == 0)
1769a747e4fSDavid du Colombier 		dname = "-";
1779a747e4fSDavid du Colombier 	if(db->fd>=0 && fprint(db->fd, "%q %q %luo %q %q %lud %lld\n", name, dname, d->mode, d->uid, d->gid, d->mtime, d->length) < 0)
1789a747e4fSDavid du Colombier 		sysfatal("appending to db: %r");
1799a747e4fSDavid du Colombier 	_insertdb(db, &e);
1809a747e4fSDavid du Colombier }
1819a747e4fSDavid du Colombier 
182