3 static Command command[100];
5 static char statsdef[20]; /* default stats list */
8 static void consserve1(void *);
9 static void installcmds(void);
10 static void tzinit(char*);
17 snprint(cons.chan->whochan, sizeof(cons.chan->whochan), "console");
24 for(i = 0; command[i].arg0; i++)
25 if(strcmp("cwcmd", command[i].arg0) == 0){
26 cmd_exec("cwcmd touchsb");
30 /* switch console output to the cmd pipe */
33 newproc(consserve1, 0, "con");
36 /* console commands process */
42 while(conline = Brdline(&bin, '\n')){
43 conline[Blinelen(&bin)-1] = '\0';
49 cmdcmp(void *va, void *vb)
55 return strcmp(a->arg0, b->arg0);
59 cmd_install(char *arg0, char *help, void (*func)(int, char*[]))
64 for(i=0; command[i].arg0; i++)
66 if(i >= nelem(command)-2) {
68 print("cmd_install: too many commands\n");
71 command[i+1].arg0 = 0;
72 command[i].help = help;
73 command[i].func = func;
74 command[i].arg0 = arg0;
75 qsort(command, i+1, sizeof(Command), cmdcmp);
82 char line[2*Maxword], *s;
86 if(strlen(arg) >= nelem(line)-2) {
87 print("cmd_exec: line too long\n");
96 while(isascii(c) && isspace(c))
100 if(argc >= nelem(argv)-2) {
101 print("cmd_exec: too many args\n");
105 while((!isascii(c) || !isspace(c)) && c != '\0')
111 for(i=0; s=command[i].arg0; i++)
112 if(strcmp(argv[0], s) == 0) {
113 (*command[i].func)(argc, argv);
116 print("cmd_exec: unknown command: %s\n", argv[0]);
120 cmd_halt(int, char *[])
122 wlock(&mainlock); /* halt */
128 cmd_duallow(int argc, char *argv[])
137 uid = strtouid(argv[1]);
139 uid = number(argv[1], -2, 10);
141 print("bad uid %s\n", argv[1]);
148 cmd_stats(int argc, char *argv[])
151 char buf[30], *s, *p, *q;
155 strcpy(statsdef, "a");
156 sprint(buf, "stats s%s", statsdef);
166 for(i = 1; i < argc; i++)
167 for(s = argv[i]; c = *s; s++) {
184 cmd_stata(int, char *[])
188 print("cons stats\n");
189 // print("\twork =%7W%7W%7W rps\n", cons.work+0, cons.work+1, cons.work+2);
190 // print("\trate =%7W%7W%7W tBps\n", cons.rate+0, cons.rate+1, cons.rate+2);
191 // print("\thits =%7W%7W%7W iops\n", cons.bhit+0, cons.bhit+1, cons.bhit+2);
192 // print("\tread =%7W%7W%7W iops\n", cons.bread+0, cons.bread+1, cons.bread+2);
193 // print("\trah =%7W%7W%7W iops\n", cons.brahead+0, cons.brahead+1, cons.brahead+2);
194 // print("\tinit =%7W%7W%7W iops\n", cons.binit+0, cons.binit+1, cons.binit+2);
195 print("\tbufs = %3ld sm %3ld lg %ld res\n",
196 cons.nsmall, cons.nlarge, cons.nreseq);
198 for(i=0; i<nelem(mballocs); i++)
200 print("\t[%d]=%d\n", i, mballocs[i]);
202 print("\tioerr= %3ld wr %3ld ww %3ld dr %3ld dw\n",
203 cons.nwormre, cons.nwormwe, cons.nwrenre, cons.nwrenwe);
204 print("\tcache= %9ld hit %9ld miss\n",
205 cons.nwormhit, cons.nwormmiss);
209 flagcmp(void *va, void *vb)
215 return strcmp(a->arg0, b->arg0);
219 flag_install(char *arg, char *help)
224 for(i=0; flag[i].arg0; i++)
228 print("flag_install: too many flags\n");
235 qsort(flag, i+1, sizeof(Flag), flagcmp);
241 cmd_flag(int argc, char *argv[])
248 for(i=0; flag[i].arg0; i++)
249 print("%.4lux %s %s\n",
250 flag[i].flag, flag[i].arg0, flag[i].help);
252 print("flag[*] = %.4lux\n", cons.flags);
253 for(cp = chans; cp; cp = cp->next)
255 print("flag[%3d] = %.4lux\n", cp->chan, cp->flags);
261 for(i=1; i<argc; i++) {
262 for(j=0; s=flag[j].arg0; j++)
263 if(strcmp(s, argv[i]) == 0)
265 j = number(argv[i], -1, 10);
267 print("bad flag argument: %s\n", argv[i]);
280 print("flag = %.8lux\n", cons.flags);
283 for(cp = chans; cp; cp = cp->next)
288 print("flag[%3d] = %.8lux\n", cp->chan, cp->flags);
291 print("no such channel\n");
295 cmd_who(int argc, char *argv[])
301 for(cp = chans; cp; cp = cp->next) {
302 if(cp->whotime == 0 && !(cons.flags & whoflag)) {
307 for(i=1; i<argc; i++)
308 if(strcmp(argv[i], cp->whoname) == 0)
315 print("%3d: %10s %24s", cp->chan, cp->whoname, cp->whochan);
321 print("%d chans not listed\n", c);
325 cmd_hangup(int argc, char *argv[])
331 print("usage: hangup chan-number\n");
334 n = number(argv[1], -1, 10);
335 for(cp = chans; cp; cp = cp->next) {
336 if(cp->whotime == 0) {
338 print("that chan is hung up\n");
342 chanhangup(cp, "console command");
347 cmd_sync(int, char *[])
349 wlock(&mainlock); /* sync */
355 cmd_help(int argc, char *argv[])
360 for(i=0; arg=command[i].arg0; i++) {
362 for(j=1; j<argc; j++)
363 if(strcmp(argv[j], arg) == 0)
368 print("\t%s %s\n", arg, command[i].help);
373 cmd_fstat(int argc, char *argv[])
377 for(i=1; i<argc; i++) {
378 if(walkto(argv[i])) {
379 print("cant stat %s\n", argv[i]);
387 cmd_create(int argc, char *argv[])
391 char elem[NAMELEN], *p;
394 print("usage: create path uid gid mode [lad]\n");
398 p = utfrrune(argv[1], '/');
401 if(walkto(argv[1])) {
402 print("create failed in walkto: %s\n", p);
410 if(strlen(p) >= NAMELEN) {
411 print("name too long %s\n", p);
415 memset(elem, 0, sizeof(elem));
418 uid = strtouid(argv[2]);
420 uid = number(argv[2], -2, 10);
422 print("bad uid %s\n", argv[2]);
426 gid = strtouid(argv[3]);
428 gid = number(argv[3], -2, 10);
430 print("bad gid %s\n", argv[3]);
434 perm = number(argv[4], 0777, 8) & 0777;
437 if(strchr(argv[5], 'l'))
439 if(strchr(argv[5], 'a'))
441 if(strchr(argv[5], 'd'))
443 if(strchr(argv[5], 't'))
447 if(con_create(FID2, elem, uid, gid, perm, 0))
448 print("create failed: %s/%s\n", argv[1], p);
452 cmd_clri(int argc, char *argv[])
456 for(i=1; i<argc; i++) {
457 if(walkto(argv[i])) {
458 print("cant remove %s\n", argv[i]);
466 cmd_allow(int argc, char *argv[])
475 uid = strtouid(name);
477 uid = number(name, -2, 10);
479 print("bad uid %s\n", name);
483 print("allowed %s\n", name);
488 cmd_disallow(int, char**)
494 ckblock(Device *d, Off a, int typ, Off qpath)
499 p = getbuf(d, a, Brd);
501 checktag(p, typ, qpath);
508 doclean(Iobuf *p, Dentry *d, int n, Off a)
518 for(i=0; i<NDBLOCK; i++) {
519 print("dblock[%d] = %lld\n", i, (Wideoff)d->dblock[i]);
520 ckblock(p->dev, d->dblock[i], typ, qpath);
524 print("dblock[%d] modified %lld\n", i, (Wideoff)a);
528 /* add NDBLOCK so user can cite block address by index */
529 for (i = 0; i < NIBLOCK; i++) {
530 print("iblocks[%d] = %lld\n", NDBLOCK+i, (Wideoff)d->iblocks[i]);
531 ckblock(p->dev, d->iblocks[i], Tind1+i, qpath);
535 print("iblocks[%d] modified %lld\n", NDBLOCK+i, (Wideoff)a);
540 p->flags |= Bmod|Bimm;
544 cmd_clean(int argc, char *argv[])
557 n = number(argv[2], -1, 10);
560 a = number(argv[3], 0, 10);
561 if(walkto(argv[1])) {
562 print("cant remove %s\n", argv[1]);
565 f = filep(cons.chan, FID2, 0);
568 if(n >= 0 && f->fs->dev->type == Devro) {
569 print("readonly %s\n", argv[1]);
572 p = getbuf(f->fs->dev, f->addr, Brd);
573 d = getdir(p, f->slot);
574 if(!d || !(d->mode & DALLOC)) {
575 print("not alloc %s\n", argv[1]);
588 cmd_remove(int argc, char *argv[])
592 for(i=1; i<argc; i++) {
593 if(walkto(argv[i])) {
594 print("cant remove %s\n", argv[i]);
602 cmd_version(int, char *[])
604 tzinit("/adm/timezone/local");
605 print("%d-bit %s as of %T\n", sizeof(Off)*8 - 1, service, fs_mktime);
606 print("\tlast boot %T\n", boottime);
610 cmd_cfs(int argc, char *argv[])
620 print("%s: unknown file system\n", name);
625 if(con_attach(FID1, "adm", fs->name))
626 panic("FID1 attach to root");
628 print("current fs is \"%s\"\n", cons.curfs->name);
632 cmd_prof(int argc, char *argv[])
638 if(cons.profbuf == 0) {
639 print("no buffer\n");
644 n = number(argv[1], n, 10);
645 if(n && !cons.profile) {
646 print("clr and start\n");
647 memset(cons.profbuf, 0, cons.nprofbuf*sizeof(cons.profbuf[0]));
651 if(!n && cons.profile) {
653 print("stop and write\n");
654 if(walkto("/adm/kprofdata"))
656 if(con_open(FID2, OWRITE|OTRUNC)) {
658 print("cant open /adm/kprofdata\n");
661 p = (char*)cons.profbuf;
662 for(m=0; m<cons.nprofbuf; m++) {
671 m = cons.nprofbuf*sizeof(cons.profbuf[0]);
677 con_write(FID2, (char*)cons.profbuf+o, o, n);
692 f = create("#e/timezone", OEXCL|OWRITE, 0666);
695 if(walkto(file) || con_open(FID2, 0)) {
696 print("tzinit: cannot access %s\n", file);
698 remove("#e/timezone");
701 for(o = 0; (n = con_read(FID2, buf, o, sizeof(buf))) > 0; o += n)
708 cmd_time(int argc, char *argv[])
716 for(i=1; i<argc; i++)
717 len += 1 + strlen(argv[i]);
718 cmd = malloc(len + 1);
720 for(i=1; i<argc; i++) {
722 strcat(cmd, argv[i]);
727 print("time = %ld ms\n", TK2MS(t2-t1));
731 cmd_noauth(int, char *[])
734 print("auth %s\n", noauth ? "disabled" : "enabled");
738 cmd_nonone(int, char *[])
741 print("none %s\n", nonone ? "disabled" : "enabled");
745 cmd_noattach(int, char *[])
747 noattach = !noattach;
748 print("attach %s\n", noattach ? "disabled" : "enabled");
752 cmd_files(int, char *[])
757 for(cp = chans; cp; cp = cp->next)
762 for(i=0; i<conf.nfile; i++)
765 files[i].cp->nfile++;
767 print("%ld out of %ld files used\n", n, conf.nfile);
771 for(cp = chans; cp; cp = cp->next)
773 print("%3d: %5d\n", cp->chan, cp->nfile);
776 print("%ld out of %ld files used\n", n, conf.nfile);
780 cmd_chatty(int argc, char *argv[])
783 print("cmd_chatty: usage: chatty n\n");
786 chatty = atoi(argv[1]);
792 cmd_install("allow", "[uid] -- disable permission checking", cmd_allow);
793 cmd_install("cfs", "[file] -- set current filesystem", cmd_cfs);
794 cmd_install("chatty", "n -- set chattiness", cmd_chatty);
795 cmd_install("clean", "file [bno [addr]] -- block print/fix", cmd_clean);
796 cmd_install("check", "[options]", cmd_check);
797 cmd_install("clri", "[file ...] -- purge files/dirs", cmd_clri);
798 cmd_install("create", "path uid gid perm [lad] -- make a file/dir", cmd_create);
799 cmd_install("disallow", "-- (re)enable permission checking", cmd_disallow);
800 cmd_install("duallow", "uid -- duallow", cmd_duallow);
801 cmd_install("flag", "-- print set flags", cmd_flag);
802 cmd_install("fstat", "path -- print info on a file/dir", cmd_fstat);
803 cmd_install("halt", "-- return to boot rom", cmd_halt);
804 cmd_install("help", "", cmd_help);
805 cmd_install("newuser", "username -- add user to /adm/users", cmd_newuser);
806 cmd_install("profile", "[01] -- fs profile", cmd_prof);
807 cmd_install("remove", "[file ...] -- remove files/dirs", cmd_remove);
808 cmd_install("stata", "-- overall stats", cmd_stata);
809 cmd_install("stats", "[[-]flags ...] -- various stats", cmd_stats);
810 cmd_install("sync", "", cmd_sync);
811 cmd_install("time", "command -- time another command", cmd_time);
812 cmd_install("users", "[file] -- read /adm/users", cmd_users);
813 cmd_install("version", "-- print time of mk and boot", cmd_version);
814 cmd_install("who", "[user ...] -- print attaches", cmd_who);
815 cmd_install("hangup", "chan -- clunk files", cmd_hangup);
816 cmd_install("printconf", "-- print configuration", cmd_printconf);
817 cmd_install("noauth", "toggle noauth flag", cmd_noauth);
818 cmd_install("nonone", "toggle nonone flag", cmd_nonone);
819 cmd_install("noattach", "toggle noattach flag", cmd_noattach);
820 cmd_install("files", "report on files structure", cmd_files);
822 chatflag = flag_install("chat", "-- verbose");
823 errorflag = flag_install("error", "-- on errors");
824 whoflag = flag_install("allchans", "-- on who");
825 authdebugflag = flag_install("authdebug", "-- report authentications");
831 char elem[NAMELEN], *p;
834 if(con_clone(FID1, FID2))
838 p = utfrune(name, '/');
840 p = strchr(name, '\0');
850 memset(elem, 0, sizeof(elem));
851 memmove(elem, name, n);
852 if(con_walk(FID2, elem))
858 /* needs to parse and return vlongs to cope with new larger block numbers */
860 number(char *arg, int def, int base)
872 for (c = *arg; isascii(c) && isspace(c) && c != '\n'; c = *arg)
879 while (isascii(c) && (isdigit(c) || base == 16 && isxdigit(c))) {
881 if(c >= 'a' && c <= 'f')
883 else if(c >= 'A' && c <= 'F')