1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "../port/error.h" 7 8 enum 9 { 10 Qdir = 0, 11 Qboot = 0x1000, 12 13 Nrootfiles = 32, 14 Nbootfiles = 32, 15 }; 16 17 typedef struct Dirlist Dirlist; 18 struct Dirlist 19 { 20 uint base; 21 Dirtab *dir; 22 uchar **data; 23 int ndir; 24 int mdir; 25 }; 26 27 static Dirtab rootdir[Nrootfiles] = { 28 "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555, 29 "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555, 30 }; 31 static uchar *rootdata[Nrootfiles]; 32 static Dirlist rootlist = 33 { 34 0, 35 rootdir, 36 rootdata, 37 2, 38 Nrootfiles 39 }; 40 41 static Dirtab bootdir[Nbootfiles] = { 42 "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555, 43 }; 44 static uchar *bootdata[Nbootfiles]; 45 static Dirlist bootlist = 46 { 47 Qboot, 48 bootdir, 49 bootdata, 50 1, 51 Nbootfiles 52 }; 53 54 /* 55 * add a file to the list 56 */ 57 static void 58 addlist(Dirlist *l, char *name, uchar *contents, ulong len, int perm) 59 { 60 Dirtab *d; 61 62 if(l->ndir >= l->mdir) 63 panic("too many root files"); 64 l->data[l->ndir] = contents; 65 d = &l->dir[l->ndir]; 66 strcpy(d->name, name); 67 d->length = len; 68 d->perm = perm; 69 d->qid.type = 0; 70 d->qid.vers = 0; 71 d->qid.path = ++l->ndir + l->base; 72 if(perm & DMDIR) 73 d->qid.type |= QTDIR; 74 } 75 76 /* 77 * add a root file 78 */ 79 void 80 addbootfile(char *name, uchar *contents, ulong len) 81 { 82 addlist(&bootlist, name, contents, len, 0555); 83 } 84 85 /* 86 * add a root directory 87 */ 88 static void 89 addrootdir(char *name) 90 { 91 addlist(&rootlist, name, nil, 0, DMDIR|0555); 92 } 93 94 static void 95 rootreset(void) 96 { 97 addrootdir("bin"); 98 addrootdir("dev"); 99 addrootdir("env"); 100 addrootdir("fd"); 101 addrootdir("mnt"); 102 addrootdir("net"); 103 addrootdir("net.alt"); 104 addrootdir("proc"); 105 addrootdir("root"); 106 addrootdir("srv"); 107 } 108 109 static Chan* 110 rootattach(char *spec) 111 { 112 return devattach('/', spec); 113 } 114 115 static int 116 rootgen(Chan *c, char *name, Dirtab*, int, int s, Dir *dp) 117 { 118 int t; 119 Dirtab *d; 120 Dirlist *l; 121 122 switch((int)c->qid.path){ 123 case Qdir: 124 return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp); 125 case Qboot: 126 if(s == DEVDOTDOT){ 127 devdir(c, (Qid){Qdir, 0, QTDIR}, "#/", 0, eve, 0555, dp); 128 return 1; 129 } 130 return devgen(c, name, bootlist.dir, bootlist.ndir, s, dp); 131 default: 132 if((int)c->qid.path < Qboot){ 133 t = c->qid.path-1; 134 l = &rootlist; 135 }else{ 136 t = c->qid.path - Qboot - 1; 137 l = &bootlist; 138 } 139 if(t >= l->ndir) 140 return -1; 141 if(s != 0) 142 return -1; 143 d = &l->dir[t]; 144 devdir(c, d->qid, d->name, d->length, eve, d->perm, dp); 145 return 1; 146 } 147 return -1; 148 } 149 150 static Walkqid* 151 rootwalk(Chan *c, Chan *nc, char **name, int nname) 152 { 153 return devwalk(c, nc, name, nname, nil, 0, rootgen); 154 } 155 156 static int 157 rootstat(Chan *c, uchar *dp, int n) 158 { 159 return devstat(c, dp, n, nil, 0, rootgen); 160 } 161 162 static Chan* 163 rootopen(Chan *c, int omode) 164 { 165 return devopen(c, omode, nil, 0, devgen); 166 } 167 168 /* 169 * sysremove() knows this is a nop 170 */ 171 static void 172 rootclose(Chan*) 173 { 174 } 175 176 static long 177 rootread(Chan *c, void *buf, long n, vlong off) 178 { 179 ulong t; 180 Dirtab *d; 181 Dirlist *l; 182 uchar *data; 183 ulong offset = off; 184 185 t = c->qid.path; 186 switch(t){ 187 case Qdir: 188 case Qboot: 189 return devdirread(c, buf, n, nil, 0, rootgen); 190 } 191 192 if(t<Qboot) 193 l = &rootlist; 194 else{ 195 t -= Qboot; 196 l = &bootlist; 197 } 198 199 d = &l->dir[t-1]; 200 data = l->data[t-1]; 201 if(offset >= d->length) 202 return 0; 203 if(offset+n > d->length) 204 n = d->length - offset; 205 memmove(buf, data+offset, n); 206 return n; 207 } 208 209 static long 210 rootwrite(Chan*, void*, long, vlong) 211 { 212 error(Egreg); 213 return 0; 214 } 215 216 Dev rootdevtab = { 217 '/', 218 "root", 219 220 rootreset, 221 devinit, 222 devshutdown, 223 rootattach, 224 rootwalk, 225 rootstat, 226 rootopen, 227 devcreate, 228 rootclose, 229 rootread, 230 devbread, 231 rootwrite, 232 devbwrite, 233 devremove, 234 devwstat, 235 }; 236 237