From 64f7506b34106955fbbd5f6bf944ecd839610672 Mon Sep 17 00:00:00 2001 From: rsc Date: Fri, 24 Feb 2006 21:17:00 +0000 Subject: tapefs from plan9 --- src/cmd/tapefs/util.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/cmd/tapefs/util.c (limited to 'src/cmd/tapefs/util.c') diff --git a/src/cmd/tapefs/util.c b/src/cmd/tapefs/util.c new file mode 100644 index 00000000..199235f3 --- /dev/null +++ b/src/cmd/tapefs/util.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include "tapefs.h" + +Idmap * +getpass(char *file) +{ + Biobuf *bp; + char *cp; + Idmap *up; + int nid, maxid; + char *line[4]; + + if ((bp = Bopen(file, OREAD)) == 0) + error("Can't open passwd/group"); + up = emalloc(1*sizeof(Idmap)); + maxid = 1; + nid = 0; + while ((cp = Brdline(bp, '\n'))) { + int nf; + cp[Blinelen(bp)-1] = 0; + nf = getfields(cp, line, 3, 0, ":\n"); + if (nf<3) { + fprint(2, "bad format in %s\n", file); + break; + } + if (nid>=maxid) { + maxid *= 2; + up = (Idmap *)erealloc(up, maxid*sizeof(Idmap)); + } + up[nid].id = atoi(line[2]); + up[nid].name = strdup(line[0]); + nid++; + } + Bterm(bp); + up[nid].name = 0; + return up; +} + +char * +mapid(Idmap *up, int id) +{ + char buf[16]; + + if (up) + while (up->name){ + if (up->id==id) + return strdup(up->name); + up++; + } + sprint(buf, "%d", id); + return strdup(buf); +} + +Ram * +poppath(Fileinf fi, int new) +{ + char *suffix; + Ram *dir, *ent; + Fileinf f; + + if (*fi.name=='\0') + return 0; + if (suffix=strrchr(fi.name, '/')){ + *suffix = 0; + suffix++; + if (*suffix=='\0'){ + fi.mode |= DMDIR; + return poppath(fi, 1); + } + f = fi; + f.size = 0; + f.addr = 0; + f.mode = 0555|DMDIR; + dir = poppath(f, 0); + if (dir==0) + dir = ram; + } else { + suffix = fi.name; + dir = ram; + if (strcmp(suffix, ".")==0) + return dir; + } + ent = lookup(dir, suffix); + fi.mode |= 0400; /* at least user read */ + if (ent){ + if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){ + fprint(2, "%s/%s directory botch\n", fi.name, suffix); + exits(""); + } + if (new) { + ent->ndata = fi.size; + ent->addr = fi.addr; + ent->data = fi.data; + ent->perm = fi.mode; + ent->mtime = fi.mdate; + ent->user = mapid(uidmap, fi.uid); + ent->group = mapid(gidmap, fi.gid); + } + } else { + fi.name = suffix; + ent = popfile(dir, fi); + } + return ent; +} + +Ram * +popfile(Ram *dir, Fileinf fi) +{ + Ram *ent = (Ram *)emalloc(sizeof(Ram)); + if (*fi.name=='\0') + return 0; + ent->busy = 1; + ent->open = 0; + ent->parent = dir; + ent->next = dir->child; + dir->child = ent; + ent->child = 0; + ent->qid.path = ++path; + ent->qid.vers = 0; + if(fi.mode&DMDIR) + ent->qid.type = QTDIR; + else + ent->qid.type = QTFILE; + ent->perm = fi.mode; + ent->name = estrdup(fi.name); + ent->atime = ent->mtime = fi.mdate; + ent->user = mapid(uidmap, fi.uid); + ent->group = mapid(gidmap, fi.gid); + ent->ndata = fi.size; + ent->data = fi.data; + ent->addr = fi.addr; + ent->replete |= replete; + return ent; +} + +Ram * +lookup(Ram *dir, char *name) +{ + Ram *r; + + if (dir==0) + return 0; + for (r=dir->child; r; r=r->next){ + if (r->busy==0 || strcmp(r->name, name)!=0) + continue; + return r; + } + return 0; +} -- cgit v1.2.3