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 #include "devtab.h" 8 9 enum{ 10 Qdir= 0, 11 Qbin, 12 Qdev, 13 Qenv, 14 Qproc, 15 Qnet, 16 Qboot, /* readable files */ 17 18 Nfiles=13, /* max root files */ 19 }; 20 21 extern ulong bootlen; 22 extern uchar bootcode[]; 23 24 Dirtab rootdir[Nfiles]={ 25 "bin", {Qbin|CHDIR}, 0, 0777, 26 "dev", {Qdev|CHDIR}, 0, 0777, 27 "env", {Qenv|CHDIR}, 0, 0777, 28 "proc", {Qproc|CHDIR}, 0, 0777, 29 "net", {Qnet|CHDIR}, 0, 0777, 30 }; 31 32 static uchar *rootdata[Nfiles]; 33 static int nroot = Qboot - 1; 34 35 /* 36 * add a root file 37 */ 38 void 39 addrootfile(char *name, uchar *contents, ulong len) 40 { 41 Dirtab *d; 42 43 44 if(nroot >= Nfiles) 45 panic("too many root files"); 46 rootdata[nroot] = contents; 47 d = &rootdir[nroot]; 48 strcpy(d->name, name); 49 d->length = len; 50 d->perm = 0555; 51 d->qid.path = nroot+1; 52 nroot++; 53 } 54 55 void 56 rootreset(void) 57 { 58 addrootfile("boot", bootcode, bootlen); /* always have a boot file */ 59 } 60 61 void 62 rootinit(void) 63 { 64 } 65 66 Chan* 67 rootattach(char *spec) 68 { 69 return devattach('/', spec); 70 } 71 72 Chan* 73 rootclone(Chan *c, Chan *nc) 74 { 75 return devclone(c, nc); 76 } 77 78 int 79 rootwalk(Chan *c, char *name) 80 { 81 if(strcmp(name, "..") == 0) { 82 c->qid.path = Qdir|CHDIR; 83 return 1; 84 } 85 if((c->qid.path & ~CHDIR) != Qdir) 86 return 0; 87 return devwalk(c, name, rootdir, nroot, devgen); 88 } 89 90 void 91 rootstat(Chan *c, char *dp) 92 { 93 devstat(c, dp, rootdir, nroot, devgen); 94 } 95 96 Chan* 97 rootopen(Chan *c, int omode) 98 { 99 return devopen(c, omode, rootdir, nroot, devgen); 100 } 101 102 void 103 rootcreate(Chan *c, char *name, int omode, ulong perm) 104 { 105 USED(c, name, omode, perm); 106 error(Eperm); 107 } 108 109 /* 110 * sysremove() knows this is a nop 111 */ 112 void 113 rootclose(Chan *c) 114 { 115 USED(c); 116 } 117 118 long 119 rootread(Chan *c, void *buf, long n, ulong offset) 120 { 121 ulong t; 122 Dirtab *d; 123 uchar *data; 124 125 t = c->qid.path & ~CHDIR; 126 if(t == Qdir) 127 return devdirread(c, buf, n, rootdir, nroot, devgen); 128 if(t < Qboot) 129 return 0; 130 131 d = &rootdir[t-1]; 132 data = rootdata[t-1]; 133 if(offset >= d->length) 134 return 0; 135 if(offset+n > d->length) 136 n = d->length - offset; 137 memmove(buf, data+offset, n); 138 return n; 139 } 140 141 long 142 rootwrite(Chan *c, void *buf, long n, ulong offset) 143 { 144 USED(c, buf, n, offset); 145 error(Egreg); 146 return 0; /* not reached */ 147 } 148 149 void 150 rootremove(Chan *c) 151 { 152 USED(c); 153 error(Eperm); 154 } 155 156 void 157 rootwstat(Chan *c, char *dp) 158 { 159 USED(c, dp); 160 error(Eperm); 161 } 162