#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 voidfreeentry(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 intentrycmp(Avl *a, Avl *b){ int n; Entry *ea, *eb; ea = (Entry*)a; eb = (Entry*)b; n = strcmp(ea->name, eb->name); if(n > 0) n = 1; else if(n < 0) n = -1; return n;} 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;} intfinddb(Db *db, char *name, Dir *d){ return _finddb(db, name, d, 0);} intmarkdb(Db *db, char *name, Dir *d){ return _finddb(db, name, d, 1);} voidremovedb(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);} voidinsertdb(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);}
#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)
{
int n;
Entry *ea, *eb;
ea = (Entry*)a;
eb = (Entry*)b;
n = strcmp(ea->name, eb->name);
if(n > 0)
n = 1;
else if(n < 0)
n = -1;
return n;
}
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);
}