Annotation of lucent/sys/src/9/port/devcons.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.