xref: /plan9/sys/src/cmd/replica/db.c (revision 853458f38e7eb3a48cfa3a36aefdb799375e398a)
1 #include "all.h"
2 
3 static Entry *fe;
4 
5 static Entry*
allocentry(void)6 allocentry(void)
7 {
8 	int i;
9 	Entry *e;
10 
11 	if(fe == nil){
12 		fe = emalloc(128*sizeof(Entry));
13 		for(i=0; i<128-1; i++)
14 			fe[i].name = (char*)&fe[i+1];
15 		fe[i].name = nil;
16 	}
17 
18 	e = fe;
19 	fe = (Entry*)e->name;
20 	memset(e, 0, sizeof *e);
21 	return e;
22 }
23 
24 static void
freeentry(Entry * e)25 freeentry(Entry *e)
26 {
27 	e->name = (char*)fe;
28 	fe = e;
29 }
30 
31 static void
_removedb(Db * db,char * name)32 _removedb(Db *db, char *name)
33 {
34 	Entry *e, k;
35 
36 	memset(&k, 0, sizeof k);
37 	k.name = name;
38 	e = nil;
39 	deleteavl(db->avl, (Avl*)&k, (Avl**)&e);
40 	if(e)
41 		freeentry(e);
42 }
43 
44 static void
_insertdb(Db * db,Entry * e)45 _insertdb(Db *db, Entry *e)
46 {
47 	Entry *o, *ne;
48 
49 	ne = allocentry();
50 	*ne = *e;
51 	o = nil;
52 	insertavl(db->avl, (Avl*)ne, (Avl**)&o);
53 	if(o)
54 		freeentry(o);
55 }
56 
57 static int
entrycmp(Avl * a,Avl * b)58 entrycmp(Avl *a, Avl *b)
59 {
60 	Entry *ea, *eb;
61 	int r;
62 
63 	ea = (Entry*)a;
64 	eb = (Entry*)b;
65 	r = strcmp(ea->name, eb->name);
66 	return r > 0 ? 1 : r < 0 ? -1 : 0;
67 }
68 
69 Db*
opendb(char * file)70 opendb(char *file)
71 {
72 	char *f[10], *s, *t;
73 	int i, fd, nf;
74 	Biobuf b;
75 	Db *db;
76 	Entry e;
77 
78 	if(file == nil)
79 		fd = -1;
80 	else if((fd = open(file, ORDWR)) < 0)
81 		sysfatal("opendb %s: %r", file);
82 	db = emalloc(sizeof(Db));
83 	db->avl = mkavltree(entrycmp);
84 	db->fd = fd;
85 	if(fd < 0)
86 		return db;
87 	Binit(&b, fd, OREAD);
88 	i = 0;
89 	for(; s=Brdstr(&b, '\n', 1); free(s)){
90 		t = estrdup(s);
91 		nf = tokenize(s, f, nelem(f));
92 		if(nf != 7)
93 			sysfatal("bad database entry '%s'", t);
94 		free(t);
95 		if(strcmp(f[2], "REMOVED") == 0)
96 			_removedb(db, f[0]);
97 		else{
98 			memset(&e, 0, sizeof e);
99 			e.name = atom(f[0]);
100 			e.d.name = atom(f[1]);
101 			if(strcmp(e.d.name, "-")==0)
102 				e.d.name = e.name;
103 			e.d.mode = strtoul(f[2], 0, 8);
104 			e.d.uid = atom(f[3]);
105 			e.d.gid = atom(f[4]);
106 			e.d.mtime = strtoul(f[5], 0, 10);
107 			e.d.length = strtoll(f[6], 0, 10);
108 			_insertdb(db, &e);
109 			i++;
110 		}
111 	}
112 	return db;
113 }
114 
115 static int
_finddb(Db * db,char * name,Dir * d,int domark)116 _finddb(Db *db, char *name, Dir *d, int domark)
117 {
118 	Entry *e, k;
119 
120 	memset(&k, 0, sizeof k);
121 	k.name = name;
122 
123 	e = (Entry*)lookupavl(db->avl, (Avl*)&k);
124 	if(e == nil)
125 		return -1;
126 	memset(d, 0, sizeof *d);
127 	d->name = e->d.name;
128 	d->uid = e->d.uid;
129 	d->gid = e->d.gid;
130 	d->mtime = e->d.mtime;
131 	d->mode = e->d.mode;
132 	d->length = e->d.length;
133 	if(domark)
134 		e->d.mark = 1;
135 	return 0;
136 }
137 
138 int
finddb(Db * db,char * name,Dir * d)139 finddb(Db *db, char *name, Dir *d)
140 {
141 	return _finddb(db, name, d, 0);
142 }
143 
144 int
markdb(Db * db,char * name,Dir * d)145 markdb(Db *db, char *name, Dir *d)
146 {
147 	return _finddb(db, name, d, 1);
148 }
149 
150 void
removedb(Db * db,char * name)151 removedb(Db *db, char *name)
152 {
153 	if(db->fd>=0 && fprint(db->fd, "%q xxx REMOVED xxx xxx 0 0\n", name) < 0)
154 		sysfatal("appending to db: %r");
155 	_removedb(db, name);
156 }
157 
158 void
insertdb(Db * db,char * name,Dir * d)159 insertdb(Db *db, char *name, Dir *d)
160 {
161 	char *dname;
162 	Entry e;
163 
164 	memset(&e, 0, sizeof e);
165 	e.name = atom(name);
166 	e.d.name = atom(d->name);
167 	e.d.uid = atom(d->uid);
168 	e.d.gid = atom(d->gid);
169 	e.d.mtime = d->mtime;
170 	e.d.mode = d->mode;
171 	e.d.length = d->length;
172 	e.d.mark = d->muid!=0;
173 
174 	dname = d->name;
175 	if(strcmp(name, dname) == 0)
176 		dname = "-";
177 	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)
178 		sysfatal("appending to db: %r");
179 	_insertdb(db, &e);
180 }
181 
182