1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <fcall.h> 5 #include <bio.h> 6 #include "tapefs.h" 7 8 Idmap * 9 getpass(char *file) 10 { 11 Biobuf *bp; 12 char *cp; 13 Idmap *up; 14 int nid, maxid; 15 char *line[4]; 16 17 if ((bp = Bopen(file, OREAD)) == 0) 18 error("Can't open passwd/group"); 19 up = emalloc(1*sizeof(Idmap)); 20 maxid = 1; 21 nid = 0; 22 while ((cp = Brdline(bp, '\n'))) { 23 int nf; 24 cp[Blinelen(bp)-1] = 0; 25 nf = getfields(cp, line, 3, 0, ":\n"); 26 if (nf<3) { 27 fprint(2, "bad format in %s\n", file); 28 break; 29 } 30 if (nid>=maxid) { 31 maxid *= 2; 32 up = (Idmap *)erealloc(up, maxid*sizeof(Idmap)); 33 } 34 up[nid].id = atoi(line[2]); 35 up[nid].name = strdup(line[0]); 36 nid++; 37 } 38 Bterm(bp); 39 up[nid].name = 0; 40 return up; 41 } 42 43 char * 44 mapid(Idmap *up, int id) 45 { 46 char buf[16]; 47 48 if (up) 49 while (up->name){ 50 if (up->id==id) 51 return strdup(up->name); 52 up++; 53 } 54 sprint(buf, "%d", id); 55 return strdup(buf); 56 } 57 58 Ram * 59 poppath(Fileinf fi, int new) 60 { 61 char *suffix, *origname; 62 Ram *dir, *ent; 63 Fileinf f; 64 65 if (*fi.name=='\0') 66 return 0; 67 origname = estrdup(fi.name); 68 if (suffix=strrchr(fi.name, '/')){ 69 *suffix = 0; 70 suffix++; 71 if (*suffix=='\0'){ 72 fi.mode |= DMDIR; 73 free(origname); 74 return poppath(fi, 1); 75 } 76 /* 77 * create parent directory of suffix; 78 * may recurse, thus shortening fi.name even further. 79 */ 80 f = fi; 81 f.size = 0; 82 f.addr = 0; 83 f.mode = 0555|DMDIR; 84 dir = poppath(f, 0); 85 if (dir==0) 86 dir = ram; 87 } else { 88 suffix = fi.name; 89 dir = ram; 90 if (strcmp(suffix, ".")==0) { 91 free(origname); 92 return dir; 93 } 94 } 95 ent = lookup(dir, suffix); 96 fi.mode |= 0400; /* at least user read */ 97 if (ent){ 98 if (((fi.mode&DMDIR)!=0) != ((ent->qid.type&QTDIR)!=0)){ 99 fprint(2, 100 "%s file type changed; probably due to union dir.; ignoring\n", 101 origname); 102 free(origname); 103 return ent; 104 } 105 if (new) { 106 ent->ndata = fi.size; 107 ent->addr = fi.addr; 108 ent->data = fi.data; 109 ent->perm = fi.mode; 110 ent->mtime = fi.mdate; 111 ent->user = mapid(uidmap, fi.uid); 112 ent->group = mapid(gidmap, fi.gid); 113 } 114 } else { 115 fi.name = suffix; 116 ent = popfile(dir, fi); 117 } 118 free(origname); 119 return ent; 120 } 121 122 Ram * 123 popfile(Ram *dir, Fileinf fi) 124 { 125 Ram *ent = (Ram *)emalloc(sizeof(Ram)); 126 if (*fi.name=='\0') 127 return 0; 128 ent->busy = 1; 129 ent->open = 0; 130 ent->parent = dir; 131 ent->next = dir->child; 132 dir->child = ent; 133 ent->child = 0; 134 ent->qid.path = ++path; 135 ent->qid.vers = 0; 136 if(fi.mode&DMDIR) 137 ent->qid.type = QTDIR; 138 else 139 ent->qid.type = QTFILE; 140 ent->perm = fi.mode; 141 ent->name = estrdup(fi.name); 142 ent->atime = ent->mtime = fi.mdate; 143 ent->user = mapid(uidmap, fi.uid); 144 ent->group = mapid(gidmap, fi.gid); 145 ent->ndata = fi.size; 146 ent->data = fi.data; 147 ent->addr = fi.addr; 148 ent->replete |= replete; 149 return ent; 150 } 151 152 Ram * 153 lookup(Ram *dir, char *name) 154 { 155 Ram *r; 156 157 if (dir==0) 158 return 0; 159 for (r=dir->child; r; r=r->next){ 160 if (r->busy==0 || strcmp(r->name, name)!=0) 161 continue; 162 return r; 163 } 164 return 0; 165 } 166