1 #include <u.h> 2 #include <libc.h> 3 #include <fcall.h> 4 #include <thread.h> 5 #include <9p.h> 6 7 uint time0; 8 9 enum 10 { 11 Qroot = 0, 12 Qkid, 13 }; 14 15 char *kidname; 16 uint kidmode; 17 18 void 19 fsattach(Req *r) 20 { 21 char *spec; 22 23 spec = r->ifcall.aname; 24 if(spec && spec[0]){ 25 respond(r, "invalid attach specifier"); 26 return; 27 } 28 r->ofcall.qid = (Qid){Qroot, 0, QTDIR}; 29 r->fid->qid = r->ofcall.qid; 30 respond(r, nil); 31 } 32 33 char* 34 fswalk1(Fid *fid, char *name, Qid *qid) 35 { 36 switch((int)fid->qid.path){ 37 default: 38 return "path not found"; 39 case Qroot: 40 if(strcmp(name, "..") == 0) 41 break; 42 if(strcmp(name, kidname) == 0){ 43 fid->qid = (Qid){Qkid, 0, kidmode>>24}; 44 break; 45 } 46 return "path not found"; 47 case Qkid: 48 if(strcmp(name, "..") == 0){ 49 fid->qid = (Qid){Qroot, 0, QTDIR}; 50 break; 51 } 52 return "path not found"; 53 } 54 *qid = fid->qid; 55 return nil; 56 } 57 58 void 59 fsstat(Req *r) 60 { 61 int q; 62 Dir *d; 63 64 d = &r->d; 65 memset(d, 0, sizeof *d); 66 q = r->fid->qid.path; 67 d->qid = r->fid->qid; 68 switch(q){ 69 case Qroot: 70 d->name = estrdup9p("/"); 71 d->mode = DMDIR|0777; 72 break; 73 74 case Qkid: 75 d->name = estrdup9p(kidname); 76 d->mode = kidmode; 77 break; 78 } 79 80 d->atime = d->mtime = time0; 81 d->uid = estrdup9p("stub"); 82 d->gid = estrdup9p("stub"); 83 d->muid = estrdup9p(""); 84 respond(r, nil); 85 } 86 87 int 88 dirgen(int off, Dir *d, void*) 89 { 90 if(off != 0) 91 return -1; 92 93 memset(d, 0, sizeof *d); 94 d->atime = d->mtime = time0; 95 d->name = estrdup9p(kidname); 96 d->mode = kidmode; 97 d->qid = (Qid){Qkid, 0, kidmode>>24}; 98 d->qid.type = d->mode>>24; 99 d->uid = estrdup9p("stub"); 100 d->gid = estrdup9p("stub"); 101 d->muid = estrdup9p(""); 102 return 0; 103 } 104 105 void 106 fsread(Req *r) 107 { 108 int q; 109 110 q = r->fid->qid.path; 111 switch(q){ 112 default: 113 respond(r, "bug"); 114 return; 115 116 case Qroot: 117 dirread9p(r, dirgen, nil); 118 respond(r, nil); 119 return; 120 } 121 } 122 123 void 124 fswrite(Req *r) 125 { 126 respond(r, "no writing"); 127 } 128 129 void 130 fsopen(Req *r) 131 { 132 if(r->fid->qid.path != Qroot){ 133 respond(r, "permission denied"); 134 return; 135 } 136 137 if(r->ifcall.mode != OREAD) 138 respond(r, "permission denied"); 139 else 140 respond(r, nil); 141 } 142 143 Srv fs = { 144 .attach= fsattach, 145 .open= fsopen, 146 .read= fsread, 147 .write= fswrite, 148 .stat= fsstat, 149 .walk1= fswalk1, 150 }; 151 152 void 153 usage(void) 154 { 155 fprint(2, "usage: aux/stub [-Dd] path/name\n"); 156 exits("usage"); 157 } 158 159 void 160 main(int argc, char **argv) 161 { 162 char *p, *mtpt; 163 164 quotefmtinstall(); 165 166 time0 = time(0); 167 ARGBEGIN{ 168 case 'D': 169 chatty9p++; 170 break; 171 case 'd': 172 kidmode = DMDIR; 173 break; 174 default: 175 usage(); 176 }ARGEND 177 178 if(argc != 1) 179 usage(); 180 181 if((p = strrchr(argv[0], '/')) == 0){ 182 mtpt = "."; 183 kidname = argv[0]; 184 }else if(p == argv[0]){ 185 mtpt = "/"; 186 kidname = argv[0]+1; 187 }else{ 188 mtpt = argv[0]; 189 *p++ = '\0'; 190 kidname = p; 191 } 192 postmountsrv(&fs, nil, mtpt, MBEFORE); 193 exits(nil); 194 } 195