#include <u.h>
#include <libc.h>
#include <auth.h>
#include <fcall.h>
#include <bio.h>
#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;
}
|