| plan 9 kernel history: overview | file list | diff list |
1992/0318/port/devcons.c (diff list | history)
| port/devcons.c on 1990/0227 | ||
| 1990/0227 | #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1990/0227 | #include "devtab.h" | |
| 1991/0607 | struct { IOQ; /* lock to klogputs */ QLock; /* qlock to getc */ | |
| 1991/0723 | }klogq; | |
| 1990/0227 | ||
| 1991/0607 | IOQ lineq; /* lock to getc; interrupt putc's */ IOQ printq; IOQ mouseq; KIOQ kbdq; | |
| 1990/0227 | ||
| 1991/1224 | static Ref ctl; /* number of opens to the control file */ static int raw; /* true if raw has been requested on a ctl file */ | |
| 1990/0227 | ||
| 1991/1109 | char eve[NAMELEN] = "bootes"; | |
| 1991/1207 | char evekey[DESKEYLEN]; | |
| 1991/1109 | ||
| 1990/0227 | /* | |
| 1991/0607 | * init the queues and set the output routine | |
| 1990/0227 | */ void | |
| 1991/0607 | printinit(void) | |
| 1990/0227 | { | |
| 1991/0607 | initq(&printq); | |
| 1991/0608 | printq.puts = 0; | |
| 1991/0607 | initq(&lineq); initq(&kbdq); kbdq.putc = kbdputc; initq(&klogq); initq(&mouseq); mouseq.putc = mouseputc; | |
| 1990/0227 | } /* | |
| 1991/0809 | * Print a string on the console. Convert \n to \r\n for serial * line consoles. Locking of the queues is left up to the screen * or uart code. Multi-line messages to serial consoles may get * interspersed with other messages. | |
| 1990/0227 | */ void putstrn(char *str, int n) { | |
| 1991/0809 | char buf[PRINTSIZE+2]; int m; | |
| 1990/0227 | char *t; | |
| 1991/0809 | /* * if there's an attached bit mapped display, * put the message there. screenputs is defined * as a null macro for systems that have no such * display. */ screenputs(str, n); /* * if there's a serial line being used as a console, * put the message there. Tack a carriage return * before new lines. */ if(printq.puts == 0) return; | |
| 1990/0227 | while(n > 0){ | |
| 1991/0809 | t = memchr(str, '\n', n); if(t){ m = t - str; memmove(buf, str, m); buf[m] = '\r'; buf[m+1] = '\n'; (*printq.puts)(&printq, buf, m+2); str = t + 1; n -= m + 1; } else { (*printq.puts)(&printq, str, n); break; } | |
| 1990/0227 | } } | |
| 1991/0607 | /* * Print a string in the kernel log. Ignore overflow. */ void klogputs(char *str, long n) | |
| 1990/0227 | { | |
| 1991/0607 | int s, m; uchar *nextin; s = splhi(); lock(&klogq); while(n){ m = &klogq.buf[NQ] - klogq.in; if(m > n) m = n; memmove(klogq.in, str, m); n -= m; str += m; nextin = klogq.in + m; if(nextin >= &klogq.buf[NQ]) klogq.in = klogq.buf; else klogq.in = nextin; } unlock(&klogq); splx(s); wakeup(&klogq.r); | |
| 1990/0227 | } int | |
| 1991/0607 | isbrkc(KIOQ *q) | |
| 1990/0227 | { uchar *p; for(p=q->out; p!=q->in; ){ | |
| 1991/1224 | if(raw) | |
| 1991/0607 | return 1; | |
| 1990/0227 | if(*p==0x04 || *p=='\n') return 1; p++; if(p >= q->buf+sizeof(q->buf)) p = q->buf; } return 0; } int sprint(char *s, char *fmt, ...) { | |
| 1990/06111 | return doprint(s, s+PRINTSIZE, fmt, (&fmt+1)) - s; | |
| 1990/0227 | } int print(char *fmt, ...) { char buf[PRINTSIZE]; int n; | |
| 1990/06111 | n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; | |
| 1990/0227 | putstrn(buf, n); return n; } | |
| 1991/0607 | int kprint(char *fmt, ...) { char buf[PRINTSIZE]; int n; n = doprint(buf, buf+sizeof(buf), fmt, (&fmt+1)) - buf; klogputs(buf, n); return n; } | |
| 1990/0227 | void panic(char *fmt, ...) { char buf[PRINTSIZE]; int n; | |
| 1991/1011 | strcpy(buf, "panic: "); | |
| 1991/0920 | n = doprint(buf+strlen(buf), buf+sizeof(buf), fmt, (&fmt+1)) - buf; | |
| 1990/0227 | buf[n] = '\n'; putstrn(buf, n+1); | |
| 1990/0907 | dumpstack(); | |
| 1991/0608 | if(conf.cntrlp) exit(); else for(;;); | |
| 1990/0227 | } int pprint(char *fmt, ...) { char buf[2*PRINTSIZE]; Chan *c; int n; | |
| 1991/0720 | if(u->p->fgrp == 0) return 0; | |
| 1991/0705 | c = u->p->fgrp->fd[2]; | |
| 1990/0227 | if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) | |
| 1990/0321 | return 0; | |
| 1990/0227 | n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); | |
| 1990/06111 | n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; | |
| 1991/0411 | qlock(&c->wrl); | |
| 1990/0227 | if(waserror()){ | |
| 1991/0411 | qunlock(&c->wrl); | |
| 1990/0321 | return 0; | |
| 1990/0227 | } | |
| 1991/0411 | (*devtab[c->type].write)(c, buf, n, c->offset); | |
| 1990/0227 | c->offset += n; | |
| 1991/0411 | qunlock(&c->wrl); | |
| 1990/0321 | poperror(); | |
| 1990/0227 | return n; } void prflush(void) { | |
| 1991/0607 | while(printq.in != printq.out) ; | |
| 1990/0227 | } void | |
| 1991/1223 | echo(Rune r, char *buf, int n) | |
| 1990/0227 | { | |
| 1991/0607 | static int ctrlt; | |
| 1990/03091 | ||
| 1990/0227 | /* | |
| 1991/0607 | * ^p hack | |
| 1990/0227 | */ | |
| 1991/1223 | if(r==0x10 && conf.cntrlp) | |
| 1991/0327 | panic("^p"); | |
| 1991/0608 | ||
| 1991/0607 | /* * ^t hack BUG */ if(ctrlt == 2){ ctrlt = 0; | |
| 1991/1223 | switch(r){ | |
| 1991/0607 | case 0x14: break; /* pass it on */ case 'm': mntdump(); return; case 'p': | |
| 1991/0608 | procdump(); | |
| 1991/0607 | return; case 'q': dumpqueues(); return; case 'r': exit(); break; } | |
| 1991/1223 | }else if(r == 0x14){ | |
| 1991/0607 | ctrlt++; return; } ctrlt = 0; | |
| 1991/1224 | if(raw) | |
| 1991/0607 | return; | |
| 1991/1223 | if(r == 0x15) | |
| 1990/0227 | putstrn("^U\n", 3); | |
| 1991/1223 | else putstrn(buf, n); | |
| 1990/0227 | } /* | |
| 1991/1206 | * turn '\r' into '\n' before putting it into the queue | |
| 1991/0727 | */ int kbdcr2nl(IOQ *q, int ch) { if(ch == '\r') ch = '\n'; return kbdputc(q, ch); } /* | |
| 1991/1223 | * Put character, possibly a rune, into read queue at interrupt time. | |
| 1991/1206 | * Always called splhi from processor 0. | |
| 1990/0227 | */ | |
| 1991/0607 | int kbdputc(IOQ *q, int ch) | |
| 1990/0227 | { | |
| 1991/1223 | int i, n; char buf[3]; Rune r; | |
| 1991/1115 | USED(q); | |
| 1991/1223 | r = ch; n = runetochar(buf, &r); if(n == 0) return 0; echo(r, buf, n); kbdq.c = r; for(i=0; i<n; i++){ *kbdq.in++ = buf[i]; if(kbdq.in == kbdq.buf+sizeof(kbdq.buf)) kbdq.in = kbdq.buf; } | |
| 1991/1224 | if(raw || r=='\n' || r==0x04) | |
| 1990/0227 | wakeup(&kbdq.r); | |
| 1991/0607 | return 0; | |
| 1990/0227 | } void | |
| 1991/0607 | kbdrepeat(int rep) | |
| 1990/0227 | { | |
| 1991/0607 | kbdq.repeat = rep; kbdq.count = 0; } | |
| 1990/0227 | ||
| 1991/0607 | void kbdclock(void) { if(kbdq.repeat == 0) return; if(kbdq.repeat==1 && ++kbdq.count>HZ){ kbdq.repeat = 2; kbdq.count = 0; return; | |
| 1990/0227 | } | |
| 1991/0607 | if(++kbdq.count&1) kbdputc(&kbdq, kbdq.c); | |
| 1990/0227 | } int consactive(void) { return printq.in != printq.out; } enum{ Qdir, Qcons, | |
| 1991/1224 | Qconsctl, | |
| 1990/0227 | Qcputime, | |
| 1991/0607 | Qlights, Qnoise, | |
| 1990/0227 | Qnull, Qpgrpid, Qpid, Qppid, Qtime, Quser, | |
| 1991/0607 | Qklog, Qmsec, Qclock, | |
| 1991/0425 | Qsysstat, | |
| 1991/0705 | Qswap, | |
| 1991/1127 | Qcrypt, Qkey, Qchal, | |
| 1990/0227 | }; Dirtab consdir[]={ | |
| 1991/1211 | "cons", {Qcons}, 0, 0660, | |
| 1991/1224 | "consctl", {Qconsctl}, 0, 0220, | |
| 1991/1127 | "cputime", {Qcputime}, 6*NUMSIZE, 0444, | |
| 1991/1211 | "time", {Qtime}, NUMSIZE, 0664, | |
| 1991/1127 | "clock", {Qclock}, 2*NUMSIZE, 0444, "msec", {Qmsec}, NUMSIZE, 0444, | |
| 1991/1211 | "lights", {Qlights}, 0, 0220, "noise", {Qnoise}, 0, 0220, | |
| 1991/1112 | "null", {Qnull}, 0, 0666, | |
| 1991/1127 | "pgrpid", {Qpgrpid}, NUMSIZE, 0444, "pid", {Qpid}, NUMSIZE, 0444, "ppid", {Qppid}, NUMSIZE, 0444, "user", {Quser}, 0, 0666, "chal", {Qchal}, 8, 0666, "crypt", {Qcrypt}, 0, 0666, | |
| 1991/1207 | "key", {Qkey}, DESKEYLEN, 0222, | |
| 1991/1112 | "klog", {Qklog}, 0, 0444, | |
| 1991/1127 | "sysstat", {Qsysstat}, 0, 0666, | |
| 1991/1211 | "swap", {Qswap}, 0, 0664, | |
| 1990/0227 | }; #define NCONS (sizeof consdir/sizeof(Dirtab)) ulong boottime; /* seconds since epoch at boot */ long seconds(void) { | |
| 1990/0620 | return boottime + TK2SEC(MACHP(0)->ticks); | |
| 1990/0227 | } int readnum(ulong off, char *buf, ulong n, ulong val, int size) { char tmp[64]; | |
| 1992/0318 | Op op = (Op){ tmp, tmp+sizeof(tmp), &val, size-1, 0, FUNSIGN|FLONG }; | |
| 1990/0227 | numbconv(&op, 10); tmp[size-1] = ' '; | |
| 1990/0312 | if(off >= size) return 0; | |
| 1990/0227 | if(off+n > size) n = size-off; | |
| 1991/0318 | memmove(buf, tmp+off, n); | |
| 1990/0227 | return n; } int readstr(ulong off, char *buf, ulong n, char *str) { int size; size = strlen(str); | |
| 1990/0312 | if(off >= size) return 0; | |
| 1990/0227 | if(off+n > size) n = size-off; | |
| 1991/0318 | memmove(buf, str+off, n); | |
| 1990/0227 | return n; } void consreset(void) { } void consinit(void) { } Chan* consattach(char *spec) { return devattach('c', spec); } Chan* consclone(Chan *c, Chan *nc) { return devclone(c, nc); } int conswalk(Chan *c, char *name) { return devwalk(c, name, consdir, NCONS, devgen); } void consstat(Chan *c, char *dp) { devstat(c, dp, consdir, NCONS, devgen); } Chan* consopen(Chan *c, int omode) { | |
| 1991/0607 | switch(c->qid.path){ | |
| 1991/1224 | case Qconsctl: | |
| 1991/1211 | if(strcmp(u->p->user, eve) != 0) | |
| 1991/0620 | error(Eperm); | |
| 1991/1224 | incref(&ctl); | |
| 1991/0607 | break; | |
| 1990/0227 | } | |
| 1991/1127 | c->aux = 0; | |
| 1990/0227 | return devopen(c, omode, consdir, NCONS, devgen); } void conscreate(Chan *c, char *name, int omode, ulong perm) { | |
| 1991/1115 | USED(c, name, omode, perm); | |
| 1990/11211 | error(Eperm); | |
| 1990/0227 | } void consclose(Chan *c) { | |
| 1991/1224 | /* last close of control file turns off raw */ if(c->qid.path==Qconsctl && (c->flag&COPEN)){ lock(&ctl); if(--ctl.ref == 0) raw = 0; unlock(&ctl); } | |
| 1991/1127 | if(c->qid.path == Qcrypt && c->aux) freeb(c->aux); c->aux = 0; | |
| 1990/0227 | } long | |
| 1991/0411 | consread(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1991/0425 | int ch, i, j, k, id; | |
| 1990/0227 | ulong l; uchar *out; char *cbuf = buf; | |
| 1991/1127 | char *user, *chal; | |
| 1990/0227 | int userlen; | |
| 1991/1127 | Block *cb; | |
| 1991/1113 | char tmp[6*NUMSIZE], xbuf[512]; | |
| 1991/0425 | Mach *mp; | |
| 1990/0227 | if(n <= 0) return n; | |
| 1990/11211 | switch(c->qid.path & ~CHDIR){ | |
| 1990/0227 | case Qdir: return devdirread(c, buf, n, consdir, NCONS, devgen); case Qcons: qlock(&kbdq); | |
| 1990/0617 | if(waserror()){ qunlock(&kbdq); nexterror(); } | |
| 1990/0227 | while(!cangetc(&lineq)){ | |
| 1991/0607 | sleep(&kbdq.r, isbrkc, &kbdq); | |
| 1990/0227 | do{ | |
| 1991/0607 | lock(&lineq); | |
| 1990/0227 | ch = getc(&kbdq); | |
| 1991/1224 | if(raw){ | |
| 1991/0607 | unlock(&lineq); goto Default; } | |
| 1990/0227 | switch(ch){ case '\b': if(lineq.in != lineq.out){ if(lineq.in == lineq.buf) lineq.in = lineq.buf+sizeof(lineq.buf); lineq.in--; } break; case 0x15: lineq.in = lineq.out; break; | |
| 1991/0607 | Default: | |
| 1990/0227 | default: | |
| 1991/0607 | *lineq.in = ch; if(lineq.in >= lineq.buf+sizeof(lineq.buf)-1) lineq.in = lineq.buf; else lineq.in++; | |
| 1990/0227 | } | |
| 1991/0607 | unlock(&lineq); | |
| 1991/1224 | }while(raw==0 && ch!='\n' && ch!=0x04); | |
| 1990/0227 | } i = 0; | |
| 1991/0607 | while(n > 0){ | |
| 1990/0227 | ch = getc(&lineq); | |
| 1991/1224 | if(ch==-1 || (raw==0 && ch==0x04)) | |
| 1990/0227 | break; i++; *cbuf++ = ch; --n; } | |
| 1991/0614 | poperror(); | |
| 1990/0227 | qunlock(&kbdq); return i; case Qcputime: | |
| 1991/0411 | k = offset; | |
| 1990/0312 | if(k >= sizeof tmp) return 0; | |
| 1990/0227 | if(k+n > sizeof tmp) n = sizeof tmp - k; /* easiest to format in a separate buffer and copy out */ for(i=0; i<6 && NUMSIZE*i<k+n; i++){ l = u->p->time[i]; if(i == TReal) l = MACHP(0)->ticks - l; | |
| 1990/0614 | l = TK2MS(l); | |
| 1990/0227 | readnum(0, tmp+NUMSIZE*i, NUMSIZE, l, NUMSIZE); } | |
| 1991/0318 | memmove(buf, tmp+k, n); | |
| 1990/0227 | return n; case Qpgrpid: | |
| 1991/0411 | return readnum(offset, buf, n, u->p->pgrp->pgrpid, NUMSIZE); | |
| 1990/0227 | case Qpid: | |
| 1991/0411 | return readnum(offset, buf, n, u->p->pid, NUMSIZE); | |
| 1990/0227 | case Qppid: | |
| 1991/0411 | return readnum(offset, buf, n, u->p->parentpid, NUMSIZE); | |
| 1990/0227 | case Qtime: | |
| 1991/0411 | return readnum(offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12); | |
| 1990/0227 | ||
| 1991/0607 | case Qclock: k = offset; if(k >= 2*NUMSIZE) return 0; if(k+n > 2*NUMSIZE) n = 2*NUMSIZE - k; readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE); readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE); memmove(buf, tmp+k, n); return n; | |
| 1991/1127 | case Qcrypt: cb = c->aux; if(!cb) return 0; if(n > cb->wptr - cb->base) n = cb->wptr - cb->base; memmove(buf, cb->base, n); return n; case Qchal: if(offset != 0 || n != 8) error(Ebadarg); chal = u->p->pgrp->crypt->chal; | |
| 1992/0318 | chal[0] = RXschal; | |
| 1991/1127 | for(i=1; i<8; i++) chal[i] = nrand(256); memmove(buf, chal, 8); encrypt(evekey, buf, 8); | |
| 1992/0318 | chal[0] = RXstick; | |
| 1991/1127 | return n; | |
| 1990/0227 | case Quser: | |
| 1991/1105 | return readstr(offset, buf, n, u->p->user); | |
| 1990/0227 | ||
| 1991/0607 | case Qnull: return 0; | |
| 1990/0720 | ||
| 1991/0607 | case Qklog: qlock(&klogq); if(waserror()){ qunlock(&klogq); nexterror(); } while(!cangetc(&klogq)) sleep(&klogq.r, cangetc, &klogq); for(i=0; i<n; i++){ if((ch=getc(&klogq)) == -1) break; *cbuf++ = ch; } poperror(); qunlock(&klogq); return i; case Qmsec: return readnum(offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE); | |
| 1991/0425 | case Qsysstat: j = 0; | |
| 1991/1113 | xbuf[0] = 0; | |
| 1991/0425 | for(id = 0; id < 32; id++) { if(active.machs & (1<<id)) { mp = MACHP(id); j += sprint(&xbuf[j], "%d %d %d %d %d %d %d %d\n", id, mp->cs, mp->intr, mp->syscall, mp->pfault, | |
| 1991/1112 | mp->tlbfault, mp->tlbpurge, mp->load); | |
| 1991/0425 | } } return readstr(offset, buf, n, xbuf); | |
| 1990/0227 | ||
| 1991/0705 | case Qswap: sprint(xbuf, "%d/%d memory %d/%d swap\n", palloc.user-palloc.freecount, palloc.user, conf.nswap-swapalloc.free, conf.nswap); return readstr(offset, buf, n, xbuf); | |
| 1990/0227 | default: | |
| 1991/1127 | print("consread %lux\n", c->qid); error(Egreg); | |
| 1990/0227 | } } | |
| 1991/0607 | void conslights(char *a, int n) { int l; char line[128]; char *lp; int c; lp = line; while(n--){ *lp++ = c = *a++; if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]) break; } *lp = 0; lights(strtoul(line, 0, 0)); } void consnoise(char *a, int n) { int freq; int duration; char line[128]; char *lp; int c; lp = line; while(n--){ *lp++ = c = *a++; if(c=='\n' || n==0 || lp==&line[sizeof(line)-1]){ *lp = 0; freq = strtoul(line, &lp, 0); while(*lp==' ' || *lp=='\t') lp++; duration = strtoul(lp, &lp, 0); buzz(freq, duration); lp = line; } } } | |
| 1990/0227 | long | |
| 1991/0411 | conswrite(Chan *c, void *va, long n, ulong offset) | |
| 1990/0227 | { char cbuf[64]; char buf[256]; | |
| 1991/1116 | long l, bp; | |
| 1990/0227 | char *a = va; | |
| 1991/1127 | Block *cb; | |
| 1991/0425 | Mach *mp; | |
| 1991/1224 | int id, fd, ch; | |
| 1991/0705 | Chan *swc; | |
| 1990/0227 | ||
| 1990/11211 | switch(c->qid.path){ | |
| 1990/0227 | case Qcons: /* | |
| 1991/1206 | * Can't page fault in putstrn, so copy the data locally. | |
| 1990/0227 | */ l = n; while(l > 0){ | |
| 1991/1116 | bp = l; if(bp > sizeof buf) bp = sizeof buf; memmove(buf, a, bp); putstrn(a, bp); a += bp; l -= bp; | |
| 1991/1224 | } break; case Qconsctl: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, a, n); buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ lock(&lineq); while((ch=getc(&kbdq)) != -1){ *lineq.in++ = ch; if(lineq.in == lineq.buf+sizeof(lineq.buf)) lineq.in = lineq.buf; } unlock(&lineq); lock(&ctl); raw = 1; unlock(&ctl); } else if(strncmp(a, "rawoff", 6) == 0){ lock(&ctl); raw = 0; unlock(&ctl); } if(a = strchr(a, ' ')) a++; | |
| 1990/0227 | } break; case Qtime: | |
| 1991/1206 | if(n<=0 || boottime!=0) /* write once file */ | |
| 1990/0227 | return 0; if(n >= sizeof cbuf) n = sizeof cbuf - 1; | |
| 1991/0318 | memmove(cbuf, a, n); | |
| 1990/0227 | cbuf[n-1] = 0; boottime = strtoul(a, 0, 0); break; | |
| 1991/1127 | case Qcrypt: cb = c->aux; if(!cb){ cb = c->aux = allocb(128); cb->type = 'E'; } if(n < 8){ if(n != 1 || a[0] != 'E' && a[0] != 'D') error(Ebadarg); cb->type = a[0]; return 1; } if(n > cb->lim - cb->base) n = cb->lim - cb->base; memmove(cb->base, a, n); cb->wptr = cb->base + n; if(cb->type == 'E') encrypt(u->p->pgrp->crypt->key, cb->base, n); else decrypt(u->p->pgrp->crypt->key, cb->base, n); break; case Qkey: | |
| 1991/1207 | if(n != DESKEYLEN) | |
| 1991/1127 | error(Ebadarg); | |
| 1991/1207 | memmove(u->p->pgrp->crypt->key, a, DESKEYLEN); | |
| 1991/1127 | if(strcmp(u->p->user, eve) == 0) | |
| 1991/1207 | memmove(evekey, a, DESKEYLEN); | |
| 1991/1127 | break; | |
| 1990/0227 | case Quser: | |
| 1991/1127 | if(offset != 0 || n >= NAMELEN-1) error(Ebadarg); if(n==strlen("none") && strncmp(a, "none", n)==0 || n==strlen(u->p->user) && strncmp(a, u->p->user, n)==0 || strcmp(u->p->user, eve)==0){ memmove(u->p->user, a, n); u->p->user[n] = '\0'; }else error(Eperm); | |
| 1991/1220 | if(!conf.cntrlp && strcmp(eve, "bootes") == 0) | |
| 1991/1127 | memmove(eve, u->p->user, NAMELEN); | |
| 1990/0227 | break; | |
| 1991/1127 | case Qchal: if(offset != 0) error(Ebadarg); | |
| 1991/1207 | if(n != 8+NAMELEN+DESKEYLEN) | |
| 1991/1127 | error(Ebadarg); decrypt(evekey, a, n); if(memcmp(u->p->pgrp->crypt->chal, a, 8) != 0) | |
| 1992/0114 | error(Eperm); | |
| 1991/1127 | strncpy(u->p->user, a+8, NAMELEN); u->p->user[NAMELEN-1] = '\0'; | |
| 1992/0129 | memmove(u->p->pgrp->crypt->key, a+8+NAMELEN, DESKEYLEN); | |
| 1991/1127 | break; | |
| 1990/0227 | case Qnull: break; | |
| 1990/11161 | ||
| 1991/0607 | case Qnoise: consnoise(a, n); | |
| 1990/11161 | break; | |
| 1991/0607 | case Qlights: conslights(a, n); break; | |
| 1991/0425 | case Qsysstat: for(id = 0; id < 32; id++) { if(active.machs & (1<<id)) { mp = MACHP(id); mp->cs = 0; mp->intr = 0; mp->syscall = 0; mp->pfault = 0; mp->tlbfault = 0; mp->tlbpurge = 0; } } break; | |
| 1991/0705 | case Qswap: if(n >= sizeof buf) error(Egreg); memmove(buf, va, n); /* so we can NUL-terminate */ buf[n] = 0; | |
| 1992/0310 | if(strncmp(buf, "start", 5) == 0){ kickpager(); /* start a pager if not already started */ break; } if(conf.cntrlp && strcmp(u->p->user, eve) != 0) error(Eperm); if(buf[0]<'0' || '9'<buf[0]) | |
| 1992/0228 | error(Ebadarg); | |
| 1991/0705 | fd = strtoul(buf, 0, 0); | |
| 1991/1011 | swc = fdtochan(fd, -1, 1); | |
| 1991/0705 | setswapchan(swc); | |
| 1992/0310 | break; | |
| 1991/0607 | ||
| 1990/0227 | default: | |
| 1991/1127 | print("conswrite: %d\n", c->qid.path); | |
| 1990/11211 | error(Egreg); | |
| 1990/0227 | } return n; } void consremove(Chan *c) { | |
| 1991/1115 | USED(c); | |
| 1990/11211 | error(Eperm); | |
| 1990/0227 | } void conswstat(Chan *c, char *dp) { | |
| 1991/1127 | USED(c, dp); | |
| 1990/11211 | error(Eperm); | |
| 1991/1127 | } /* | |
| 1991/1206 | * Rand is huge and not worth it here. Be small. * Borrowed from the white book. | |
| 1991/1127 | */ int nrand(int n) { | |
| 1992/0312 | static ulong randn; randn = randn*1103515245 + 12345 + MACHP(0)->ticks; | |
| 1991/1127 | return (randn>>16) % n; | |
| 1990/0227 | } | |
| 1991/1102 | void setterm(char *f) { char buf[2*NAMELEN]; sprint(buf, f, conffile); ksetenv("terminal", buf); } | |