#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, *origname; Ram *dir, *ent; Fileinf f; if (*fi.name=='\0') return 0; origname = estrdup(fi.name); if (suffix=strrchr(fi.name, '/')){ *suffix = 0; suffix++; if (*suffix=='\0'){ fi.mode |= DMDIR; free(origname); return poppath(fi, 1); } /* * create parent directory of suffix; * may recurse, thus shortening fi.name even further. */ 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) { free(origname); 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 file type changed; probably due to union dir.; ignoring\n", origname); free(origname); return ent; } 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); } free(origname); 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; }