16 if(strcmp(s, "~0") == 0)
18 return strtoul(s, 0, 0);
22 cmd9pStrtoull(char* s)
24 if(strcmp(s, "~0") == 0)
26 return strtoull(s, 0, 0);
30 cmd9pTag(Fcall* f, int i, char **argv)
34 cbox.tag = strtoul(argv[0], 0, 0)-1;
40 cmd9pTwstat(Fcall* f, int i, char **argv)
43 static uchar buf[DIRMAX];
46 memset(&d, 0, sizeof d);
51 d.mode = cmd9pStrtoul(argv[4]);
52 d.mtime = cmd9pStrtoul(argv[5]);
53 d.length = cmd9pStrtoull(argv[6]);
55 f->fid = strtol(argv[0], 0, 0);
57 f->nstat = convD2M(&d, buf, sizeof buf);
58 if(f->nstat < BIT16SZ){
59 werrstr("Twstat: convD2M failed (internal error)");
67 cmd9pTstat(Fcall* f, int i, char** argv)
70 f->fid = strtol(argv[0], 0, 0);
76 cmd9pTremove(Fcall* f, int i, char** argv)
79 f->fid = strtol(argv[0], 0, 0);
85 cmd9pTclunk(Fcall* f, int i, char** argv)
88 f->fid = strtol(argv[0], 0, 0);
94 cmd9pTwrite(Fcall* f, int i, char** argv)
97 f->fid = strtol(argv[0], 0, 0);
98 f->offset = strtoll(argv[1], 0, 0);
100 f->count = strlen(argv[2]);
106 cmd9pTread(Fcall* f, int i, char** argv)
109 f->fid = strtol(argv[0], 0, 0);
110 f->offset = strtoll(argv[1], 0, 0);
111 f->count = strtol(argv[2], 0, 0);
117 cmd9pTcreate(Fcall* f, int i, char** argv)
120 f->fid = strtol(argv[0], 0, 0);
122 f->perm = strtol(argv[2], 0, 8);
123 f->mode = strtol(argv[3], 0, 0);
129 cmd9pTopen(Fcall* f, int i, char** argv)
132 f->fid = strtol(argv[0], 0, 0);
133 f->mode = strtol(argv[1], 0, 0);
139 cmd9pTwalk(Fcall* f, int argc, char** argv)
144 werrstr("usage: Twalk tag fid newfid [name...]");
147 f->fid = strtol(argv[0], 0, 0);
148 f->newfid = strtol(argv[1], 0, 0);
150 if(f->nwname > MAXWELEM){
151 werrstr("Twalk: too many names");
154 for(i = 0; i < argc-2; i++)
155 f->wname[i] = argv[2+i];
161 cmd9pTflush(Fcall* f, int i, char** argv)
164 f->oldtag = strtol(argv[0], 0, 0);
170 cmd9pTattach(Fcall* f, int i, char** argv)
173 f->fid = strtol(argv[0], 0, 0);
174 f->afid = strtol(argv[1], 0, 0);
182 cmd9pTauth(Fcall* f, int i, char** argv)
185 f->afid = strtol(argv[0], 0, 0);
193 cmd9pTversion(Fcall* f, int i, char** argv)
196 f->msize = strtoul(argv[0], 0, 0);
197 if(f->msize > cbox.con->msize){
198 werrstr("msize too big");
201 f->version = argv[1];
206 typedef struct Cmd9p Cmd9p;
212 int (*f)(Fcall*, int, char**);
215 static Cmd9p cmd9pTmsg[] = {
216 "Tversion", Tversion, 2, "msize version", cmd9pTversion,
217 "Tauth", Tauth, 3, "afid uname aname", cmd9pTauth,
218 "Tflush", Tflush, 1, "oldtag", cmd9pTflush,
219 "Tattach", Tattach, 4, "fid afid uname aname", cmd9pTattach,
220 "Twalk", Twalk, 0, "fid newfid [name...]", cmd9pTwalk,
221 "Topen", Topen, 2, "fid mode", cmd9pTopen,
222 "Tcreate", Tcreate, 4, "fid name perm mode", cmd9pTcreate,
223 "Tread", Tread, 3, "fid offset count", cmd9pTread,
224 "Twrite", Twrite, 3, "fid offset data", cmd9pTwrite,
225 "Tclunk", Tclunk, 1, "fid", cmd9pTclunk,
226 "Tremove", Tremove, 1, "fid", cmd9pTremove,
227 "Tstat", Tstat, 1, "fid", cmd9pTstat,
228 "Twstat", Twstat, 7, "fid name uid gid mode mtime length", cmd9pTwstat,
229 "nexttag", 0, 0, "", cmd9pTag,
233 cmd9p(int argc, char* argv[])
241 usage = "usage: 9p T-message ...";
245 return cliError(usage);
248 return cliError(usage);
250 for(i = 0; i < nelem(cmd9pTmsg); i++){
251 if(strcmp(cmd9pTmsg[i].name, argv[0]) == 0)
254 if(i == nelem(cmd9pTmsg))
255 return cliError(usage);
258 if(cmd9pTmsg[i].argc && argc != cmd9pTmsg[i].argc){
259 werrstr("usage: %s %s",
260 cmd9pTmsg[i].name, cmd9pTmsg[i].usage);
264 memset(&t, 0, sizeof(t));
265 t.type = cmd9pTmsg[i].type;
266 if(t.type == Tversion)
270 msize = cbox.con->msize;
271 if(!cmd9pTmsg[i].f(&t, argc, argv))
273 buf = vtmalloc(msize);
274 n = convS2M(&t, buf, msize);
276 werrstr("%s: convS2M error", cmd9pTmsg[i].name);
280 if(write(cbox.confd[0], buf, n) != n){
281 werrstr("%s: write error: %r", cmd9pTmsg[i].name);
285 consPrint("\t-> %F\n", &t);
287 if((n = read9pmsg(cbox.confd[0], buf, msize)) <= 0){
288 werrstr("%s: read error: %r", cmd9pTmsg[i].name);
292 if(convM2S(buf, n, &f) == 0){
293 werrstr("%s: convM2S error", cmd9pTmsg[i].name);
297 consPrint("\t<- %F\n", &f);
304 cmdDot(int argc, char* argv[])
310 char *f, *p, *s, *usage;
312 usage = "usage: . file";
316 return cliError(usage);
319 return cliError(usage);
321 if((dir = dirstat(argv[0])) == nil)
322 return cliError(". dirstat %s: %r", argv[0]);
323 length = dir->length;
329 * Read the whole file in.
331 if((fd = open(argv[0], OREAD)) < 0)
332 return cliError(". open %s: %r", argv[0]);
333 f = vtmalloc(dir->length+1);
334 if((l = read(fd, f, length)) < 0){
337 return cliError(". read %s: %r", argv[0]);
343 * Call cliExec() for each line.
345 for(p = s = f; *p != '\0'; p++){
350 consPrint("%s: %r\n", s);
359 werrstr("errors in . %#q", argv[0]);
364 cmdDflag(int argc, char* argv[])
368 usage = "usage: dflag";
372 return cliError(usage);
375 return cliError(usage);
378 consPrint("dflag %d\n", Dflag);
384 cmdEcho(int argc, char* argv[])
390 usage = "usage: echo [-n] ...";
394 return cliError(usage);
400 for(i = 0; i < argc; i++){
402 consPrint(" %s", argv[i]);
413 cmdBind(int argc, char* argv[])
418 usage = "usage: bind [-b|-a|-c|-bc|-ac] new old";
431 return cliError(usage);
434 if(argc != 2 || (flag&MAFTER)&&(flag&MBEFORE))
435 return cliError(usage);
438 if(bind(argv[0], argv[1], flag) < 0){
439 /* try to give a less confusing error than the default */
440 if(access(argv[0], 0) < 0)
441 return cliError("bind: %s: %r", argv[0]);
442 else if(access(argv[1], 0) < 0)
443 return cliError("bind: %s: %r", argv[1]);
445 return cliError("bind %s %s: %r", argv[0], argv[1]);
454 cbox.confd[0] = cbox.confd[1] = -1;
456 cliAddCmd(".", cmdDot);
457 cliAddCmd("9p", cmd9p);
458 cliAddCmd("dflag", cmdDflag);
459 cliAddCmd("echo", cmdEcho);
460 cliAddCmd("bind", cmdBind);
462 if(pipe(cbox.confd) < 0)
464 if((cbox.con = conAlloc(cbox.confd[1], "console", 0)) == nil){
465 close(cbox.confd[0]);
466 close(cbox.confd[1]);
467 cbox.confd[0] = cbox.confd[1] = -1;
471 cbox.con->isconsole = 1;