123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- #include "stdinc.h"
- #include "9.h"
- static struct {
- VtLock* lock;
- Con* con;
- int confd[2];
- ushort tag;
- } cbox;
- static ulong
- cmd9pStrtoul(char* s)
- {
- if(strcmp(s, "~0") == 0)
- return ~0UL;
- return strtoul(s, 0, 0);
- }
- static uvlong
- cmd9pStrtoull(char* s)
- {
- if(strcmp(s, "~0") == 0)
- return ~0ULL;
- return strtoull(s, 0, 0);
- }
- static int
- cmd9pTag(Fcall*, int, char **argv)
- {
- cbox.tag = strtoul(argv[0], 0, 0)-1;
- return 1;
- }
- static int
- cmd9pTwstat(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 int
- cmd9pTstat(Fcall* f, int, char** argv)
- {
- f->fid = strtol(argv[0], 0, 0);
- return 1;
- }
- static int
- cmd9pTremove(Fcall* f, int, char** argv)
- {
- f->fid = strtol(argv[0], 0, 0);
- return 1;
- }
- static int
- cmd9pTclunk(Fcall* f, int, char** argv)
- {
- f->fid = strtol(argv[0], 0, 0);
- return 1;
- }
- static int
- cmd9pTwrite(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 int
- cmd9pTread(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 int
- cmd9pTcreate(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 int
- cmd9pTopen(Fcall* f, int, char** argv)
- {
- f->fid = strtol(argv[0], 0, 0);
- f->mode = strtol(argv[1], 0, 0);
- return 1;
- }
- static int
- cmd9pTwalk(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 int
- cmd9pTflush(Fcall* f, int, char** argv)
- {
- f->oldtag = strtol(argv[0], 0, 0);
- return 1;
- }
- static int
- cmd9pTattach(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 int
- cmd9pTauth(Fcall* f, int, char** argv)
- {
- f->afid = strtol(argv[0], 0, 0);
- f->uname = argv[1];
- f->aname = argv[2];
- return 1;
- }
- static int
- cmd9pTversion(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 int
- cmd9p(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 int
- cmdDot(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 int
- cmdDflag(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 int
- cmdEcho(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 int
- cmdBind(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;
- }
- int
- cmdInit(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;
- }
|