diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/replica/db.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/replica/db.c')
-rwxr-xr-x | sys/src/cmd/replica/db.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/sys/src/cmd/replica/db.c b/sys/src/cmd/replica/db.c new file mode 100755 index 000000000..29e6b0a39 --- /dev/null +++ b/sys/src/cmd/replica/db.c @@ -0,0 +1,179 @@ +#include "all.h" + +static Entry *fe; + +static Entry* +allocentry(void) +{ + int i; + Entry *e; + + if(fe == nil){ + fe = emalloc(128*sizeof(Entry)); + for(i=0; i<128-1; i++) + fe[i].name = (char*)&fe[i+1]; + fe[i].name = nil; + } + + e = fe; + fe = (Entry*)e->name; + memset(e, 0, sizeof *e); + return e; +} + +static void +freeentry(Entry *e) +{ + e->name = (char*)fe; + fe = e; +} + +static void +_removedb(Db *db, char *name) +{ + Entry *e, k; + + memset(&k, 0, sizeof k); + k.name = name; + e = nil; + deleteavl(db->avl, (Avl*)&k, (Avl**)&e); + if(e) + freeentry(e); +} + +static void +_insertdb(Db *db, Entry *e) +{ + Entry *o, *ne; + + ne = allocentry(); + *ne = *e; + o = nil; + insertavl(db->avl, (Avl*)ne, (Avl**)&o); + if(o) + freeentry(o); +} + +static int +entrycmp(Avl *a, Avl *b) +{ + Entry *ea, *eb; + + ea = (Entry*)a; + eb = (Entry*)b; + return strcmp(ea->name, eb->name); +} + +Db* +opendb(char *file) +{ + char *f[10], *s, *t; + int i, fd, nf; + Biobuf b; + Db *db; + Entry e; + + if(file == nil) + fd = -1; + else if((fd = open(file, ORDWR)) < 0) + sysfatal("opendb %s: %r", file); + db = emalloc(sizeof(Db)); + db->avl = mkavltree(entrycmp); + db->fd = fd; + if(fd < 0) + return db; + Binit(&b, fd, OREAD); + i = 0; + for(; s=Brdstr(&b, '\n', 1); free(s)){ + t = estrdup(s); + nf = tokenize(s, f, nelem(f)); + if(nf != 7) + sysfatal("bad database entry '%s'", t); + free(t); + if(strcmp(f[2], "REMOVED") == 0) + _removedb(db, f[0]); + else{ + memset(&e, 0, sizeof e); + e.name = atom(f[0]); + e.d.name = atom(f[1]); + if(strcmp(e.d.name, "-")==0) + e.d.name = e.name; + e.d.mode = strtoul(f[2], 0, 8); + e.d.uid = atom(f[3]); + e.d.gid = atom(f[4]); + e.d.mtime = strtoul(f[5], 0, 10); + e.d.length = strtoll(f[6], 0, 10); + _insertdb(db, &e); + i++; + } + } + return db; +} + +static int +_finddb(Db *db, char *name, Dir *d, int domark) +{ + Entry *e, k; + + memset(&k, 0, sizeof k); + k.name = name; + + e = (Entry*)lookupavl(db->avl, (Avl*)&k); + if(e == nil) + return -1; + memset(d, 0, sizeof *d); + d->name = e->d.name; + d->uid = e->d.uid; + d->gid = e->d.gid; + d->mtime = e->d.mtime; + d->mode = e->d.mode; + d->length = e->d.length; + if(domark) + e->d.mark = 1; + return 0; +} + +int +finddb(Db *db, char *name, Dir *d) +{ + return _finddb(db, name, d, 0); +} + +int +markdb(Db *db, char *name, Dir *d) +{ + return _finddb(db, name, d, 1); +} + +void +removedb(Db *db, char *name) +{ + if(db->fd>=0 && fprint(db->fd, "%q xxx REMOVED xxx xxx 0 0\n", name) < 0) + sysfatal("appending to db: %r"); + _removedb(db, name); +} + +void +insertdb(Db *db, char *name, Dir *d) +{ + char *dname; + Entry e; + + memset(&e, 0, sizeof e); + e.name = atom(name); + e.d.name = atom(d->name); + e.d.uid = atom(d->uid); + e.d.gid = atom(d->gid); + e.d.mtime = d->mtime; + e.d.mode = d->mode; + e.d.length = d->length; + e.d.mark = d->muid!=0; + + dname = d->name; + if(strcmp(name, dname) == 0) + dname = "-"; + 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) + sysfatal("appending to db: %r"); + _insertdb(db, &e); +} + |