Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "all.h"
2
 
3
static Entry *fe;
4
 
5
static Entry*
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
25
freeentry(Entry *e)
26
{
27
	e->name = (char*)fe;
28
	fe = e;
29
}
30
 
31
static void
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
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
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*
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
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
139
finddb(Db *db, char *name, Dir *d)
140
{
141
	return _finddb(db, name, d, 0);
142
}
143
 
144
int
145
markdb(Db *db, char *name, Dir *d)
146
{
147
	return _finddb(db, name, d, 1);
148
}
149
 
150
void
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
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