static long conswrite(Chan *c, void *va, long n, vlong offset) { char buf[128], *a, ch; int x; if(c->qid.type & QTDIR) error(Eperm); switch((ulong)c->qid.path) { default: error(Egreg); case Qcons: if(canrlock(&kprintq.l)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq.l); nexterror(); } qwrite(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } runlock(&kprintq.l); } return write(1, va, n); case Qsysctl: return sysconwrite(va, n); case Qconsctl: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = 0; for(a = buf; a;){ if(strncmp(a, "rawon", 5) == 0){ kbd.raw = 1; /* clumsy hack - wake up reader */ ch = 0; qwrite(kbdq, &ch, 1); } else if(strncmp(buf, "rawoff", 6) == 0){ kbd.raw = 0; } if((a = strchr(a, ' ')) != nil) a++; } break; case Qkeyboard: for(x=0; x<n; ) { Rune r; x += chartorune(&r, &((char*)va)[x]); gkbdputc(gkbdq, r); } break; case Qnull: break; case Qtime: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = '\0'; timeoffset = strtoll(buf, 0, 0)-osusectime(); break; case Qhostowner: if(!iseve()) error(Eperm); if(offset != 0 || n >= sizeof(buf)) error(Ebadarg); memmove(buf, va, n); buf[n] = '\0'; if(n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; if(n == 0) error(Ebadarg); /* renameuser(eve, buf); */ /* renameproguser(eve, buf); */ kstrdup(&eve, buf); kstrdup(&up->env->user, buf); break; case Quser: if(!iseve()) error(Eperm); if(offset != 0) error(Ebadarg); if(n <= 0 || n >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, n); buf[n] = '\0'; if(n > 0 && buf[n-1] == '\n') buf[--n] = '\0'; if(n == 0) error(Ebadarg); setid(buf, 0); break; case Qhoststdout: return write(1, va, n); case Qhoststderr: return write(2, va, n); case Qjit: if(n >= sizeof(buf)) n = sizeof(buf)-1; strncpy(buf, va, n); buf[n] = '\0'; x = atoi(buf); if(x < 0 || x > 9) error(Ebadarg); cflag = x; break; case Qsysname: if(offset != 0) error(Ebadarg); if(n < 0 || n >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, n); buf[n] = '\0'; if(buf[n-1] == '\n') buf[n-1] = 0; kstrdup(&ossysname, buf); break; } return n; }
long conswrite(Chan *c, void *va, long count, vlong offset) { char buf[128], *p; int x, y; USED(offset); if(c->qid.type & QTDIR) error(Eperm); switch((ulong)c->qid.path) { default: error(Egreg); case Qcons: if(canrlock(&kprintq.l)){ if(kprintq.q != nil){ if(waserror()){ runlock(&kprintq.l); nexterror(); } qwrite(kprintq.q, va, count); poperror(); runlock(&kprintq.l); return count; } runlock(&kprintq.l); } return write(1, va, count); case Qsysctl: return sysconwrite(va, count); case Qconsctl: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = 0; if(strncmp(buf, "rawon", 5) == 0) { kbd.raw = 1; return count; } else if(strncmp(buf, "rawoff", 6) == 0) { kbd.raw = 0; return count; } error(Ebadctl); case Qkeyboard: for(x=0; x<count; ) { Rune r; x += chartorune(&r, &((char*)va)[x]); gkbdputc(gkbdq, r); } return count; case Qpointer: if(count > sizeof buf-1) count = sizeof buf -1; memmove(buf, va, count); buf[count] = 0; p = nil; x = strtoul(buf+1, &p, 0); if(p == nil || p == buf+1) error(Eshort); y = strtoul(p, 0, 0); setpointer(x, y); return count; case Qnull: return count; case Qpin: if(up->env->pgrp->pin != Nopin) error("pin already set"); if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; up->env->pgrp->pin = atoi(buf); return count; case Qtime: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; timeoffset = strtoll(buf, 0, 0)-osusectime(); return count; case Quser: if(count >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, count); buf[count] = '\0'; if(count > 0 && buf[count-1] == '\n') buf[--count] = '\0'; if(count == 0) error(Ebadarg); if(strcmp(up->env->user, eve) != 0) error(Eperm); setid(buf, 0); return count; case Qhostowner: if(count >= sizeof(buf)) error(Ebadarg); strncpy(buf, va, count); buf[count] = '\0'; if(count > 0 && buf[count-1] == '\n') buf[--count] = '\0'; if(count == 0) error(Ebadarg); if(strcmp(up->env->user, eve) != 0) error(Eperm); kstrdup(&eve, buf); return count; case Qhoststdout: return write(1, va, count); case Qhoststderr: return write(2, va, count); case Qjit: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; x = atoi(buf); if (x < 0 || x > 9) error(Ebadarg); cflag = x; return count; case Qsysname: if(count >= sizeof(buf)) count = sizeof(buf)-1; strncpy(buf, va, count); buf[count] = '\0'; kstrdup(&ossysname, buf); return count; case Qsnarf: if(offset+count >= SnarfSize) error(Etoobig); snarftab->qid.vers++; memmove((uchar*)(c->aux)+offset, va, count); return count; } return 0; }