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 extern Rootdata rootdata[]; 9 extern Dirtab roottab[]; 10 extern int rootmaxq; 11 12 static Chan* 13 rootattach(char *spec) 14 { 15 int i; 16 ulong len; 17 Rootdata *r; 18 19 if(*spec) 20 error(Ebadspec); 21 for (i = 0; i < rootmaxq; i++){ 22 r = &rootdata[i]; 23 if (r->sizep){ 24 len = *r->sizep; 25 r->size = len; 26 roottab[i].length = len; 27 } 28 } 29 return devattach('/', spec); 30 } 31 32 static int 33 rootgen(Chan *c, char *name, Dirtab *tab, int nd, int s, Dir *dp) 34 { 35 int p, i; 36 Rootdata *r; 37 38 if(s == DEVDOTDOT){ 39 p = rootdata[c->qid.path].dotdot; 40 c->qid.path = p; 41 c->qid.type = QTDIR; 42 name = "#/"; 43 if(p != 0){ 44 for(i = 0; i < rootmaxq; i++) 45 if(roottab[i].qid.path == c->qid.path){ 46 name = roottab[i].name; 47 break; 48 } 49 } 50 devdir(c, c->qid, name, 0, eve, 0555, dp); 51 return 1; 52 } 53 if(name != nil){ 54 isdir(c); 55 r = &rootdata[(int)c->qid.path]; 56 tab = r->ptr; 57 for(i=0; i<r->size; i++, tab++) 58 if(strcmp(tab->name, name) == 0){ 59 devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); 60 return 1; 61 } 62 return -1; 63 } 64 if(s >= nd) 65 return -1; 66 tab += s; 67 devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); 68 return 1; 69 } 70 71 static Walkqid* 72 rootwalk(Chan *c, Chan *nc, char **name, int nname) 73 { 74 ulong p; 75 76 p = c->qid.path; 77 if(nname == 0) 78 p = rootdata[p].dotdot; 79 return devwalk(c, nc, name, nname, rootdata[p].ptr, rootdata[p].size, rootgen); 80 } 81 82 static int 83 rootstat(Chan *c, uchar *dp, int n) 84 { 85 int p; 86 87 p = rootdata[c->qid.path].dotdot; 88 return devstat(c, dp, n, rootdata[p].ptr, rootdata[p].size, rootgen); 89 } 90 91 static Chan* 92 rootopen(Chan *c, int omode) 93 { 94 int p; 95 96 p = rootdata[c->qid.path].dotdot; 97 return devopen(c, omode, rootdata[p].ptr, rootdata[p].size, rootgen); 98 } 99 100 /* 101 * sysremove() knows this is a nop 102 */ 103 static void 104 rootclose(Chan*) 105 { 106 } 107 108 static long 109 rootread(Chan *c, void *buf, long n, vlong offset) 110 { 111 ulong p, len; 112 uchar *data; 113 114 p = c->qid.path; 115 if(c->qid.type & QTDIR) 116 return devdirread(c, buf, n, rootdata[p].ptr, rootdata[p].size, rootgen); 117 len = rootdata[p].size; 118 if(offset < 0 || offset >= len) 119 return 0; 120 if(offset+n > len) 121 n = len - offset; 122 data = rootdata[p].ptr; 123 memmove(buf, data+offset, n); 124 return n; 125 } 126 127 static long 128 rootwrite(Chan*, void*, long, vlong) 129 { 130 error(Eperm); 131 return 0; 132 } 133 134 Dev rootdevtab = { 135 '/', 136 "root", 137 138 devreset, 139 devinit, 140 devshutdown, 141 rootattach, 142 rootwalk, 143 rootstat, 144 rootopen, 145 devcreate, 146 rootclose, 147 rootread, 148 devbread, 149 rootwrite, 150 devbwrite, 151 devremove, 152 devwstat, 153 }; 154