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