123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- #include "all.h"
- static Command command[100];
- static Flag flag[35];
- static char statsdef[20]; /* default stats list */
- static int whoflag;
- static void consserve1(void *);
- static void installcmds(void);
- void
- consserve(void)
- {
- int i;
- strncpy(cons.chan->whochan, "console", sizeof(cons.chan->whochan));
- installcmds();
- con_session();
- cmd_exec("cfs");
- cmd_exec("users");
- cmd_exec("version");
- for(i = 0; command[i].arg0; i++)
- if(strcmp("cwcmd", command[i].arg0) == 0){
- cmd_exec("cwcmd touchsb");
- break;
- }
- newproc(consserve1, 0, "con");
- }
- /* console commands process */
- static void
- consserve1(void *)
- {
- char *conline;
- for (;;) {
- /* conslock(); */
- do {
- print("%s: ", service);
- if ((conline = Brdline(&bin, '\n')) == nil)
- print("\n");
- else {
- conline[Blinelen(&bin)-1] = '\0';
- cmd_exec(conline);
- }
- } while (conline != nil);
- }
- }
- static int
- cmdcmp(const void *va, const void *vb)
- {
- Command *a, *b;
- a = va;
- b = vb;
- return strcmp(a->arg0, b->arg0);
- }
- void
- cmd_install(char *arg0, char *help, void (*func)(int, char*[]))
- {
- int i;
- qlock(&cons);
- for(i=0; command[i].arg0; i++)
- ;
- if(i >= nelem(command)-2) {
- qunlock(&cons);
- print("cmd_install: too many commands\n");
- return;
- }
- command[i+1].arg0 = 0;
- command[i].help = help;
- command[i].func = func;
- command[i].arg0 = arg0;
- qsort(command, i+1, sizeof(Command), cmdcmp);
- qunlock(&cons);
- }
- void
- cmd_exec(char *arg)
- {
- char line[2*Maxword], *s;
- char *argv[10];
- int argc, i, c;
- if(strlen(arg) >= nelem(line)-2) {
- print("cmd_exec: line too long\n");
- return;
- }
- strcpy(line, arg);
- argc = 0;
- s = line;
- c = *s++;
- for(;;) {
- while(isascii(c) && isspace(c))
- c = *s++;
- if(c == 0)
- break;
- if(argc >= nelem(argv)-2) {
- print("cmd_exec: too many args\n");
- return;
- }
- argv[argc++] = s-1;
- while((!isascii(c) || !isspace(c)) && c != '\0')
- c = *s++;
- s[-1] = 0;
- }
- if(argc <= 0)
- return;
- for(i=0; s=command[i].arg0; i++)
- if(strcmp(argv[0], s) == 0) {
- (*command[i].func)(argc, argv);
- prflush();
- return;
- }
- print("cmd_exec: unknown command: %s\n", argv[0]);
- }
- static void
- cmd_halt(int, char *[])
- {
- wlock(&mainlock); /* halt */
- sync("halt");
- exit();
- }
- static void
- cmd_duallow(int argc, char *argv[])
- {
- int uid;
- if(argc <= 1) {
- duallow = 0;
- return;
- }
- uid = strtouid(argv[1]);
- if(uid < 0)
- uid = number(argv[1], -2, 10);
- if(uid < 0) {
- print("bad uid %s\n", argv[1]);
- return;
- }
- duallow = uid;
- }
- static void
- cmd_stats(int argc, char *argv[])
- {
- int i, c;
- char buf[30], *s, *p, *q;
- if(argc <= 1) {
- if(statsdef[0] == 0)
- strcpy(statsdef, "a");
- sprint(buf, "stats s%s", statsdef);
- cmd_exec(buf);
- return;
- }
- strcpy(buf, "stat");
- p = strchr(buf, 0);
- p[1] = 0;
- q = 0;
- for(i = 1; i < argc; i++)
- for(s = argv[i]; c = *s; s++) {
- if(c == 's')
- continue;
- if(c == '-') {
- q = statsdef;
- continue;
- }
- if(q) {
- *q++ = c;
- *q = 0;
- }
- *p = c;
- cmd_exec(buf);
- }
- }
- static void
- cmd_stata(int, char *[])
- {
- int i;
- print("cons stats\n");
- // print("\twork =%7W%7W%7W rps\n", cons.work+0, cons.work+1, cons.work+2);
- // print("\trate =%7W%7W%7W tBps\n", cons.rate+0, cons.rate+1, cons.rate+2);
- // print("\thits =%7W%7W%7W iops\n", cons.bhit+0, cons.bhit+1, cons.bhit+2);
- // print("\tread =%7W%7W%7W iops\n", cons.bread+0, cons.bread+1, cons.bread+2);
- // print("\trah =%7W%7W%7W iops\n", cons.brahead+0, cons.brahead+1, cons.brahead+2);
- // print("\tinit =%7W%7W%7W iops\n", cons.binit+0, cons.binit+1, cons.binit+2);
- print("\tbufs = %3ld sm %3ld lg %ld res\n",
- cons.nsmall, cons.nlarge, cons.nreseq);
- for(i=0; i<nelem(mballocs); i++)
- if(mballocs[i])
- print("\t[%d]=%d\n", i, mballocs[i]);
- print("\tioerr= %3ld wr %3ld ww %3ld dr %3ld dw\n",
- cons.nwormre, cons.nwormwe, cons.nwrenre, cons.nwrenwe);
- print("\tcache= %9ld hit %9ld miss\n",
- cons.nwormhit, cons.nwormmiss);
- }
- static int
- flagcmp(const void *va, const void *vb)
- {
- Flag *a, *b;
- a = va;
- b = vb;
- return strcmp(a->arg0, b->arg0);
- }
- uint32_t
- flag_install(char *arg, char *help)
- {
- int i;
- qlock(&cons);
- for(i=0; flag[i].arg0; i++)
- ;
- if(i >= 32) {
- qunlock(&cons);
- print("flag_install: too many flags\n");
- return 0;
- }
- flag[i+1].arg0 = 0;
- flag[i].arg0 = arg;
- flag[i].help = help;
- flag[i].flag = 1<<i;
- qsort(flag, i+1, sizeof(Flag), flagcmp);
- qunlock(&cons);
- return 1<<i;
- }
- void
- cmd_flag(int argc, char *argv[])
- {
- int f, n, i, j;
- char *s;
- Chan *cp;
- if(argc <= 1) {
- for(i=0; flag[i].arg0; i++)
- print("%.4lux %s %s\n",
- flag[i].flag, flag[i].arg0, flag[i].help);
- if(cons.flags)
- print("flag[*] = %.4lux\n", cons.flags);
- for(cp = chans; cp; cp = cp->next)
- if(cp->flags)
- print("flag[%3d] = %.4lux\n", cp->chan, cp->flags);
- return;
- }
- f = 0;
- n = -1;
- for(i=1; i<argc; i++) {
- for(j=0; s=flag[j].arg0; j++)
- if(strcmp(s, argv[i]) == 0)
- goto found;
- j = number(argv[i], -1, 10);
- if(j < 0) {
- print("bad flag argument: %s\n", argv[i]);
- continue;
- }
- n = j;
- continue;
- found:
- f |= flag[j].flag;
- }
- if(n < 0) {
- cons.flags ^= f;
- if(f == 0)
- cons.flags = 0;
- print("flag = %.8lux\n", cons.flags);
- return;
- }
- for(cp = chans; cp; cp = cp->next)
- if(cp->chan == n) {
- cp->flags ^= f;
- if(f == 0)
- cp->flags = 0;
- print("flag[%3d] = %.8lux\n", cp->chan, cp->flags);
- return;
- }
- print("no such channel\n");
- }
- static void
- cmd_who(int argc, char *argv[])
- {
- Chan *cp;
- int i, c;
- c = 0;
- for(cp = chans; cp; cp = cp->next) {
- if(cp->whotime == 0 && !(cons.flags & whoflag)) {
- c++;
- continue;
- }
- if(argc > 1) {
- for(i=1; i<argc; i++)
- if(strcmp(argv[i], cp->whoname) == 0)
- break;
- if(i >= argc) {
- c++;
- continue;
- }
- }
- print("%3d: %10s %24s", cp->chan,
- cp->whoname? cp->whoname: "<nowhoname>", cp->whochan);
- if(cp->whoprint)
- cp->whoprint(cp);
- print("\n");
- prflush();
- }
- if(c > 0)
- print("%d chans not listed\n", c);
- }
- static void
- cmd_hangup(int argc, char *argv[])
- {
- Chan *cp;
- int n;
- if(argc < 2) {
- print("usage: hangup chan-number\n");
- return;
- }
- n = number(argv[1], -1, 10);
- for(cp = chans; cp; cp = cp->next) {
- if(cp->whotime == 0) {
- if(cp->chan == n)
- print("that chan is hung up\n");
- continue;
- }
- if(cp->chan == n) {
- /* need more than just fileinit with tcp */
- chanhangup(cp, "console command", 1);
- fileinit(cp);
- }
- }
- }
- static void
- cmd_sync(int, char *[])
- {
- wlock(&mainlock); /* sync */
- sync("command");
- wunlock(&mainlock);
- print("\n");
- }
- static void
- cmd_help(int argc, char *argv[])
- {
- char *arg;
- int i, j;
- for(i=0; arg=command[i].arg0; i++) {
- if(argc > 1) {
- for(j=1; j<argc; j++)
- if(strcmp(argv[j], arg) == 0)
- goto found;
- continue;
- }
- found:
- print("\t%s %s\n", arg, command[i].help);
- prflush();
- }
- }
- void
- cmd_fstat(int argc, char *argv[])
- {
- int i;
- for(i=1; i<argc; i++) {
- if(walkto(argv[i])) {
- print("cant stat %s\n", argv[i]);
- continue;
- }
- con_fstat(FID2);
- }
- }
- void
- cmd_create(int argc, char *argv[])
- {
- int uid, gid;
- int32_t perm;
- char elem[NAMELEN], *p;
- if(argc < 5) {
- print("usage: create path uid gid mode [lad]\n");
- return;
- }
- p = utfrrune(argv[1], '/');
- if(p) {
- *p++ = 0;
- if(walkto(argv[1])) {
- print("create failed in walkto: %s\n", p);
- return;
- }
- } else {
- if(walkto("/"))
- return;
- p = argv[1];
- }
- if(strlen(p) >= NAMELEN) {
- print("name too long %s\n", p);
- return;
- }
- memset(elem, 0, sizeof(elem));
- strcpy(elem, p);
- uid = strtouid(argv[2]);
- if(uid < -1)
- uid = number(argv[2], -2, 10);
- if(uid < -1) {
- print("bad uid %s\n", argv[2]);
- return;
- }
- gid = strtouid(argv[3]);
- if(gid < -1)
- gid = number(argv[3], -2, 10);
- if(gid < -1) {
- print("bad gid %s\n", argv[3]);
- return;
- }
- perm = number(argv[4], 0777, 8) & 0777;
- if(argc > 5) {
- if(strchr(argv[5], 'l'))
- perm |= PLOCK;
- if(strchr(argv[5], 'a'))
- perm |= PAPND;
- if(strchr(argv[5], 'd'))
- perm |= PDIR;
- }
- if(con_create(FID2, elem, uid, gid, perm, 0))
- print("create failed: %s/%s\n", argv[1], p);
- }
- static void
- cmd_clri(int argc, char *argv[])
- {
- int i;
- for(i=1; i<argc; i++) {
- if(walkto(argv[i])) {
- print("cant remove %s\n", argv[i]);
- continue;
- }
- con_clri(FID2);
- }
- }
- static void
- cmd_allow(int, char**)
- {
- wstatallow = writeallow = 1;
- }
- static void
- cmd_disallow(int, char**)
- {
- wstatallow = writeallow = 0;
- }
- void
- ckblock(Device *d, Off a, int typ, Off qpath)
- {
- Iobuf *p;
- if(a) {
- p = getbuf(d, a, Brd);
- if(p) {
- checktag(p, typ, qpath);
- putbuf(p);
- }
- }
- }
- void
- doclean(Iobuf *p, Dentry *d, int n, Off a)
- {
- int i, mod, typ;
- Off qpath;
- mod = 0;
- qpath = d->qid.path;
- typ = Tfile;
- if(d->mode & DDIR)
- typ = Tdir;
- for(i=0; i<NDBLOCK; i++) {
- print("dblock[%d] = %lld\n", i, (Wideoff)d->dblock[i]);
- ckblock(p->dev, d->dblock[i], typ, qpath);
- if(i == n) {
- d->dblock[i] = a;
- mod = 1;
- print("dblock[%d] modified %lld\n", i, (Wideoff)a);
- }
- }
- /* add NDBLOCK so user can cite block address by index */
- for (i = 0; i < NIBLOCK; i++) {
- print("iblocks[%d] = %lld\n", NDBLOCK+i, (Wideoff)d->iblocks[i]);
- ckblock(p->dev, d->iblocks[i], Tind1+i, qpath);
- if(NDBLOCK+i == n) {
- d->iblocks[i] = a;
- mod = 1;
- print("iblocks[%d] modified %lld\n", NDBLOCK+i, (Wideoff)a);
- }
- }
- if(mod)
- p->flags |= Bmod|Bimm;
- }
- static void
- cmd_clean(int argc, char *argv[])
- {
- int n;
- Off a;
- Iobuf *p;
- Dentry *d;
- File *f;
- p = 0;
- f = 0;
- while(argc > 1) {
- n = -1;
- if(argc > 2)
- n = number(argv[2], -1, 10);
- a = 0;
- if(argc > 3)
- a = number(argv[3], 0, 10);
- if(walkto(argv[1])) {
- print("cant remove %s\n", argv[1]);
- break;
- }
- f = filep(cons.chan, FID2, 0);
- if(!f)
- break;
- if(n >= 0 && f->fs->dev->type == Devro) {
- print("readonly %s\n", argv[1]);
- break;
- }
- p = getbuf(f->fs->dev, f->addr, Brd);
- d = getdir(p, f->slot);
- if(!d || !(d->mode & DALLOC)) {
- print("not alloc %s\n", argv[1]);
- break;
- }
- doclean(p, d, n, a);
- break;
- }
- if(f)
- qunlock(f);
- if(p)
- putbuf(p);
- }
- static void
- cmd_remove(int argc, char *argv[])
- {
- int i;
- for(i=1; i<argc; i++) {
- if(walkto(argv[i])) {
- print("cant remove %s\n", argv[i]);
- continue;
- }
- con_remove(FID2);
- }
- }
- static void
- cmd_version(int, char *[])
- {
- print("%d-bit %s as of %T\n", sizeof(Off)*8 - 1, service, fs_mktime);
- print("\tlast boot %T\n", boottime);
- }
- static void
- cmd_cfs(int argc, char *argv[])
- {
- Filsys *fs;
- char *name;
- name = "main";
- if(argc > 1)
- name = argv[1];
- fs = fsstr(name);
- if(fs == 0) {
- print("%s: unknown file system\n", name);
- if(cons.curfs)
- return;
- fs = &filsys[0];
- }
- if(con_attach(FID1, "adm", fs->name))
- panic("FID1 attach to root");
- cons.curfs = fs;
- print("current fs is \"%s\"\n", cons.curfs->name);
- }
- static void
- cmd_prof(int argc, char *argv[])
- {
- int n;
- int32_t m, o;
- char *p;
- if(cons.profbuf == 0) {
- print("no buffer\n");
- return;
- }
- n = !cons.profile;
- if(argc > 1)
- n = number(argv[1], n, 10);
- if(n && !cons.profile) {
- print("clr and start\n");
- memset(cons.profbuf, 0, cons.nprofbuf*sizeof(cons.profbuf[0]));
- cons.profile = 1;
- return;
- }
- if(!n && cons.profile) {
- cons.profile = 0;
- print("stop and write\n");
- if(walkto("/adm/kprofdata"))
- goto bad;
- if(con_open(FID2, OWRITE|OTRUNC)) {
- bad:
- print("cant open /adm/kprofdata\n");
- return;
- }
- p = (char*)cons.profbuf;
- for(m=0; m<cons.nprofbuf; m++) {
- n = cons.profbuf[m];
- p[0] = n>>24;
- p[1] = n>>16;
- p[2] = n>>8;
- p[3] = n>>0;
- p += 4;
- }
- m = cons.nprofbuf*sizeof(cons.profbuf[0]);
- o = 0;
- while(m > 0) {
- n = 8192;
- if(n > m)
- n = m;
- con_write(FID2, (char*)cons.profbuf+o, o, n);
- m -= n;
- o += n;
- }
- return;
- }
- }
- static void
- cmd_time(int argc, char *argv[])
- {
- int i, len;
- char *cmd;
- Timet t1, t2;
- t1 = time(nil);
- len = 0;
- for(i=1; i<argc; i++)
- len += 1 + strlen(argv[i]);
- cmd = malloc(len + 1);
- cmd[0] = 0;
- for(i=1; i<argc; i++) {
- strcat(cmd, " ");
- strcat(cmd, argv[i]);
- }
- cmd_exec(cmd);
- t2 = time(nil);
- free(cmd);
- print("time = %ld ms\n", TK2MS(t2-t1));
- }
- void
- cmd_noattach(int, char *[])
- {
- noattach = !noattach;
- if(noattach)
- print("attaches are DISABLED\n");
- }
- void
- cmd_files(int, char *[])
- {
- int32_t i, n;
- Chan *cp;
- for(cp = chans; cp; cp = cp->next)
- cp->nfile = 0;
- lock(&flock);
- n = 0;
- for(i=0; i<conf.nfile; i++)
- if(files[i].cp) {
- n++;
- files[i].cp->nfile++;
- }
- print("%ld out of %ld files used\n", n, conf.nfile);
- unlock(&flock);
- n = 0;
- for(cp = chans; cp; cp = cp->next)
- if(cp->nfile) {
- print("%3d: %5d\n", cp->chan, cp->nfile);
- prflush();
- n += cp->nfile;
- }
- print("%ld out of %ld files used\n", n, conf.nfile);
- }
- static void
- installcmds(void)
- {
- cmd_install("allow", "-- disable permission checking", cmd_allow);
- cmd_install("cfs", "[file] -- set current filesystem", cmd_cfs);
- cmd_install("clean", "file [bno [addr]] -- block print/fix", cmd_clean);
- cmd_install("check", "[options]", cmd_check);
- cmd_install("clri", "[file ...] -- purge files/dirs", cmd_clri);
- cmd_install("create", "path uid gid perm [lad] -- make a file/dir", cmd_create);
- cmd_install("disallow", "-- enable permission checking", cmd_disallow);
- cmd_install("duallow", "uid -- duallow", cmd_duallow);
- cmd_install("flag", "-- print set flags", cmd_flag);
- cmd_install("fstat", "path -- print info on a file/dir", cmd_fstat);
- cmd_install("halt", "-- return to boot rom", cmd_halt);
- cmd_install("help", "", cmd_help);
- cmd_install("newuser", "username -- add user to /adm/users", cmd_newuser);
- cmd_install("profile", "[01] -- fs profile", cmd_prof);
- cmd_install("remove", "[file ...] -- remove files/dirs", cmd_remove);
- cmd_install("stata", "-- overall stats", cmd_stata);
- cmd_install("stats", "[[-]flags ...] -- various stats", cmd_stats);
- cmd_install("sync", "", cmd_sync);
- cmd_install("time", "command -- time another command", cmd_time);
- cmd_install("users", "[file] -- read /adm/users", cmd_users);
- cmd_install("version", "-- print time of mk and boot", cmd_version);
- cmd_install("who", "[user ...] -- print attaches", cmd_who);
- cmd_install("hangup", "chan -- clunk files", cmd_hangup);
- cmd_install("printconf", "-- print configuration", cmd_printconf);
- cmd_install("noattach", "toggle noattach flag", cmd_noattach);
- cmd_install("files", "report on files structure", cmd_files);
- attachflag = flag_install("attach", "-- attach calls");
- chatflag = flag_install("chat", "-- verbose");
- errorflag = flag_install("error", "-- on errors");
- whoflag = flag_install("allchans", "-- on who");
- authdebugflag = flag_install("authdebug", "-- report authentications");
- authdisableflag = flag_install("authdisable", "-- disable authentication");
- }
- int
- walkto(char *name)
- {
- char elem[NAMELEN], *p;
- int n;
- if(con_clone(FID1, FID2))
- return 1;
- for(;;) {
- p = utfrune(name, '/');
- if(p == nil)
- p = strchr(name, '\0');
- if(p == name) {
- if(*name == '\0')
- return 0;
- name = p+1;
- continue;
- }
- n = p-name;
- if(n > NAMELEN)
- return 1;
- memset(elem, 0, sizeof(elem));
- memmove(elem, name, n);
- if(con_walk(FID2, elem))
- return 1;
- name = p;
- }
- }
- /* needs to parse and return vlongs to cope with new larger block numbers */
- int64_t
- number(char *arg, int def, int base)
- {
- int c, sign, any;
- int64_t n;
- if(arg == nil)
- return def;
- sign = 0;
- any = 0;
- n = 0;
- for (c = *arg; isascii(c) && isspace(c) && c != '\n'; c = *arg)
- arg++;
- if(c == '-') {
- sign = 1;
- arg++;
- c = *arg;
- }
- while (isascii(c) && (isdigit(c) || base == 16 && isxdigit(c))) {
- n *= base;
- if(c >= 'a' && c <= 'f')
- n += c - 'a' + 10;
- else if(c >= 'A' && c <= 'F')
- n += c - 'A' + 10;
- else
- n += c - '0';
- arg++;
- c = *arg;
- any = 1;
- }
- if(!any)
- return def;
- if(sign)
- n = -n;
- return n;
- }
|