📄 ccmd.c
字号:
#include "stdinc.h"#include "9.h"static struct { VtLock* lock; Con* con; int confd[2]; ushort tag;} cbox;static ulongcmd9pStrtoul(char* s){ if(strcmp(s, "~0") == 0) return ~0UL; return strtoul(s, 0, 0);}static uvlongcmd9pStrtoull(char* s){ if(strcmp(s, "~0") == 0) return ~0ULL; return strtoull(s, 0, 0);}static intcmd9pTag(Fcall*, int, char **argv){ cbox.tag = strtoul(argv[0], 0, 0)-1; return 1;}static intcmd9pTwstat(Fcall* f, int, char **argv){ Dir d; static uchar buf[DIRMAX]; memset(&d, 0, sizeof d); nulldir(&d); d.name = argv[1]; d.uid = argv[2]; d.gid = argv[3]; d.mode = cmd9pStrtoul(argv[4]); d.mtime = cmd9pStrtoul(argv[5]); d.length = cmd9pStrtoull(argv[6]); f->fid = strtol(argv[0], 0, 0); f->stat = buf; f->nstat = convD2M(&d, buf, sizeof buf); if(f->nstat < BIT16SZ){ vtSetError("Twstat: convD2M failed (internal error)"); return 0; } return 1;}static intcmd9pTstat(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); return 1;}static intcmd9pTremove(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); return 1;}static intcmd9pTclunk(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); return 1;}static intcmd9pTwrite(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); f->offset = strtoll(argv[1], 0, 0); f->data = argv[2]; f->count = strlen(argv[2]); return 1;}static intcmd9pTread(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); f->offset = strtoll(argv[1], 0, 0); f->count = strtol(argv[2], 0, 0); return 1;}static intcmd9pTcreate(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); f->name = argv[1]; f->perm = strtol(argv[2], 0, 8); f->mode = strtol(argv[3], 0, 0); return 1;}static intcmd9pTopen(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); f->mode = strtol(argv[1], 0, 0); return 1;}static intcmd9pTwalk(Fcall* f, int argc, char** argv){ int i; if(argc < 2){ vtSetError("usage: Twalk tag fid newfid [name...]"); return 0; } f->fid = strtol(argv[0], 0, 0); f->newfid = strtol(argv[1], 0, 0); f->nwname = argc-2; if(f->nwname > MAXWELEM){ vtSetError("Twalk: too many names"); return 0; } for(i = 0; i < argc-2; i++) f->wname[i] = argv[2+i]; return 1;}static intcmd9pTflush(Fcall* f, int, char** argv){ f->oldtag = strtol(argv[0], 0, 0); return 1;}static intcmd9pTattach(Fcall* f, int, char** argv){ f->fid = strtol(argv[0], 0, 0); f->afid = strtol(argv[1], 0, 0); f->uname = argv[2]; f->aname = argv[3]; return 1;}static intcmd9pTauth(Fcall* f, int, char** argv){ f->afid = strtol(argv[0], 0, 0); f->uname = argv[1]; f->aname = argv[2]; return 1;}static intcmd9pTversion(Fcall* f, int, char** argv){ f->msize = strtoul(argv[0], 0, 0); if(f->msize > cbox.con->msize){ vtSetError("msize too big"); return 0; } f->version = argv[1]; return 1;}typedef struct Cmd9p Cmd9p;struct Cmd9p { char* name; int type; int argc; char* usage; int (*f)(Fcall*, int, char**);};static Cmd9p cmd9pTmsg[] = { "Tversion", Tversion, 2, "msize version", cmd9pTversion, "Tauth", Tauth, 3, "afid uname aname", cmd9pTauth, "Tflush", Tflush, 1, "oldtag", cmd9pTflush, "Tattach", Tattach, 4, "fid afid uname aname", cmd9pTattach, "Twalk", Twalk, 0, "fid newfid [name...]", cmd9pTwalk, "Topen", Topen, 2, "fid mode", cmd9pTopen, "Tcreate", Tcreate, 4, "fid name perm mode", cmd9pTcreate, "Tread", Tread, 3, "fid offset count", cmd9pTread, "Twrite", Twrite, 3, "fid offset data", cmd9pTwrite, "Tclunk", Tclunk, 1, "fid", cmd9pTclunk, "Tremove", Tremove, 1, "fid", cmd9pTremove, "Tstat", Tstat, 1, "fid", cmd9pTstat, "Twstat", Twstat, 7, "fid name uid gid mode mtime length", cmd9pTwstat, "nexttag", 0, 0, "", cmd9pTag,};static intcmd9p(int argc, char* argv[]){ int i, n; Fcall f, t; uchar *buf; char *usage; u32int msize; usage = "usage: 9p T-message ..."; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc < 1) return cliError(usage); for(i = 0; i < nelem(cmd9pTmsg); i++){ if(strcmp(cmd9pTmsg[i].name, argv[0]) == 0) break; } if(i == nelem(cmd9pTmsg)) return cliError(usage); argc--; argv++; if(cmd9pTmsg[i].argc && argc != cmd9pTmsg[i].argc){ vtSetError("usage: %s %s", cmd9pTmsg[i].name, cmd9pTmsg[i].usage); return 0; } memset(&t, 0, sizeof(t)); t.type = cmd9pTmsg[i].type; if(t.type == Tversion) t.tag = NOTAG; else t.tag = ++cbox.tag; msize = cbox.con->msize; if(!cmd9pTmsg[i].f(&t, argc, argv)) return 0; buf = vtMemAlloc(msize); n = convS2M(&t, buf, msize); if(n <= BIT16SZ){ vtSetError("%s: convS2M error", cmd9pTmsg[i].name); vtMemFree(buf); return 0; } if(write(cbox.confd[0], buf, n) != n){ vtSetError("%s: write error: %r", cmd9pTmsg[i].name); vtMemFree(buf); return 0; } consPrint("\t-> %F\n", &t); if((n = read9pmsg(cbox.confd[0], buf, msize)) <= 0){ vtSetError("%s: read error: %r", cmd9pTmsg[i].name); vtMemFree(buf); return 0; } if(convM2S(buf, n, &f) == 0){ vtSetError("%s: convM2S error", cmd9pTmsg[i].name); vtMemFree(buf); return 0; } consPrint("\t<- %F\n", &f); vtMemFree(buf); return 1;}static intcmdDot(int argc, char* argv[]){ long l; Dir *dir; int fd, r; vlong length; char *f, *p, *s, *usage; usage = "usage: . file"; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc != 1) return cliError(usage); if((dir = dirstat(argv[0])) == nil) return cliError(". dirstat %s: %r", argv[0]); length = dir->length; free(dir); r = 1; if(length != 0){ /* * Read the whole file in. */ if((fd = open(argv[0], OREAD)) < 0) return cliError(". open %s: %r", argv[0]); f = vtMemAlloc(dir->length+1); if((l = read(fd, f, length)) < 0){ vtMemFree(f); close(fd); return cliError(". read %s: %r", argv[0]); } close(fd); f[l] = '\0'; /* * Call cliExec() for each line. */ for(p = s = f; *p != '\0'; p++){ if(*p == '\n'){ *p = '\0'; if(cliExec(s) == 0){ r = 0; consPrint("%s: %R\n", s); } s = p+1; } } vtMemFree(f); } if(r == 0) vtSetError("errors in . %#q", argv[0]); return r;}static intcmdDflag(int argc, char* argv[]){ char *usage; usage = "usage: dflag"; ARGBEGIN{ default: return cliError(usage); }ARGEND if(argc) return cliError(usage); Dflag ^= 1; consPrint("dflag %d\n", Dflag); return 1;}static intcmdEcho(int argc, char* argv[]){ char *usage; int i, nflag; nflag = 0; usage = "usage: echo [-n] ..."; ARGBEGIN{ default: return cliError(usage); case 'n': nflag = 1; break; }ARGEND for(i = 0; i < argc; i++){ if(i != 0) consPrint(" %s", argv[i]); else consPrint(argv[i]); } if(!nflag) consPrint("\n"); return 1;}static intcmdBind(int argc, char* argv[]){ ulong flag = 0; char *usage; usage = "usage: bind [-b|-a|-c|-bc|-ac] new old"; ARGBEGIN{ case 'a': flag |= MAFTER; break; case 'b': flag |= MBEFORE; break; case 'c': flag |= MCREATE; break; default: return cliError(usage); }ARGEND if(argc != 2 || (flag&MAFTER)&&(flag&MBEFORE)) return cliError(usage); if(bind(argv[0], argv[1], flag) < 0){ /* try to give a less confusing error than the default */ if(access(argv[0], 0) < 0) return cliError("bind: %s: %r", argv[0]); else if(access(argv[1], 0) < 0) return cliError("bind: %s: %r", argv[1]); else return cliError("bind %s %s: %r", argv[0], argv[1]); } return 1;}intcmdInit(void){ cbox.lock = vtLockAlloc(); cbox.confd[0] = cbox.confd[1] = -1; cliAddCmd(".", cmdDot); cliAddCmd("9p", cmd9p); cliAddCmd("dflag", cmdDflag); cliAddCmd("echo", cmdEcho); cliAddCmd("bind", cmdBind); if(pipe(cbox.confd) < 0) return 0; if((cbox.con = conAlloc(cbox.confd[1], "console", 0)) == nil){ close(cbox.confd[0]); close(cbox.confd[1]); cbox.confd[0] = cbox.confd[1] = -1; return 0; } cbox.con->isconsole = 1; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -