1 #include <u.h> 2 #include <libc.h> 3 #include <auth.h> 4 #include <fcall.h> 5 #include <tapefs.h> 6 #include <bio.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 setfields(":\n"); 23 while ((cp = Brdline(bp, '\n'))) { 24 getfields(cp, line, 3); 25 if (nid>=maxid) { 26 maxid *= 2; 27 up = (Idmap *)erealloc(up, maxid*sizeof(Idmap)); 28 } 29 if (line[0] && line[2]) { 30 up[nid].id = atoi(line[2]); 31 up[nid].name = strdup(line[0]); 32 nid++; 33 } 34 } 35 Bterm(bp); 36 up[nid].name = 0; 37 return up; 38 } 39 40 char * 41 mapid(Idmap *up, int id) 42 { 43 char buf[16]; 44 45 if (up) 46 while (up->name){ 47 if (up->id==id) 48 return strdup(up->name); 49 up++; 50 } 51 sprint(buf, "%d", id); 52 return strdup(buf); 53 } 54 55 Ram * 56 poppath(Fileinf fi, int new) 57 { 58 char *suffix; 59 Ram *dir, *ent; 60 if (*fi.name=='\0') 61 return 0; 62 if (suffix=strrchr(fi.name, '/')){ 63 Fileinf f; 64 *suffix = 0; 65 suffix++; 66 if (*suffix=='\0'){ 67 fi.mode |= CHDIR; 68 return poppath(fi, 1); 69 } 70 f = fi; 71 f.size = 0; 72 f.addr = 0; 73 f.mode = 0555|CHDIR; 74 dir = poppath(f, 0); 75 if (dir==0) 76 dir = ram; 77 } else { 78 suffix = fi.name; 79 dir = ram; 80 if (strcmp(suffix, ".")==0) 81 return dir; 82 } 83 ent = lookup(dir, suffix); 84 fi.mode |= 0400; /* at least user read */ 85 if (ent){ 86 if ((fi.mode&CHDIR) != (ent->qid.path&CHDIR)){ 87 fprint(2, "%s/%s directory botch\n", fi.name, suffix); 88 exits(""); 89 } 90 if (new) { 91 ent->ndata = fi.size; 92 ent->data = fi.addr; 93 ent->perm = fi.mode; 94 ent->mtime = fi.mdate; 95 ent->user = mapid(uidmap, fi.uid); 96 ent->group = mapid(gidmap, fi.gid); 97 } 98 } else { 99 strncpy(fi.name, suffix, NAMELEN); 100 ent = popfile(dir, fi); 101 } 102 return ent; 103 } 104 105 Ram * 106 popfile(Ram *dir, Fileinf fi) 107 { 108 Ram *ent = (Ram *)emalloc(sizeof(Ram)); 109 110 if (*fi.name=='\0') 111 return 0; 112 ent->busy = 1; 113 ent->open = 0; 114 ent->parent = dir; 115 ent->next = dir->child; 116 dir->child = ent; 117 ent->child = 0; 118 ent->qid.path = ++path | fi.mode&CHDIR; 119 ent->qid.vers = 0; 120 ent->perm = fi.mode; 121 strncpy(ent->name, fi.name, NAMELEN); 122 ent->atime = ent->mtime = fi.mdate; 123 ent->user = mapid(uidmap, fi.uid); 124 ent->group = mapid(gidmap, fi.gid); 125 ent->ndata = fi.size; 126 ent->data = fi.addr; 127 ent->replete |= replete; 128 return ent; 129 } 130 131 Ram * 132 lookup(Ram *dir, char *name) 133 { 134 Ram *r; 135 136 if (dir==0) 137 return 0; 138 for (r=dir->child; r; r=r->next){ 139 if (r->busy==0 || strcmp(r->name, name)!=0) 140 continue; 141 return r; 142 } 143 return 0; 144 } 145