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