|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "io.h" ! 7: #include "../port/error.h" ! 8: ! 9: #include "devtab.h" ! 10: ! 11: struct { ! 12: IOQ; /* lock to klogputs */ ! 13: QLock; /* qlock to getc */ ! 14: }klogq; ! 15: ! 16: IOQ mouseq; ! 17: IOQ lineq; /* lock to getc; interrupt putc's */ ! 18: IOQ printq; ! 19: KIOQ kbdq; ! 20: ! 21: static Ref ctl; /* number of opens to the control file */ ! 22: static int raw; /* true if raw has been requested on ctl file */ ! 23: ! 24: char sysname[NAMELEN]; ! 25: ! 26: /* ! 27: * init the queues and set the output routine ! 28: */ ! 29: void ! 30: printinit(void) ! 31: { ! 32: initq(&printq); ! 33: printq.puts = 0; ! 34: initq(&lineq); ! 35: initq(&kbdq); ! 36: kbdq.putc = kbdputc; ! 37: initq(&klogq); ! 38: initq(&mouseq); ! 39: mouseq.putc = mouseputc; ! 40: } ! 41: ! 42: /* ! 43: * Print a string on the console. Convert \n to \r\n for serial ! 44: * line consoles. Locking of the queues is left up to the screen ! 45: * or uart code. Multi-line messages to serial consoles may get ! 46: * interspersed with other messages. ! 47: */ ! 48: void ! 49: putstrn(char *str, int n) ! 50: { ! 51: char buf[PRINTSIZE+2]; ! 52: int m; ! 53: char *t; ! 54: ! 55: /* ! 56: * if there's an attached bit mapped display, ! 57: * put the message there. screenputs is defined ! 58: * as a null macro for systems that have no such ! 59: * display. ! 60: */ ! 61: screenputs(str, n); ! 62: ! 63: /* ! 64: * if there's a serial line being used as a console, ! 65: * put the message there. Tack a carriage return ! 66: * before new lines. ! 67: */ ! 68: if(printq.puts == 0) ! 69: return; ! 70: ! 71: while(n > 0){ ! 72: t = memchr(str, '\n', n); ! 73: if(t){ ! 74: m = t - str; ! 75: memmove(buf, str, m); ! 76: buf[m] = '\r'; ! 77: buf[m+1] = '\n'; ! 78: (*printq.puts)(&printq, buf, m+2); ! 79: str = t + 1; ! 80: n -= m + 1; ! 81: } else { ! 82: (*printq.puts)(&printq, str, n); ! 83: break; ! 84: } ! 85: } ! 86: } ! 87: ! 88: /* ! 89: * Print a string in the kernel log. Ignore overflow. ! 90: */ ! 91: void ! 92: klogputs(char *str, long n) ! 93: { ! 94: int s, m; ! 95: uchar *nextin; ! 96: ! 97: s = splhi(); ! 98: lock(&klogq); ! 99: while(n){ ! 100: m = &klogq.buf[NQ] - klogq.in; ! 101: if(m > n) ! 102: m = n; ! 103: memmove(klogq.in, str, m); ! 104: n -= m; ! 105: str += m; ! 106: nextin = klogq.in + m; ! 107: if(nextin >= &klogq.buf[NQ]) ! 108: klogq.in = klogq.buf; ! 109: else ! 110: klogq.in = nextin; ! 111: } ! 112: unlock(&klogq); ! 113: splx(s); ! 114: wakeup(&klogq.r); ! 115: } ! 116: ! 117: int ! 118: isbrkc(KIOQ *q) ! 119: { ! 120: uchar *p; ! 121: ! 122: for(p=q->out; p!=q->in; ){ ! 123: if(raw) ! 124: return 1; ! 125: if(*p==0x04 || *p=='\n') ! 126: return 1; ! 127: p++; ! 128: if(p >= q->buf+sizeof(q->buf)) ! 129: p = q->buf; ! 130: } ! 131: return 0; ! 132: } ! 133: ! 134: int ! 135: sprint(char *s, char *fmt, ...) ! 136: { ! 137: return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s; ! 138: } ! 139: ! 140: int ! 141: snprint(char *s, int n, char *fmt, ...) ! 142: { ! 143: return doprint(s, s+n, fmt, (&fmt+1)) - s; ! 144: } ! 145: ! 146: int ! 147: print(char *fmt, ...) ! 148: { ! 149: char buf[PRINTSIZE]; ! 150: int n; ! 151: ! 152: n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; ! 153: putstrn(buf, n); ! 154: return n; ! 155: } ! 156: ! 157: int ! 158: kprint(char *fmt, ...) ! 159: { ! 160: char buf[PRINTSIZE]; ! 161: int n; ! 162: ! 163: n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; ! 164: klogputs(buf, n); ! 165: return n; ! 166: } ! 167: ! 168: void ! 169: panic(char *fmt, ...) ! 170: { ! 171: char buf[PRINTSIZE]; ! 172: int n; ! 173: ! 174: strcpy(buf, "panic: "); ! 175: n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, (&fmt+1)) - buf; ! 176: buf[n] = '\n'; ! 177: putstrn(buf, n+1); ! 178: dumpstack(); ! 179: exit(1); ! 180: } ! 181: int ! 182: pprint(char *fmt, ...) ! 183: { ! 184: char buf[2*PRINTSIZE]; ! 185: Chan *c; ! 186: int n; ! 187: ! 188: if(u->p->fgrp == 0) ! 189: return 0; ! 190: ! 191: c = u->p->fgrp->fd[2]; ! 192: if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) ! 193: return 0; ! 194: n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); ! 195: n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; ! 196: ! 197: if(waserror()) ! 198: return 0; ! 199: (*devtab[c->type].write)(c, buf, n, c->offset); ! 200: poperror(); ! 201: ! 202: lock(c); ! 203: c->offset += n; ! 204: unlock(c); ! 205: ! 206: return n; ! 207: } ! 208: ! 209: void ! 210: prflush(void) ! 211: { ! 212: while(printq.in != printq.out) ; ! 213: } ! 214: #include <ureg.h> ! 215: void ! 216: echo(Rune r, char *buf, int n) ! 217: { ! 218: static int ctrlt; ! 219: ! 220: /* ! 221: * ^p hack ! 222: */ ! 223: if(r==0x10 && cpuserver) ! 224: exit(0); ! 225: ! 226: /* ! 227: * ^t hack BUG ! 228: */ ! 229: if(ctrlt == 2){ ! 230: ctrlt = 0; ! 231: switch(r){ ! 232: case 0x14: ! 233: break; /* pass it on */ ! 234: case 'x': ! 235: xsummary(); ! 236: break; ! 237: case 'b': ! 238: bitdebug(); ! 239: break; ! 240: case 'd': ! 241: consdebug(); ! 242: return; ! 243: case 'p': ! 244: procdump(); ! 245: return; ! 246: case 'r': ! 247: exit(0); ! 248: break; ! 249: } ! 250: }else if(r == 0x14){ ! 251: ctrlt++; ! 252: return; ! 253: } ! 254: ctrlt = 0; ! 255: if(raw) ! 256: return; ! 257: if(r == 0x15) ! 258: putstrn("^U\n", 3); ! 259: else ! 260: putstrn(buf, n); ! 261: } ! 262: ! 263: /* ! 264: * turn '\r' into '\n' before putting it into the queue ! 265: */ ! 266: int ! 267: kbdcr2nl(IOQ *q, int ch) ! 268: { ! 269: if(ch == '\r') ! 270: ch = '\n'; ! 271: return kbdputc(q, ch); ! 272: } ! 273: ! 274: /* ! 275: * Put character, possibly a rune, into read queue at interrupt time. ! 276: * Always called splhi from processor 0. ! 277: */ ! 278: int ! 279: kbdputc(IOQ *q, int ch) ! 280: { ! 281: int i, n; ! 282: char buf[3]; ! 283: Rune r; ! 284: ! 285: USED(q); ! 286: r = ch; ! 287: n = runetochar(buf, &r); ! 288: if(n == 0) ! 289: return 0; ! 290: echo(r, buf, n); ! 291: kbdq.c = r; ! 292: for(i=0; i<n; i++){ ! 293: *kbdq.in++ = buf[i]; ! 294: if(kbdq.in == kbdq.buf+sizeof(kbdq.buf)) ! 295: kbdq.in = kbdq.buf; ! 296: } ! 297: if(raw || r=='\n' || r==0x04) ! 298: wakeup(&kbdq.r); ! 299: return 0; ! 300: } ! 301: ! 302: void ! 303: kbdrepeat(int rep) ! 304: { ! 305: kbdq.repeat = rep; ! 306: kbdq.count = 0; ! 307: } ! 308: ! 309: void ! 310: kbdclock(void) ! 311: { ! 312: if(kbdq.repeat == 0) ! 313: return; ! 314: if(kbdq.repeat==1 && ++kbdq.count>HZ){ ! 315: kbdq.repeat = 2; ! 316: kbdq.count = 0; ! 317: return; ! 318: } ! 319: if(++kbdq.count&1) ! 320: kbdputc(&kbdq, kbdq.c); ! 321: } ! 322: ! 323: int ! 324: consactive(void) ! 325: { ! 326: return printq.in != printq.out; ! 327: } ! 328: ! 329: enum{ ! 330: Qdir, ! 331: Qauth, ! 332: Qauthcheck, ! 333: Qauthent, ! 334: Qclock, ! 335: Qcons, ! 336: Qconsctl, ! 337: Qcputime, ! 338: Qhz, ! 339: Qkey, ! 340: Qhostdomain, ! 341: Qhostowner, ! 342: Qklog, ! 343: Qlights, ! 344: Qmsec, ! 345: Qnoise, ! 346: Qnull, ! 347: Qpgrpid, ! 348: Qpid, ! 349: Qppid, ! 350: Qswap, ! 351: Qsysname, ! 352: Qsysstat, ! 353: Qtime, ! 354: Quser, ! 355: }; ! 356: ! 357: Dirtab consdir[]={ ! 358: "authenticate", {Qauth}, 0, 0666, ! 359: "authcheck", {Qauthcheck}, 0, 0666, ! 360: "authenticator", {Qauthent}, 0, 0666, ! 361: "clock", {Qclock}, 2*NUMSIZE, 0444, ! 362: "cons", {Qcons}, 0, 0660, ! 363: "consctl", {Qconsctl}, 0, 0220, ! 364: "cputime", {Qcputime}, 6*NUMSIZE, 0444, ! 365: "hostdomain", {Qhostdomain}, DOMLEN, 0664, ! 366: "hostowner", {Qhostowner}, NAMELEN, 0664, ! 367: "hz", {Qhz}, NUMSIZE, 0666, ! 368: "key", {Qkey}, DESKEYLEN, 0622, ! 369: "klog", {Qklog}, 0, 0444, ! 370: "lights", {Qlights}, 0, 0220, ! 371: "msec", {Qmsec}, NUMSIZE, 0444, ! 372: "noise", {Qnoise}, 0, 0220, ! 373: "null", {Qnull}, 0, 0666, ! 374: "pgrpid", {Qpgrpid}, NUMSIZE, 0444, ! 375: "pid", {Qpid}, NUMSIZE, 0444, ! 376: "ppid", {Qppid}, NUMSIZE, 0444, ! 377: "swap", {Qswap}, 0, 0664, ! 378: "sysname", {Qsysname}, 0, 0664, ! 379: "sysstat", {Qsysstat}, 0, 0666, ! 380: "time", {Qtime}, NUMSIZE, 0664, ! 381: "user", {Quser}, NAMELEN, 0666, ! 382: }; ! 383: ! 384: #define NCONS (sizeof consdir/sizeof(Dirtab)) ! 385: ! 386: ulong boottime; /* seconds since epoch at boot */ ! 387: ! 388: long ! 389: seconds(void) ! 390: { ! 391: return boottime + TK2SEC(MACHP(0)->ticks); ! 392: } ! 393: ! 394: int ! 395: readnum(ulong off, char *buf, ulong n, ulong val, int size) ! 396: { ! 397: char tmp[64]; ! 398: Fconv fconv = (Fconv){ tmp, tmp+sizeof(tmp), size-1, 0, 0, 'u' }; ! 399: ! 400: numbconv(&val, &fconv); ! 401: tmp[size-1] = ' '; ! 402: if(off >= size) ! 403: return 0; ! 404: if(off+n > size) ! 405: n = size-off; ! 406: memmove(buf, tmp+off, n); ! 407: return n; ! 408: } ! 409: ! 410: int ! 411: readstr(ulong off, char *buf, ulong n, char *str) ! 412: { ! 413: int size; ! 414: ! 415: size = strlen(str); ! 416: if(off >= size) ! 417: return 0; ! 418: if(off+n > size) ! 419: n = size-off; ! 420: memmove(buf, str+off, n); ! 421: return n; ! 422: } ! 423: ! 424: void ! 425: consreset(void) ! 426: { ! 427: } ! 428: ! 429: void ! 430: consinit(void) ! 431: { ! 432: } ! 433: ! 434: Chan* ! 435: consattach(char *spec) ! 436: { ! 437: return devattach('c', spec); ! 438: } ! 439: ! 440: Chan* ! 441: consclone(Chan *c, Chan *nc) ! 442: { ! 443: return devclone(c, nc); ! 444: } ! 445: ! 446: int ! 447: conswalk(Chan *c, char *name) ! 448: { ! 449: return devwalk(c, name, consdir, NCONS, devgen); ! 450: } ! 451: ! 452: void ! 453: consstat(Chan *c, char *dp) ! 454: { ! 455: devstat(c, dp, consdir, NCONS, devgen); ! 456: } ! 457: ! 458: Chan* ! 459: consopen(Chan *c, int omode) ! 460: { ! 461: c->aux = 0; ! 462: switch(c->qid.path){ ! 463: case Qconsctl: ! 464: if(!iseve()) ! 465: error(Eperm); ! 466: incref(&ctl); ! 467: break; ! 468: } ! 469: return devopen(c, omode, consdir, NCONS, devgen); ! 470: } ! 471: ! 472: void ! 473: conscreate(Chan *c, char *name, int omode, ulong perm) ! 474: { ! 475: USED(c, name, omode, perm); ! 476: error(Eperm); ! 477: } ! 478: ! 479: void ! 480: consclose(Chan *c) ! 481: { ! 482: /* last close of control file turns off raw */ ! 483: switch(c->qid.path){ ! 484: case Qconsctl: ! 485: if(c->flag&COPEN){ ! 486: lock(&ctl); ! 487: if(--ctl.ref == 0) ! 488: raw = 0; ! 489: unlock(&ctl); ! 490: } ! 491: break; ! 492: case Qauth: ! 493: case Qauthcheck: ! 494: case Qauthent: ! 495: authclose(c); ! 496: break; ! 497: } ! 498: } ! 499: ! 500: long ! 501: consread(Chan *c, void *buf, long n, ulong offset) ! 502: { ! 503: int ch, i, k, id; ! 504: ulong l; ! 505: char *cbuf = buf; ! 506: char *b, *bp; ! 507: char tmp[128]; /* must be >= 6*NUMSIZE */ ! 508: Mach *mp; ! 509: ! 510: if(n <= 0) ! 511: return n; ! 512: switch(c->qid.path & ~CHDIR){ ! 513: case Qdir: ! 514: return devdirread(c, buf, n, consdir, NCONS, devgen); ! 515: ! 516: case Qcons: ! 517: qlock(&kbdq); ! 518: if(waserror()){ ! 519: qunlock(&kbdq); ! 520: nexterror(); ! 521: } ! 522: while(!cangetc(&lineq)){ ! 523: sleep(&kbdq.r, isbrkc, &kbdq); ! 524: do{ ! 525: lock(&lineq); ! 526: ch = getc(&kbdq); ! 527: if(raw) ! 528: goto Default; ! 529: switch(ch){ ! 530: case '\b': ! 531: if(lineq.in != lineq.out){ ! 532: if(lineq.in == lineq.buf) ! 533: lineq.in = lineq.buf+sizeof(lineq.buf); ! 534: lineq.in--; ! 535: } ! 536: break; ! 537: case 0x15: ! 538: lineq.in = lineq.out; ! 539: break; ! 540: Default: ! 541: default: ! 542: *lineq.in = ch; ! 543: if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1) ! 544: lineq.in = lineq.buf; ! 545: else ! 546: lineq.in++; ! 547: } ! 548: unlock(&lineq); ! 549: }while(raw==0 && ch!='\n' && ch!=0x04); ! 550: } ! 551: i = 0; ! 552: while(n > 0){ ! 553: ch = getc(&lineq); ! 554: if(ch==-1 || (raw==0 && ch==0x04)) ! 555: break; ! 556: i++; ! 557: *cbuf++ = ch; ! 558: --n; ! 559: } ! 560: poperror(); ! 561: qunlock(&kbdq); ! 562: return i; ! 563: ! 564: case Qcputime: ! 565: k = offset; ! 566: if(k >= 6*NUMSIZE) ! 567: return 0; ! 568: if(k+n > 6*NUMSIZE) ! 569: n = 6*NUMSIZE - k; ! 570: /* easiest to format in a separate buffer and copy out */ ! 571: for(i=0; i<6 && NUMSIZE*i<k+n; i++){ ! 572: l = u->p->time[i]; ! 573: if(i == TReal) ! 574: l = MACHP(0)->ticks - l; ! 575: l = TK2MS(l); ! 576: readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); ! 577: } ! 578: memmove(buf, tmp+k, n); ! 579: return n; ! 580: ! 581: case Qpgrpid: ! 582: return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE); ! 583: ! 584: case Qpid: ! 585: return readnum(offset, buf, n, u->p->pid, NUMSIZE); ! 586: ! 587: case Qppid: ! 588: return readnum(offset, buf, n, u->p->parentpid, NUMSIZE); ! 589: ! 590: case Qtime: ! 591: return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); ! 592: ! 593: case Qclock: ! 594: k = offset; ! 595: if(k >= 2*NUMSIZE) ! 596: return 0; ! 597: if(k+n > 2*NUMSIZE) ! 598: n = 2*NUMSIZE - k; ! 599: readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE); ! 600: readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE); ! 601: memmove(buf, tmp+k, n); ! 602: return n; ! 603: ! 604: case Qkey: ! 605: return keyread(buf, n, offset); ! 606: ! 607: case Qauth: ! 608: return authread(c, cbuf, n); ! 609: ! 610: case Qauthent: ! 611: return authentread(c, cbuf, n); ! 612: ! 613: case Qhostowner: ! 614: return readstr(offset, buf, n, eve); ! 615: ! 616: case Qhostdomain: ! 617: return readstr(offset, buf, n, hostdomain); ! 618: ! 619: case Quser: ! 620: return readstr(offset, buf, n, u->p->user); ! 621: ! 622: case Qnull: ! 623: return 0; ! 624: ! 625: case Qklog: ! 626: qlock(&klogq); ! 627: if(waserror()){ ! 628: qunlock(&klogq); ! 629: nexterror(); ! 630: } ! 631: while(!cangetc(&klogq)) ! 632: sleep(&klogq.r, cangetc, &klogq); ! 633: for(i=0; i<n; i++){ ! 634: if((ch=getc(&klogq)) == -1) ! 635: break; ! 636: *cbuf++ = ch; ! 637: } ! 638: poperror(); ! 639: qunlock(&klogq); ! 640: return i; ! 641: ! 642: case Qmsec: ! 643: return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); ! 644: ! 645: case Qhz: ! 646: return readnum(offset, buf, n, HZ, NUMSIZE); ! 647: ! 648: case Qsysstat: ! 649: b = smalloc(conf.nmach*(NUMSIZE*8+1) + 1); /* +1 for NUL */ ! 650: bp = b; ! 651: for(id = 0; id < 32; id++) { ! 652: if(active.machs & (1<<id)) { ! 653: mp = MACHP(id); ! 654: readnum(0, bp, NUMSIZE, id, NUMSIZE); ! 655: bp += NUMSIZE; ! 656: readnum(0, bp, NUMSIZE, mp->cs, NUMSIZE); ! 657: bp += NUMSIZE; ! 658: readnum(0, bp, NUMSIZE, mp->intr, NUMSIZE); ! 659: bp += NUMSIZE; ! 660: readnum(0, bp, NUMSIZE, mp->syscall, NUMSIZE); ! 661: bp += NUMSIZE; ! 662: readnum(0, bp, NUMSIZE, mp->pfault, NUMSIZE); ! 663: bp += NUMSIZE; ! 664: readnum(0, bp, NUMSIZE, mp->tlbfault, NUMSIZE); ! 665: bp += NUMSIZE; ! 666: readnum(0, bp, NUMSIZE, mp->tlbpurge, NUMSIZE); ! 667: bp += NUMSIZE; ! 668: readnum(0, bp, NUMSIZE, mp->load, NUMSIZE); ! 669: bp += NUMSIZE; ! 670: *bp++ = '\n'; ! 671: } ! 672: } ! 673: n = readstr(offset, buf, n, b); ! 674: free(b); ! 675: return n; ! 676: ! 677: case Qswap: ! 678: sprint(tmp, "%d/%d memory %d/%d swap\n", ! 679: palloc.user-palloc.freecount, palloc.user, ! 680: conf.nswap-swapalloc.free, conf.nswap); ! 681: ! 682: return readstr(offset, buf, n, tmp); ! 683: ! 684: case Qsysname: ! 685: return readstr(offset, buf, n, sysname); ! 686: ! 687: default: ! 688: print("consread %lux\n", c->qid); ! 689: error(Egreg); ! 690: } ! 691: return -1; /* never reached */ ! 692: } ! 693: ! 694: void ! 695: conslights(char *a, int n) ! 696: { ! 697: char line[128]; ! 698: char *lp; ! 699: int c; ! 700: ! 701: lp = line; ! 702: while(n--){ ! 703: *lp++ = c = *a++; ! 704: if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]) ! 705: break; ! 706: } ! 707: *lp = 0; ! 708: lights(strtoul(line, 0, 0)); ! 709: } ! 710: ! 711: void ! 712: consnoise(char *a, int n) ! 713: { ! 714: int freq; ! 715: int duration; ! 716: char line[128]; ! 717: char *lp; ! 718: int c; ! 719: ! 720: lp = line; ! 721: while(n--){ ! 722: *lp++ = c = *a++; ! 723: if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]){ ! 724: *lp = 0; ! 725: freq = strtoul(line, &lp, 0); ! 726: while(*lp==' ' || *lp=='\t') ! 727: lp++; ! 728: duration = strtoul(lp, &lp, 0); ! 729: buzz(freq, duration); ! 730: lp = line; ! 731: } ! 732: } ! 733: } ! 734: ! 735: long ! 736: conswrite(Chan *c, void *va, long n, ulong offset) ! 737: { ! 738: char cbuf[64]; ! 739: char buf[256]; ! 740: long l, bp; ! 741: char *a = va; ! 742: Mach *mp; ! 743: int id, fd, ch; ! 744: Chan *swc; ! 745: ! 746: switch(c->qid.path){ ! 747: case Qcons: ! 748: l = n; ! 749: while(l > 0){ ! 750: bp = l; ! 751: if(bp > sizeof buf) ! 752: bp = sizeof buf; ! 753: memmove(buf, a, bp); ! 754: putstrn(a, bp); ! 755: a += bp; ! 756: l -= bp; ! 757: } ! 758: break; ! 759: ! 760: case Qconsctl: ! 761: if(n >= sizeof(buf)) ! 762: n = sizeof(buf)-1; ! 763: strncpy(buf, a, n); ! 764: buf[n] = 0; ! 765: if(strncmp(a, "rawon", 5) == 0){ ! 766: lock(&lineq); ! 767: while((ch=getc(&kbdq)) != -1){ ! 768: *lineq.in++ = ch; ! 769: if(lineq.in == lineq.buf+sizeof(lineq.buf)) ! 770: lineq.in = lineq.buf; ! 771: } ! 772: unlock(&lineq); ! 773: lock(&ctl); ! 774: raw = 1; ! 775: unlock(&ctl); ! 776: } ! 777: else ! 778: if(strncmp(a, "rawoff", 6) == 0){ ! 779: lock(&ctl); ! 780: raw = 0; ! 781: unlock(&ctl); ! 782: } ! 783: else ! 784: error(Ebadctl); ! 785: break; ! 786: ! 787: case Qtime: ! 788: if(n<=0 || boottime!=0) /* write once file */ ! 789: return 0; ! 790: if(n >= sizeof cbuf) ! 791: n = sizeof cbuf - 1; ! 792: memmove(cbuf, a, n); ! 793: cbuf[n-1] = 0; ! 794: boottime = strtoul(a, 0, 0)-TK2SEC(MACHP(0)->ticks); ! 795: break; ! 796: ! 797: case Qkey: ! 798: return keywrite(a, n); ! 799: ! 800: case Qhostowner: ! 801: return hostownerwrite(a, n); ! 802: ! 803: case Qhostdomain: ! 804: return hostdomainwrite(a, n); ! 805: ! 806: case Quser: ! 807: return userwrite(a, n); ! 808: ! 809: case Qauth: ! 810: return authwrite(c, a, n); ! 811: ! 812: case Qauthcheck: ! 813: return authcheck(c, a, n); ! 814: ! 815: case Qauthent: ! 816: return authentwrite(c, a, n); ! 817: ! 818: case Qnull: ! 819: break; ! 820: ! 821: case Qnoise: ! 822: consnoise(a, n); ! 823: break; ! 824: ! 825: case Qlights: ! 826: conslights(a, n); ! 827: break; ! 828: ! 829: case Qsysstat: ! 830: for(id = 0; id < 32; id++) { ! 831: if(active.machs & (1<<id)) { ! 832: mp = MACHP(id); ! 833: mp->cs = 0; ! 834: mp->intr = 0; ! 835: mp->syscall = 0; ! 836: mp->pfault = 0; ! 837: mp->tlbfault = 0; ! 838: mp->tlbpurge = 0; ! 839: } ! 840: } ! 841: break; ! 842: ! 843: case Qswap: ! 844: if(n >= sizeof buf) ! 845: error(Egreg); ! 846: memmove(buf, va, n); /* so we can NUL-terminate */ ! 847: buf[n] = 0; ! 848: /* start a pager if not already started */ ! 849: if(strncmp(buf, "start", 5) == 0){ ! 850: kickpager(); ! 851: break; ! 852: } ! 853: if(cpuserver && strcmp(u->p->user, eve) != 0) ! 854: error(Eperm); ! 855: if(buf[0]<'0' || '9'<buf[0]) ! 856: error(Ebadusefd); ! 857: fd = strtoul(buf, 0, 0); ! 858: swc = fdtochan(fd, -1, 1, 0); ! 859: setswapchan(swc); ! 860: break; ! 861: ! 862: case Qsysname: ! 863: if(offset != 0) ! 864: error(Ebadarg); ! 865: if(n <= 0 || n >= NAMELEN) ! 866: error(Ebadarg); ! 867: strncpy(sysname, a, n); ! 868: sysname[n] = 0; ! 869: if(sysname[n-1] == '\n') ! 870: sysname[n-1] = 0; ! 871: break; ! 872: ! 873: default: ! 874: print("conswrite: %d\n", c->qid.path); ! 875: error(Egreg); ! 876: } ! 877: return n; ! 878: } ! 879: ! 880: void ! 881: consremove(Chan *c) ! 882: { ! 883: USED(c); ! 884: error(Eperm); ! 885: } ! 886: ! 887: void ! 888: conswstat(Chan *c, char *dp) ! 889: { ! 890: USED(c, dp); ! 891: error(Eperm); ! 892: } ! 893: ! 894: int ! 895: nrand(int n) ! 896: { ! 897: static ulong randn; ! 898: ! 899: randn = randn*1103515245 + 12345 + MACHP(0)->ticks; ! 900: return (randn>>16) % n; ! 901: } ! 902: ! 903: void ! 904: setterm(char *f) ! 905: { ! 906: char buf[2*NAMELEN]; ! 907: ! 908: sprint(buf, f, conffile); ! 909: ksetenv("terminal", buf); ! 910: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.