void main(int argc, char **argv) { int stdio, srvfd, pipefd[2]; rep = malloc(sizeof(Fcall)); req = malloc(Reqsize); if(rep == nil || req == nil) panic("out of memory"); stdio = 0; ARGBEGIN{ case ':': trspaces = 1; break; case 'r': readonly = 1; break; case 'v': ++chatty; break; case 'f': deffile = ARGF(); break; case 's': stdio = 1; break; case 'p': doabort = 1; break; default: usage(); }ARGEND if(argc == 0) strcpy(srvfile, "#s/dos"); else if(argc == 1) snprint(srvfile, sizeof srvfile, "#s/%s", argv[0]); else usage(); if(stdio){ pipefd[0] = 0; pipefd[1] = 1; }else{ close(0); close(1); open("/dev/null", OREAD); open("/dev/null", OWRITE); if(pipe(pipefd) < 0) panic("pipe"); srvfd = create(srvfile, OWRITE|ORCLOSE, 0600); if(srvfd < 0) panic(srvfile); fprint(srvfd, "%d", pipefd[0]); close(pipefd[0]); atexit(rmservice); fprint(2, "%s: serving %s\n", argv0, srvfile); } srvfd = pipefd[1]; switch(rfork(RFNOWAIT|RFNOTEG|RFFDG|RFPROC|RFNAMEG)){ case -1: panic("fork"); default: _exits(0); case 0: break; } iotrack_init(); if(!chatty){ close(2); open("#c/cons", OWRITE); } io(srvfd); exits(0); }
static int32_t cmdread(Chan *ch, void *a, int32_t n, int64_t offset) { Proc *up = externup(); Conv *c; Proc *p; char *s, *cmds; int fd; char buf[256]; USED(offset); s = a; switch(TYPE(ch->qid)) { default: error(Eperm); case Qcmd: case Qtopdir: case Qconvdir: return devdirread(ch, a, n, 0, 0, cmdgen); case Qctl: sprint(up->genbuf, "%ld", CONV(ch->qid)); return readstr(offset, s, n, up->genbuf); case Qalloc: c = cmd.conv[CONV(ch->qid)]; p = c->p; snprint(buf, sizeof(buf), "%#p %#p %#p %#p %#p %#p %#p %#p", p->seg[TSEG]->base, p->seg[TSEG]->top, p->seg[DSEG]->base, p->seg[DSEG]->top, p->seg[BSEG]->base, p->seg[BSEG]->top, p->seg[SSEG]->base, p->seg[SSEG]->top); return readstr(offset, s, n, buf); case Qexec: c = cmd.conv[CONV(ch->qid)]; snprint(up->genbuf, sizeof(up->genbuf), "%ld", c->esz); return readstr(offset, s, n, up->genbuf); case Qstatus: c = cmd.conv[CONV(ch->qid)]; cmds = ""; if(c->cmd != nil) cmds = c->cmd->f[1]; snprint(up->genbuf, sizeof(up->genbuf), "cmd/%d %d %s %q %q\n", c->x, c->inuse, c->state, c->dir, cmds); return readstr(offset, s, n, up->genbuf); case Qdata: case Qstderr: fd = 1; if(TYPE(ch->qid) == Qstderr) fd = 2; c = cmd.conv[CONV(ch->qid)]; qlock(&c->l); if(c->fd[fd] == -1){ qunlock(&c->l); return 0; } qunlock(&c->l); // osenter(); // n = read(c->fd[fd], a, n); // osleave(); // if(n < 0) // oserror(); return n; case Qwait: c = cmd.conv[CONV(ch->qid)]; return qread(c->waitq, a, n); } }
static int gzipf(char *file, int stdout) { Dir *dir; char ofile[256], *f, *s; int ifd, ofd, ok; ifd = open(file, OREAD); if(ifd < 0){ fprint(2, "gzip: can't open %s: %r\n", file); return 0; } dir = dirfstat(ifd); if(dir == nil){ fprint(2, "gzip: can't stat %s: %r\n", file); close(ifd); return 0; } if(dir->mode & DMDIR){ fprint(2, "gzip: can't compress a directory\n"); close(ifd); free(dir); return 0; } if(stdout){ ofd = 1; strcpy(ofile, "<stdout>"); }else{ f = strrchr(file, '/'); if(f != nil) f++; else f = file; s = strrchr(f, '.'); if(s != nil && s != ofile && strcmp(s, ".tar") == 0){ *s = '\0'; snprint(ofile, sizeof(ofile), "%s.tgz", f); }else snprint(ofile, sizeof(ofile), "%s.gz", f); ofd = create(ofile, OWRITE, 0666); if(ofd < 0){ fprint(2, "gzip: can't open %s: %r\n", ofile); close(ifd); return 0; } } if(verbose) fprint(2, "compressing %s to %s\n", file, ofile); Binit(&bout, ofd, OWRITE); ok = gzip(file, dir->mtime, ifd, &bout); if(!ok || Bflush(&bout) < 0){ fprint(2, "gzip: error writing %s: %r\n", ofile); if(!stdout) remove(ofile); } Bterm(&bout); free(dir); close(ifd); close(ofd); return ok; }
static void cmparena(char *name, vlong len) { ArenaHead head; DigestState s; u64int n, e; u32int bs; int i, j; char buf[20]; fprint(2, "cmp %s\n", name); memset(&s, 0, sizeof s); /* * read a little bit, which will include the header */ if(readblock(fd, data, HeadSize) < 0){ fprint(2, "%s: reading header: %r\n", name); return; } if(unpackarenahead(&head, data) < 0){ fprint(2, "%s: corrupt arena header: %r\n", name); return; } if(head.version != ArenaVersion4 && head.version != ArenaVersion5) fprint(2, "%s: warning: unknown arena version %d\n", name, head.version); if(len != 0 && len != head.size) fprint(2, "%s: warning: unexpected length %lld != %lld\n", name, head.size, len); if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0) fprint(2, "%s: warning: unexpected name %s\n", name, head.name); if(readblock(fd1, data1, HeadSize) < 0){ fprint(2, "%s: reading header: %r\n", name); return; } if(unpackarenahead(&head, data) < 0){ fprint(2, "%s: corrupt arena header: %r\n", name); return; } if(head.version != ArenaVersion4 && head.version != ArenaVersion5) fprint(2, "%s: warning: unknown arena version %d\n", name, head.version); if(len != 0 && len != head.size) fprint(2, "%s: warning: unexpected length %lld != %lld\n", name, head.size, len); if(strcmp(name, "<stdin>") != 0 && strcmp(head.name, name) != 0) fprint(2, "%s: warning: unexpected name %s\n", name, head.name); seek(fd, -HeadSize, 1); seek(fd1, -HeadSize, 1); if(printheader(name, &head, fd) < 0) return; /* * now we know how much to read * read everything but the last block, which is special */ e = head.size; bs = blocksize; for(n = 0; n < e; n += bs){ if(n + bs > e) bs = e - n; if(readblock(fd, data, bs) < 0){ fprint(2, "%s: read data: %r\n", name); return; } if(readblock(fd1, data1, bs) < 0){ fprint(2, "%s: read data: %r\n", name); return; } if(memcmp(data, data1, bs) != 0){ print("mismatch at %llx\n", n); for(i=0; i<bs; i+=16){ if(memcmp(data+i, data1+i, 16) != 0){ snprint(buf, sizeof buf, "%llx", n+i); print("%s ", buf); for(j=0; j<16; j++){ print(" %.2ux", data[i+j]); if(j == 7) print(" -"); } print("\n"); print("%*s ", (int)strlen(buf), ""); for(j=0; j<16; j++){ print(" %.2ux", data1[i+j]); if(j == 7) print(" -"); } print("\n"); } } } } }
void challengebox(Ticketreq *tr) { long chal; char *key, *netkey; char kbuf[DESKEYLEN], nkbuf[DESKEYLEN], hkey[DESKEYLEN]; char buf[NETCHLEN+1]; char *err; key = findkey(KEYDB, tr->uid, kbuf); netkey = findkey(NETKEYDB, tr->uid, nkbuf); if(key == 0 && netkey == 0){ /* make one up so caller doesn't know it was wrong */ mkkey(nkbuf); netkey = nkbuf; if(debug) syslog(0, AUTHLOG, "cr-fail uid %s@%s", tr->uid, raddr); } if(findkey(KEYDB, tr->hostid, hkey) == 0){ /* make one up so caller doesn't know it was wrong */ mkkey(hkey); if(debug) syslog(0, AUTHLOG, "cr-fail hostid %s %s@%s", tr->hostid, tr->uid, raddr); } /* * challenge-response */ memset(buf, 0, sizeof(buf)); buf[0] = AuthOK; chal = lnrand(MAXNETCHAL); snprint(buf+1, sizeof buf - 1, "%lud", chal); if(write(1, buf, NETCHLEN+1) < 0) exits(0); if(readn(0, buf, NETCHLEN) < 0) exits(0); if(!(key && netcheck(key, chal, buf)) && !(netkey && netcheck(netkey, chal, buf)) && (err = secureidcheck(tr->uid, buf)) != nil){ replyerror("cr-fail %s %s %s", err, tr->uid, raddr); logfail(tr->uid); if(debug) syslog(0, AUTHLOG, "cr-fail %s@%s(%s): bad resp", tr->uid, tr->hostid, raddr); return; } succeed(tr->uid); /* * reply with ticket & authenticator */ if(tickauthreply(tr, hkey) < 0){ if(debug) syslog(0, AUTHLOG, "cr-fail %s@%s(%s): hangup", tr->uid, tr->hostid, raddr); exits(0); } if(debug) syslog(0, AUTHLOG, "cr-ok %s@%s(%s)", tr->uid, tr->hostid, raddr); }
static int32_t capwrite(Chan *c, void *va, int32_t n, int64_t m) { Caphash *p; char *cp; uint8_t hash[Hashlen]; char *key, *from, *to; char err[256]; Proc *up = externup(); switch((uint32_t)c->qid.path){ case Qhash: if(!iseve()) error(Eperm); if(n < Hashlen) error(Eshort); memmove(hash, va, Hashlen); addcap(hash); break; case Quse: /* copy key to avoid a fault in hmac_xx */ cp = nil; if(waserror()){ free(cp); nexterror(); } cp = smalloc(n+1); memmove(cp, va, n); cp[n] = 0; from = cp; key = strrchr(cp, '@'); if(key == nil) error(Eshort); *key++ = 0; hmac_sha1((uint8_t*)from, strlen(from), (uint8_t*)key, strlen(key), hash, nil); p = remcap(hash); if(p == nil){ snprint(err, sizeof err, "invalid capability %s@%s", from, key); error(err); } /* if a from user is supplied, make sure it matches */ to = strchr(from, '@'); if(to == nil){ to = from; } else { *to++ = 0; if(strcmp(from, up->user) != 0) error("capability must match user"); } /* set user id */ kstrdup(&up->user, to); up->basepri = PriNormal; free(p); free(cp); poperror(); break; default: error(Eperm); break; } return n; }
static int progheap(Heapqry *hq, char *va, int count, ulong offset) { WORD *w; void *p; List *hd; Array *a; char *fmt, *str; Module *m; Modlink *ml; Channel *c; ulong addr; String *ss; union { REAL r; LONG l; WORD w[2]; } rock; int i, s, n, len, signed_off; Type *t; n = 0; s = 0; signed_off = offset; addr = hq->addr; for(i = 0; i < hq->count; i++) { switch(hq->fmt) { case 'W': if(addr & 3) return -1; n += snprint(va+n, count-n, "%d\n", *(WORD*)addr); s = sizeof(WORD); break; case 'B': n += snprint(va+n, count-n, "%d\n", *(BYTE*)addr); s = sizeof(BYTE); break; case 'V': if(addr & 3) return -1; w = (WORD*)addr; rock.w[0] = w[0]; rock.w[1] = w[1]; n += snprint(va+n, count-n, "%lld\n", rock.l); s = sizeof(LONG); break; case 'R': if(addr & 3) return -1; w = (WORD*)addr; rock.w[0] = w[0]; rock.w[1] = w[1]; n += snprint(va+n, count-n, "%g\n", rock.r); s = sizeof(REAL); break; case 'I': if(addr & 3) return -1; for(m = modules; m != nil; m = m->link) if(m == (Module*)hq->module) break; if(m == nil) error(Ebadctl); addr = (ulong)(m->prog+addr); n += snprint(va+n, count-n, "%D\n", (Inst*)addr); s = sizeof(Inst); break; case 'P': if(addr & 3) return -1; p = *(void**)addr; fmt = "nil\n"; if(p != H) fmt = "%lux\n"; n += snprint(va+n, count-n, fmt, p); s = sizeof(WORD); break; case 'L': if(addr & 3) return -1; hd = *(List**)addr; if(hd == H || D2H(hd)->t != &Tlist) return -1; n += snprint(va+n, count-n, "%lux.%lux\n", (ulong)&hd->tail, (ulong)hd->data); s = sizeof(WORD); break; case 'A': if(addr & 3) return -1; a = *(Array**)addr; if(a == H) n += snprint(va+n, count-n, "nil\n"); else { if(D2H(a)->t != &Tarray) return -1; n += snprint(va+n, count-n, "%d.%lux\n", a->len, (ulong)a->data); } s = sizeof(WORD); break; case 'C': if(addr & 3) return -1; ss = *(String**)addr; if(ss == H) ss = &snil; else if(D2H(ss)->t != &Tstring) return -1; n += snprint(va+n, count-n, "%d.", abs(ss->len)); str = string2c(ss); len = strlen(str); if(count-n < len) len = count-n; if(len > 0) { memmove(va+n, str, len); n += len; } break; case 'M': if(addr & 3) return -1; ml = *(Modlink**)addr; fmt = ml == H ? "nil\n" : "%lux\n"; n += snprint(va+n, count-n, fmt, ml->MP); s = sizeof(WORD); break; case 'c': if(addr & 3) return -1; c = *(Channel**)addr; if(c == H) n += snprint(va+n, count-n, "nil\n"); else{ t = D2H(c)->t; if(t != &Tchannel && t != Trdchan && t != Twrchan) return -1; if(c->buf == H) n += snprint(va+n, count-n, "0.%lux\n", (ulong)c); else n += snprint(va+n, count-n, "%d.%lux.%d.%d\n", c->buf->len, (ulong)c->buf->data, c->front, c->size); } break; } addr += s; if(signed_off > 0) { signed_off -= n; if(signed_off < 0) { memmove(va, va+n+signed_off, -signed_off); n = -signed_off; } else n = 0; } } return n; }
/* * lookup info about a client in the database. Find an address on the * same net as riip. */ int lookup(Bootp *bp, Info *iip, Info *riip) { Ndbtuple *t, *nt; Ndbs s; char *hwattr; char *hwval, hwbuf[33]; uchar ciaddr[IPaddrlen]; if(opendb() == nil){ warning(1, "can't open db"); return -1; } memset(iip, 0, sizeof(*iip)); /* client knows its address? */ v4tov6(ciaddr, bp->ciaddr); if(validip(ciaddr)){ if(lookupip(ciaddr, iip, 0) < 0) { if (debug) warning(0, "don't know %I", ciaddr); return -1; /* don't know anything about it */ } if(!samenet(riip->ipaddr, iip)){ warning(0, "%I not on %I", ciaddr, riip->ipnet); return -1; } /* * see if this is a masquerade, i.e., if the ether * address doesn't match what we expected it to be. */ if(memcmp(iip->etheraddr, zeroes, 6) != 0) if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0) warning(0, "ciaddr %I rcvd from %E instead of %E", ciaddr, bp->chaddr, iip->etheraddr); return 0; } if(bp->hlen > Maxhwlen) return -1; switch(bp->htype){ case 1: hwattr = "ether"; hwval = hwbuf; snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr); break; default: syslog(0, blog, "not ethernet %E, htype %d, hlen %d", bp->chaddr, bp->htype, bp->hlen); return -1; } /* * use hardware address to find an ip address on * same net as riip */ t = ndbsearch(db, &s, hwattr, hwval); while(t){ for(nt = t; nt; nt = nt->entry){ if(strcmp(nt->attr, "ip") != 0) continue; parseip(ciaddr, nt->val); if(lookupip(ciaddr, iip, 0) < 0) continue; if(samenet(riip->ipaddr, iip)){ ndbfree(t); return 0; } } ndbfree(t); t = ndbsnext(&s, hwattr, hwval); } return -1; }
/* * do an ipinfo with defaults */ int lookupip(uchar *ipaddr, Info *iip, int gate) { char ip[32]; Ndbtuple *t, *nt; char *attrs[32], **p; if(opendb() == nil){ warning(1, "can't open db"); return -1; } p = attrs; *p++ = "ip"; *p++ = "ipmask"; *p++ = "@ipgw"; if(!gate){ *p++ = "bootf"; *p++ = "bootf2"; *p++ = "@tftp"; *p++ = "@tftp2"; *p++ = "rootpath"; *p++ = "dhcp"; *p++ = "vendorclass"; *p++ = "ether"; *p++ = "dom"; *p++ = "@fs"; *p++ = "@auth"; } *p = 0; memset(iip, 0, sizeof(*iip)); snprint(ip, sizeof(ip), "%I", ipaddr); t = ndbipinfo(db, "ip", ip, attrs, p - attrs); if(t == nil) return -1; for(nt = t; nt != nil; nt = nt->entry){ if(strcmp(nt->attr, "ip") == 0) setipaddr(iip->ipaddr, nt->val); else if(strcmp(nt->attr, "ipmask") == 0) setipmask(iip->ipmask, nt->val); else if(strcmp(nt->attr, "fs") == 0) setipaddr(iip->fsip, nt->val); else if(strcmp(nt->attr, "auth") == 0) setipaddr(iip->auip, nt->val); else if(strcmp(nt->attr, "tftp") == 0) setipaddr(iip->tftp, nt->val); else if(strcmp(nt->attr, "tftp2") == 0) setipaddr(iip->tftp2, nt->val); else if(strcmp(nt->attr, "ipgw") == 0) setipaddr(iip->gwip, nt->val); else if(strcmp(nt->attr, "ether") == 0){ /* * this is probably wrong for machines with multiple * ethers. bootp or dhcp requests could come from any * of the ethers listed in the ndb entry. */ if(memcmp(iip->etheraddr, noetheraddr, 6) == 0) parseether(iip->etheraddr, nt->val); iip->indb = 1; } else if(strcmp(nt->attr, "dhcp") == 0){ if(iip->dhcpgroup[0] == 0) strcpy(iip->dhcpgroup, nt->val); } else if(strcmp(nt->attr, "bootf") == 0){ if(iip->bootf[0] == 0) strcpy(iip->bootf, nt->val); } else if(strcmp(nt->attr, "bootf2") == 0){ if(iip->bootf2[0] == 0) strcpy(iip->bootf2, nt->val); } else if(strcmp(nt->attr, "vendor") == 0){ if(iip->vendor[0] == 0) strcpy(iip->vendor, nt->val); } else if(strcmp(nt->attr, "dom") == 0){ if(iip->domain[0] == 0) strcpy(iip->domain, nt->val); } else if(strcmp(nt->attr, "rootpath") == 0){ if(iip->rootpath[0] == 0) strcpy(iip->rootpath, nt->val); } } ndbfree(t); maskip(iip->ipaddr, iip->ipmask, iip->ipnet); return 0; }
/* * attach a device (or pkt driver) to the interface. * called with c locked */ static char* ipifcbind(Conv *c, char **argv, int argc) { Mach *m = machp(); Ipifc *ifc; Medium *medium; if(argc < 2) return Ebadarg; ifc = (Ipifc*)c->ptcl; /* bind the device to the interface */ medium = ipfindmedium(argv[1]); if(medium == nil) return "unknown interface type"; wlock(ifc); if(ifc->medium != nil){ wunlock(ifc); return "interface already bound"; } if(waserror()){ wunlock(ifc); nexterror(); } /* do medium specific binding */ (*medium->bind)(ifc, argc, argv); /* set the bound device name */ if(argc > 2) strncpy(ifc->dev, argv[2], sizeof(ifc->dev)); else snprint(ifc->dev, sizeof ifc->dev, "%s%d", medium->name, c->x); ifc->dev[sizeof(ifc->dev)-1] = 0; /* set up parameters */ ifc->medium = medium; ifc->mintu = ifc->medium->mintu; ifc->maxtu = ifc->medium->maxtu; if(ifc->medium->unbindonclose == 0) ifc->conv->inuse++; ifc->rp.mflag = 0; /* default not managed */ ifc->rp.oflag = 0; ifc->rp.maxraint = 600000; /* millisecs */ ifc->rp.minraint = 200000; ifc->rp.linkmtu = 0; /* no mtu sent */ ifc->rp.reachtime = 0; ifc->rp.rxmitra = 0; ifc->rp.ttl = MAXTTL; ifc->rp.routerlt = 3 * ifc->rp.maxraint; /* any ancillary structures (like routes) no int32_ter pertain */ ifc->ifcid++; /* reopen all the queues closed by a previous unbind */ qreopen(c->rq); qreopen(c->eq); qreopen(c->sq); wunlock(ifc); poperror(); return nil; }
char* ipifcadd6(Ipifc *ifc, char**argv, int argc) { int plen = 64; int32_t origint = NOW / 1000, preflt = ~0L, validlt = ~0L; char addr[Maxv6repr], preflen[6]; char *params[3]; uint8_t autoflag = 1, onlink = 1; uint8_t prefix[IPaddrlen]; Iplifc *lifc; switch(argc) { case 7: preflt = atoi(argv[6]); /* fall through */ case 6: validlt = atoi(argv[5]); /* fall through */ case 5: autoflag = atoi(argv[4]); /* fall through */ case 4: onlink = atoi(argv[3]); /* fall through */ case 3: plen = atoi(argv[2]); /* fall through */ case 2: break; default: return Ebadarg; } if (parseip(prefix, argv[1]) != 6) return "bad ipv6 address"; if (validlt < preflt) return "valid ipv6 lifetime less than preferred lifetime"; if (plen < 0) return "negative ipv6 prefix length"; /* i think that this length limit is bogus - geoff */ // if (plen > 64) // return "ipv6 prefix length greater than 64; if (islinklocal(prefix)) return "ipv6 prefix is link-local"; lifc = smalloc(sizeof(Iplifc)); lifc->onlink = (onlink != 0); lifc->autoflag = (autoflag != 0); lifc->validlt = validlt; lifc->preflt = preflt; lifc->origint = origint; /* issue "add" ctl msg for v6 link-local addr and prefix len */ if(!ifc->medium->pref2addr) return "no pref2addr on interface"; ifc->medium->pref2addr(prefix, ifc->mac); /* mac → v6 link-local addr */ snprint(addr, sizeof addr, "%I", prefix); snprint(preflen, sizeof preflen, "/%d", plen); params[0] = "add"; params[1] = addr; params[2] = preflen; return ipifcadd(ifc, params, 3, 0, lifc); }
int main(int argc, char **argv) { int isnew; char *id, buf[Maxmsg], home[Maxmsg], prompt[100], *hexHi; char *pass, *passck; long expsecs; mpint *H = mpnew(0), *Hi = mpnew(0); PW *pw; Tm *tm; SECSTORE_DIR = unsharp("#9/secstore"); ARGBEGIN{ case 'v': verbose++; break; }ARGEND; if(argc!=1){ print("usage: secuser [-v] <user>\n"); exits("usage"); } ensure_exists(SECSTORE_DIR, DMDIR|0755L); snprint(home, sizeof(home), "%s/who", SECSTORE_DIR); ensure_exists(home, DMDIR|0755L); snprint(home, sizeof(home), "%s/store", SECSTORE_DIR); ensure_exists(home, DMDIR|0700L); id = argv[0]; if(verbose) fprint(2,"secuser %s\n", id); if((pw = getPW(id,1)) == nil){ isnew = 1; print("new account (because %s/%s %r)\n", SECSTORE_DIR, id); pw = emalloc(sizeof(*pw)); pw->id = estrdup(id); snprint(home, sizeof(home), "%s/store/%s", SECSTORE_DIR, id); if(access(home, AEXIST) == 0){ print("new user, but directory %s already exists\n", home); exits(home); } }else{ isnew = 0; } /* get main password for id */ for(;;){ if(isnew) snprint(prompt, sizeof(prompt), "%s password", id); else snprint(prompt, sizeof(prompt), "%s password [default = don't change]", id); pass = readcons(prompt, nil, 1); if(pass == nil){ print("getpass failed\n"); exits("getpass failed"); } if(verbose) print("%ld characters\n", strlen(pass)); if(pass[0] == '\0' && isnew == 0) break; if(strlen(pass) >= 7) break; print("password must be at least 7 characters\n"); } if(pass[0] != '\0'){ snprint(prompt, sizeof(prompt), "retype password"); if(verbose) print("confirming...\n"); passck = readcons(prompt, nil, 1); if(passck == nil){ print("getpass failed\n"); exits("getpass failed"); } if(strcmp(pass, passck) != 0){ print("passwords didn't match\n"); exits("no match"); } memset(passck, 0, strlen(passck)); free(passck); hexHi = PAK_Hi(id, pass, H, Hi); memset(pass, 0, strlen(pass)); free(pass); free(hexHi); mpfree(H); pw->Hi = Hi; } /* get expiration time (midnight of date specified) */ if(isnew) expsecs = time(0) + 365*24*60*60; else expsecs = pw->expire; for(;;){ tm = localtime(expsecs); print("expires [DDMMYYYY, default = %2.2d%2.2d%4.4d]: ", tm->mday, tm->mon, tm->year+1900); userinput(buf, sizeof(buf)); if(strlen(buf) == 0) break; if(strlen(buf) != 8){ print("!bad date format: %s\n", buf); continue; } tm->mday = (buf[0]-'0')*10 + (buf[1]-'0'); if(tm->mday > 31 || tm->mday < 1){ print("!bad day of month: %d\n", tm->mday); continue; } tm->mon = (buf[2]-'0')*10 + (buf[3]-'0') - 1; if(tm->mon > 11 || tm->mday < 0){ print("!bad month: %d\n", tm->mon + 1); continue; } tm->year = atoi(buf+4) - 1900; if(tm->year < 70){ print("!bad year: %d\n", tm->year + 1900); continue; } tm->sec = 59; tm->min = 59; tm->hour = 23; tm->yday = 0; expsecs = tm2sec(tm); break; } pw->expire = expsecs; /* failed logins */ if(pw->failed != 0 ) print("clearing %d failed login attempts\n", pw->failed); pw->failed = 0; /* status bits */ if(isnew) pw->status = Enabled; for(;;){ print("Enabled or Disabled [default %s]: ", (pw->status & Enabled) ? "Enabled" : "Disabled" ); userinput(buf, sizeof(buf)); if(strlen(buf) == 0) break; if(buf[0]=='E' || buf[0]=='e'){ pw->status |= Enabled; break; } if(buf[0]=='D' || buf[0]=='d'){ pw->status = pw->status & ~Enabled; break; } } for(;;){ print("require STA? [default %s]: ", (pw->status & STA) ? "yes" : "no" ); userinput(buf, sizeof(buf)); if(strlen(buf) == 0) break; if(buf[0]=='Y' || buf[0]=='y'){ pw->status |= STA; break; } if(buf[0]=='N' || buf[0]=='n'){ pw->status = pw->status & ~STA; break; } } /* free form field */ if(isnew) pw->other = nil; print("comments [default = %s]: ", (pw->other == nil) ? "" : pw->other); userinput(buf, 72); /* 72 comes from password.h */ if(buf[0]) if((pw->other = strdup(buf)) == nil) sysfatal("strdup"); syslog(0, LOG, "CHANGELOGIN for '%s'", pw->id); if(putPW(pw) < 0){ print("error writing entry: %r\n"); exits("can't write password file"); }else{ print("change written\n"); if(isnew && create(home, OREAD, DMDIR | 0775L) < 0){ print("unable to create %s: %r\n", home); exits(home); } } exits(""); return 1; /* keep other compilers happy */ }
void vnc(Ticketreq *tr) { uchar chal[VNCchallen+6]; uchar reply[VNCchallen]; char *secret, *hkey; char sbuf[SECRETLEN], hbuf[DESKEYLEN]; DESstate s; int i; /* * Create a challenge and send it. */ randombytes(chal+6, VNCchallen); chal[0] = AuthOKvar; snprint((char*)chal+1, sizeof chal - 1, "%-5d", VNCchallen); if(write(1, chal, sizeof(chal)) != sizeof(chal)) return; /* * lookup keys (and swizzle bits) */ memset(sbuf, 0, sizeof(sbuf)); secret = findsecret(KEYDB, tr->uid, sbuf); if(secret == 0){ randombytes((uchar*)sbuf, sizeof(sbuf)); secret = sbuf; } for(i = 0; i < 8; i++) secret[i] = swizzletab[(uchar)secret[i]]; hkey = findkey(KEYDB, tr->hostid, hbuf); if(hkey == 0){ randombytes((uchar*)hbuf, sizeof(hbuf)); hkey = hbuf; } /* * get response */ if(readn(0, reply, sizeof(reply)) != sizeof(reply)) return; /* * decrypt response and compare */ setupDESstate(&s, (uchar*)secret, nil); desECBdecrypt(reply, sizeof(reply), &s); if(memcmp(reply, chal+6, VNCchallen) != 0){ replyerror("vnc-fail bad response %s", raddr); logfail(tr->uid); return; } succeed(tr->uid); /* * reply with ticket & authenticator */ if(tickauthreply(tr, hkey) < 0) exits(0); if(debug) syslog(0, AUTHLOG, "vnc-ok %s %s", tr->uid, raddr); }
void apop(Ticketreq *tr, int type) { int challen, i, tries; char *secret, *hkey, *p; Ticketreq treq; DigestState *s; char sbuf[SECRETLEN], hbuf[DESKEYLEN]; char tbuf[TICKREQLEN]; char buf[MD5dlen*2]; uchar digest[MD5dlen], resp[MD5dlen]; ulong rb[4]; char chal[256]; USED(tr); /* * Create a challenge and send it. */ randombytes((uchar*)rb, sizeof(rb)); p = chal; p += snprint(p, sizeof(chal), "<%lux%lux.%lux%lux@%s>", rb[0], rb[1], rb[2], rb[3], domainname()); challen = p - chal; print("%c%-5d%s", AuthOKvar, challen, chal); /* give user a few attempts */ for(tries = 0; ; tries++) { /* * get ticket request */ if(readn(0, tbuf, TICKREQLEN) < 0) exits(0); convM2TR(tbuf, &treq); tr = &treq; if(tr->type != type) exits(0); /* * read response */ if(readn(0, buf, MD5dlen*2) < 0) exits(0); for(i = 0; i < MD5dlen; i++) resp[i] = (h2b(buf[2*i])<<4)|h2b(buf[2*i+1]); /* * lookup */ secret = findsecret(KEYDB, tr->uid, sbuf); hkey = findkey(KEYDB, tr->hostid, hbuf); if(hkey == 0 || secret == 0){ replyerror("apop-fail bad response %s", raddr); logfail(tr->uid); if(tries > 5) return; continue; } /* * check for match */ if(type == AuthCram){ hmac_md5((uchar*)chal, challen, (uchar*)secret, strlen(secret), digest, nil); } else { s = md5((uchar*)chal, challen, 0, 0); md5((uchar*)secret, strlen(secret), digest, s); } if(memcmp(digest, resp, MD5dlen) != 0){ replyerror("apop-fail bad response %s", raddr); logfail(tr->uid); if(tries > 5) return; continue; } break; } succeed(tr->uid); /* * reply with ticket & authenticator */ if(tickauthreply(tr, hkey) < 0) exits(0); if(debug){ if(type == AuthCram) syslog(0, AUTHLOG, "cram-ok %s %s", tr->uid, raddr); else syslog(0, AUTHLOG, "apop-ok %s %s", tr->uid, raddr); } }
// // read in the mailbox and parse into messages. // static char* _readmbox(Mailbox *mb, int doplumb, Mlock *lk) { int fd, n; String *tmp; Dir *d; static char err[Errlen]; Message *m, **l; Inbuf *inb; char *x; l = &mb->root->part; /* * open the mailbox. If it doesn't exist, try the temporary one. */ n = 0; retry: fd = open(mb->path, OREAD); if(fd < 0){ rerrstr(err, sizeof(err)); if(strstr(err, "exclusive lock") != 0 && n++ < 20){ sleep(500); /* wait for lock to go away */ goto retry; } if(strstr(err, "exist") != 0){ tmp = s_copy(mb->path); s_append(tmp, ".tmp"); if(sysrename(s_to_c(tmp), mb->path) == 0){ s_free(tmp); goto retry; } s_free(tmp); } return err; } /* * a new qid.path means reread the mailbox, while * a new qid.vers means read any new messages */ d = dirfstat(fd); if(d == nil){ close(fd); errstr(err, sizeof(err)); return err; } if(mb->d != nil){ if(d->qid.path == mb->d->qid.path && d->qid.vers == mb->d->qid.vers){ close(fd); free(d); return nil; } if(d->qid.path == mb->d->qid.path){ while(*l != nil) l = &(*l)->next; seek(fd, mb->d->length, 0); } free(mb->d); } mb->d = d; mb->vers++; henter(PATH(0, Qtop), mb->name, (Qid){PATH(mb->id, Qmbox), mb->vers, QTDIR}, nil, mb); inb = emalloc(sizeof(Inbuf)); inb->rptr = inb->wptr = inb->data; inb->fd = fd; // read new messages snprint(err, sizeof err, "reading '%s'", mb->path); logmsg(err, nil); for(;;){ if(lk != nil) syslockrefresh(lk); m = newmessage(mb->root); m->mallocd = 1; m->inmbox = 1; if(readmessage(m, inb) < 0){ delmessage(mb, m); mb->root->subname--; break; } // merge mailbox versions while(*l != nil){ if(memcmp((*l)->digest, m->digest, SHA1dlen) == 0){ // matches mail we already read, discard logmsg("duplicate", *l); delmessage(mb, m); mb->root->subname--; m = nil; l = &(*l)->next; break; } else { // old mail no longer in box, mark deleted logmsg("disappeared", *l); if(doplumb) mailplumb(mb, *l, 1); (*l)->inmbox = 0; (*l)->deleted = 1; l = &(*l)->next; } } if(m == nil) continue; x = strchr(m->start, '\n'); if(x == nil) m->header = m->end; else m->header = x + 1; m->mheader = m->mhend = m->header; parseunix(m); parse(m, 0, mb, 0); logmsg("new", m); /* chain in */ *l = m; l = &m->next; if(doplumb) mailplumb(mb, m, 0); } logmsg("mbox read", nil); // whatever is left has been removed from the mbox, mark deleted while(*l != nil){ if(doplumb) mailplumb(mb, *l, 1); (*l)->inmbox = 0; (*l)->deleted = 1; l = &(*l)->next; } close(fd); free(inb); return nil; }
void main(int argc, char **argv) { int conn, ctlfd, fd, n; char buf[128], *base, *mtpt, *post, *url; mtpt = "/mnt/web"; post = nil; base = nil; ARGBEGIN{ default: usage(); case 'b': base = EARGF(usage()); break; case 'm': mtpt = EARGF(usage()); break; case 'p': post = EARGF(usage()); break; }ARGEND; if (argc != 1) usage(); url = argv[0]; snprint(buf, sizeof buf, "%s/clone", mtpt); if((ctlfd = open(buf, ORDWR)) < 0) sysfatal("couldn't open %s: %r", buf); if((n = read(ctlfd, buf, sizeof buf-1)) < 0) sysfatal("reading clone: %r"); if(n == 0) sysfatal("short read on clone"); buf[n] = '\0'; conn = atoi(buf); if(base) if(fprint(ctlfd, "baseurl %s", base) < 0) sysfatal("baseurl ctl write: %r"); if(fprint(ctlfd, "url %s", url) <= 0) sysfatal("get ctl write: %r"); if(post){ snprint(buf, sizeof buf, "%s/%d/postbody", mtpt, conn); if((fd = open(buf, OWRITE)) < 0) sysfatal("open %s: %r", buf); if(write(fd, post, strlen(post)) < 0) sysfatal("post write failed: %r"); close(fd); } snprint(buf, sizeof buf, "%s/%d/body", mtpt, conn); if((fd = open(buf, OREAD)) < 0) sysfatal("open %s: %r", buf); xfer(fd, 1); exits(nil); }
void main(int argc, char *argv[]) { int i, c; char *a; char name[LIBNAMELEN]; Binit(&bso, 1, OWRITE); cout = -1; listinit(); memset(debug, 0, sizeof(debug)); nerrors = 0; outfile = "6.out"; HEADTYPE = -1; INITTEXT = -1; INITTEXTP = -1; INITDAT = -1; INITRND = -1; INITENTRY = 0; ARGBEGIN { default: c = ARGC(); if(c >= 0 && c < sizeof(debug)) debug[c]++; break; case 'o': /* output to (next arg) */ outfile = ARGF(); break; case 'E': a = ARGF(); if(a) INITENTRY = a; break; case 'H': a = ARGF(); if(a) HEADTYPE = atolwhex(a); break; case 'L': addlibpath(EARGF(usage())); break; case 'T': a = ARGF(); if(a) INITTEXT = atolwhex(a); break; case 'P': a = ARGF(); if(a) INITTEXTP = atolwhex(a); break; case 'D': a = ARGF(); if(a) INITDAT = atolwhex(a); break; case 'R': a = ARGF(); if(a) INITRND = atolwhex(a); break; case 'x': /* produce export table */ doexp = 1; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) readundefs(ARGF(), SEXPORT); break; case 'u': /* produce dynamically loadable module */ dlm = 1; debug['l']++; if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])) readundefs(ARGF(), SIMPORT); break; } ARGEND USED(argc); if(*argv == 0) usage(); if(!debug['9'] && !debug['U'] && !debug['B']) debug[DEFAULT] = 1; a = getenv("ccroot"); if(a != nil && *a != '\0') { if(!fileexists(a)) { diag("nonexistent $ccroot: %s", a); errorexit(); } }else a = ""; snprint(name, sizeof(name), "%s/%s/lib", a, thestring); addlibpath(name); if(HEADTYPE == -1) { if(debug['B']) HEADTYPE = 2; if(debug['9']) HEADTYPE = 2; } switch(HEADTYPE) { default: diag("unknown -H option"); errorexit(); case 2: /* plan 9 */ HEADR = 32L+8L; if(INITTEXT == -1) INITTEXT = 0x200000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 0x200000; break; case 5: /* elf32 executable */ HEADR = rnd(Ehdr32sz+3*Phdr32sz, 16); if(INITTEXT == -1) INITTEXT = 0xf0110000L; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 4096; break; case 6: /* ELF64 executable */ HEADR = rnd(Ehdr64sz+3*Phdr64sz, 16); if(INITTEXT == -1) INITTEXT = 0x200000+HEADR; if(INITDAT == -1) INITDAT = 0; if(INITRND == -1) INITRND = 0x200000; break; } if (INITTEXTP == -1) INITTEXTP = INITTEXT; if(INITDAT != 0 && INITRND != 0) print("warning: -D0x%llux is ignored because of -R0x%lux\n", INITDAT, INITRND); if(debug['v']) Bprint(&bso, "HEADER = -H%ld -T0x%llux -D0x%llux -R0x%lux\n", HEADTYPE, INITTEXT, INITDAT, INITRND); Bflush(&bso); for(i=1; optab[i].as; i++) { c = optab[i].as; if(opindex[c] != nil) { diag("phase error in optab: %d (%A)", i, c); errorexit(); } opindex[c] = &optab[i]; } for(i=0; i<Ymax; i++) ycover[i*Ymax + i] = 1; ycover[Yi0*Ymax + Yi8] = 1; ycover[Yi1*Ymax + Yi8] = 1; ycover[Yi0*Ymax + Ys32] = 1; ycover[Yi1*Ymax + Ys32] = 1; ycover[Yi8*Ymax + Ys32] = 1; ycover[Yi0*Ymax + Yi32] = 1; ycover[Yi1*Ymax + Yi32] = 1; ycover[Yi8*Ymax + Yi32] = 1; ycover[Ys32*Ymax + Yi32] = 1; ycover[Yi0*Ymax + Yi64] = 1; ycover[Yi1*Ymax + Yi64] = 1; ycover[Yi8*Ymax + Yi64] = 1; ycover[Ys32*Ymax + Yi64] = 1; ycover[Yi32*Ymax + Yi64] = 1; ycover[Yal*Ymax + Yrb] = 1; ycover[Ycl*Ymax + Yrb] = 1; ycover[Yax*Ymax + Yrb] = 1; ycover[Ycx*Ymax + Yrb] = 1; ycover[Yrx*Ymax + Yrb] = 1; ycover[Yrl*Ymax + Yrb] = 1; ycover[Ycl*Ymax + Ycx] = 1; ycover[Yax*Ymax + Yrx] = 1; ycover[Ycx*Ymax + Yrx] = 1; ycover[Yax*Ymax + Yrl] = 1; ycover[Ycx*Ymax + Yrl] = 1; ycover[Yrx*Ymax + Yrl] = 1; ycover[Yf0*Ymax + Yrf] = 1; ycover[Yal*Ymax + Ymb] = 1; ycover[Ycl*Ymax + Ymb] = 1; ycover[Yax*Ymax + Ymb] = 1; ycover[Ycx*Ymax + Ymb] = 1; ycover[Yrx*Ymax + Ymb] = 1; ycover[Yrb*Ymax + Ymb] = 1; ycover[Yrl*Ymax + Ymb] = 1; ycover[Ym*Ymax + Ymb] = 1; ycover[Yax*Ymax + Yml] = 1; ycover[Ycx*Ymax + Yml] = 1; ycover[Yrx*Ymax + Yml] = 1; ycover[Yrl*Ymax + Yml] = 1; ycover[Ym*Ymax + Yml] = 1; ycover[Yax*Ymax + Ymm] = 1; ycover[Ycx*Ymax + Ymm] = 1; ycover[Yrx*Ymax + Ymm] = 1; ycover[Yrl*Ymax + Ymm] = 1; ycover[Ym*Ymax + Ymm] = 1; ycover[Ymr*Ymax + Ymm] = 1; ycover[Yax*Ymax + Yxm] = 1; ycover[Ycx*Ymax + Yxm] = 1; ycover[Yrx*Ymax + Yxm] = 1; ycover[Yrl*Ymax + Yxm] = 1; ycover[Ym*Ymax + Yxm] = 1; ycover[Yxr*Ymax + Yxm] = 1; for(i=0; i<D_NONE; i++) { reg[i] = -1; if(i >= D_AL && i <= D_R15B) { reg[i] = (i-D_AL) & 7; if(i >= D_SPB && i <= D_DIB) regrex[i] = 0x40; if(i >= D_R8B && i <= D_R15B) regrex[i] = Rxr | Rxx | Rxb; } if(i >= D_AH && i<= D_BH) reg[i] = 4 + ((i-D_AH) & 7); if(i >= D_AX && i <= D_R15) { reg[i] = (i-D_AX) & 7; if(i >= D_R8) regrex[i] = Rxr | Rxx | Rxb; } if(i >= D_F0 && i <= D_F0+7) reg[i] = (i-D_F0) & 7; if(i >= D_M0 && i <= D_M0+7) reg[i] = (i-D_M0) & 7; if(i >= D_X0 && i <= D_X0+15) { reg[i] = (i-D_X0) & 7; if(i >= D_X0+8) regrex[i] = Rxr | Rxx | Rxb; } if(i >= D_CR+8 && i <= D_CR+15) regrex[i] = Rxr; } zprg.link = P; zprg.pcond = P; zprg.back = 2; zprg.as = AGOK; zprg.from.type = D_NONE; zprg.from.index = D_NONE; zprg.from.scale = 1; zprg.to = zprg.from; zprg.mode = 64; pcstr = "%.6llux "; nuxiinit(); histgen = 0; textp = P; datap = P; edatap = P; pc = 0; dtype = 4; cout = create(outfile, 1, 0775); if(cout < 0) { diag("cannot create %s: %r", outfile); errorexit(); } version = 0; cbp = buf.cbuf; cbc = sizeof(buf.cbuf); firstp = prg(); lastp = firstp; if(INITENTRY == 0) { INITENTRY = "_main"; if(debug['p']) INITENTRY = "_mainp"; if(!debug['l']) lookup(INITENTRY, 0)->type = SXREF; } else if(!(*INITENTRY >= '0' && *INITENTRY <= '9')) lookup(INITENTRY, 0)->type = SXREF; while(*argv) objfile(*argv++); if(!debug['l']) loadlib(); firstp = firstp->link; if(firstp == P) errorexit(); if(doexp || dlm){ EXPTAB = "_exporttab"; zerosig(EXPTAB); zerosig("etext"); zerosig("edata"); zerosig("end"); if(dlm){ import(); HEADTYPE = 2; INITTEXT = 0; INITDAT = 0; INITRND = 8; INITENTRY = EXPTAB; } export();
static long consread(Chan *c, void *va, long n, vlong offset) { int send; char *p, buf[64], ch; FILE * battery; FILE * brightness; int size; if(c->qid.type & QTDIR) return devdirread(c, va, n, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, n, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, n, ossysname); case Qrandom: return randomread(va, n); case Qnotquiterandom: genrandom(va, n); return n; case Qhostowner: return readstr(offset, va, n, eve); case Qhoststdin: return read(0, va, n); /* should be pread */ case Quser: return readstr(offset, va, n, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, n, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, n, buf); case Qdrivers: return devtabread(c, va, n, offset); case Qmemory: return poolread(va, n, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, n, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); while(!qcanread(lineq)) { if(qread(kbdq, &ch, 1) == 0) continue; send = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) send = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case 0x04: send = 1; break; case '\n': send = 1; default: kbd.line[kbd.x++] = ch; break; } } if(send || kbd.x == sizeof kbd.line){ qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, va, n); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, n, gkscanid); return qread(gkscanq, va, n); case Qkeyboard: return qread(gkbdq, va, n); case Qevents: return qread(c->aux, va, n); case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; case Qbattery: if(type == 's') battery = fopen("/sys/class/power_supply/battery/capacity", "r"); else if(type == 'c') battery = fopen("/sys/class/power_supply/max17042-0/capacity", "r"); else battery = fopen("/sys/class/power_supply/battery/capacity", "r"); size = fread(buf, 1, sizeof(buf), battery); fclose(battery); buf[size - 1] = '\0'; return readstr(offset, va, n, buf); case Qtype: if(type == 's') strncpy(buf, "nexus s", sizeof(buf)); else if(type == 'c') strncpy(buf, "nook color", sizeof(buf)); else if(type == 'e') strncpy(buf, "emulator", sizeof(buf)); else strncpy(buf, "nexus s", sizeof(buf)); return readstr(offset, va, n, buf); case Qbrightness: if(type == 'c') brightness = fopen("/sys/devices/platform/omap_pwm_led/leds/lcd-backlight/brightness", "r"); else if(type == 'e') return; else brightness = fopen("/sys/class/backlight/s5p_bl/brightness", "r"); size = fread(buf, 1, sizeof(buf), brightness); fclose(brightness); buf[size - 1] = '\0'; return readstr(offset, va, n, buf); } }
void dbgxec(Prog *p) { Bpt *b; Prog *kid; Osenv *env; Progctl *ctl; int op, pc, n; char buf[ERRMAX+10]; extern void (*dec[])(void); env = p->osenv; ctl = env->debug; ctl->ref++; if(waserror()){ closedbgctl(ctl, p); nexterror(); } R = p->R; R.MP = R.M->MP; R.IC = p->quanta; if((ulong)R.IC > ctl->step) R.IC = ctl->step; if(ctl->stop) R.IC = 0; buf[0] = '\0'; if(R.IC != 0 && R.M->compiled) { comvec(); if(p != currun()) dbgblock(p); goto save; } while(R.IC != 0) { if(0) print("step: %lux: %s %4ld %D\n", (ulong)p, R.M->m->name, R.PC-R.M->prog, R.PC); dec[R.PC->add](); op = R.PC->op; R.PC++; optab[op](); /* * check notification about new progs */ if(op == ISPAWN || op == IMSPAWN) { /* pick up the kid from the end of the run queue */ kid = delruntail(Pdebug); n = snprint(buf, sizeof buf, "new %d", kid->pid); qproduce(ctl->q, buf, n); buf[0] = '\0'; } if(op == ILOAD) { n = snprint(buf, sizeof buf, "load %s", string2c(*(String**)R.s)); qproduce(ctl->q, buf, n); buf[0] = '\0'; } /* * check for returns at big steps */ if(op == IRET) R.IC = 1; /* * check for blocked progs */ if(R.IC == 1 && p != currun()) dbgblock(p); if(ctl->stop) R.IC = 1; R.IC--; if(ctl->bpts == nil) continue; pc = R.PC - R.M->prog; for(b = ctl->bpts; b != nil; b = b->next) { if(pc == b->pc && (strcmp(R.M->m->path, b->path) == 0 || strcmp(R.M->m->path, b->file) == 0)) { strcpy(buf, "breakpoint"); goto save; } } } save: if(ctl->stop) strcpy(buf, "stopped"); p->R = R; if(env->debug == nil) { poperror(); return; } if(p == currun()) delrun(Pdebug); telldbg(env->debug, buf); poperror(); closedbgctl(env->debug, p); }
/* * Print * sysname: time: mesg * on /sys/log/logname. * If cons or log file can't be opened, print on the system console, too. */ void syslog(int cons, char *logname, char *fmt, ...) { char buf[1024]; char *ctim, *p; va_list arg; int n; Dir *d; char err[ERRMAX]; err[0] = '\0'; errstr(err, sizeof err); lock(&sl); /* * paranoia makes us stat to make sure a fork+close * hasn't broken our fd's */ d = dirfstat(sl.fd); if(sl.fd < 0 || sl.name == nil || strcmp(sl.name, logname) != 0 || !eqdirdev(d, sl.d)){ free(sl.name); sl.name = strdup(logname); if(sl.name == nil) cons = 1; else{ free(sl.d); sl.d = nil; _syslogopen(); if(sl.fd < 0) cons = 1; else sl.d = dirfstat(sl.fd); } } free(d); if(cons){ d = dirfstat(sl.consfd); if(sl.consfd < 0 || !eqdirdev(d, sl.consd)){ free(sl.consd); sl.consd = nil; sl.consfd = open("#c/cons", OWRITE|OCEXEC); if(sl.consfd >= 0) sl.consd = dirfstat(sl.consfd); } free(d); } if(fmt == nil){ unlock(&sl); return; } ctim = ctime(time(0)); p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname()); strncpy(p, ctim+4, 15); p += 15; *p++ = ' '; errstr(err, sizeof err); va_start(arg, fmt); p = vseprint(p, buf+sizeof(buf)-1, fmt, arg); va_end(arg); *p++ = '\n'; n = p - buf; if(sl.fd >= 0){ seek(sl.fd, 0, 2); write(sl.fd, buf, n); } if(cons && sl.consfd >=0) write(sl.consfd, buf, n); unlock(&sl); }
static long progread(Chan *c, void *va, long n, vlong offset) { int i; Prog *p; Osenv *o; Mntwalk *mw; ulong grpid; char *a = va; Progctl *ctl; char mbuf[64], timebuf[12]; char flag[10]; if(c->qid.type & QTDIR) return devdirread(c, a, n, 0, 0, proggen); switch(QID(c->qid)){ case Qdbgctl: ctl = c->aux; return qread(ctl->q, va, n); case Qstatus: acquire(); p = progpid(PID(c->qid)); if(p == nil || p->state == Pexiting || p->R.M == H) { release(); snprint(up->genbuf, sizeof(up->genbuf), "%8lud %8d %10s %s %10s %5dK %s", PID(c->qid), 0, eve, progtime(0, timebuf, timebuf+sizeof(timebuf)), progstate[Pexiting], 0, "[$Sys]"); return readstr(offset, va, n, up->genbuf); } modstatus(&p->R, mbuf, sizeof(mbuf)); o = p->osenv; snprint(up->genbuf, sizeof(up->genbuf), "%8d %8d %10s %s %10s %5dK %s", p->pid, p->group!=nil? p->group->id: 0, o->user, progtime(p->ticks, timebuf, timebuf+sizeof(timebuf)), progstate[p->state], progsize(p), mbuf); release(); return readstr(offset, va, n, up->genbuf); case Qwait: return qread(c->aux, va, n); case Qns: acquire(); if(waserror()){ release(); nexterror(); } p = progpid(PID(c->qid)); if(p == nil) error(Ethread); mw = c->aux; if(mw->cddone){ poperror(); release(); return 0; } o = p->osenv; mntscan(mw, o->pgrp); if(mw->mh == 0) { mw->cddone = 1; i = snprint(a, n, "cd %s\n", o->pgrp->dot->name->s); poperror(); release(); return i; } int2flag(mw->cm->mflag, flag); if(strcmp(mw->cm->to->name->s, "#M") == 0){ i = snprint(a, n, "mount %s %s %s %s\n", flag, mw->cm->to->mchan->name->s, mw->mh->from->name->s, mw->cm->spec? mw->cm->spec : ""); }else i = snprint(a, n, "bind %s %s %s\n", flag, mw->cm->to->name->s, mw->mh->from->name->s); poperror(); release(); return i; case Qnsgrp: acquire(); p = progpid(PID(c->qid)); if(p == nil) { release(); error(Ethread); } grpid = ((Osenv *)p->osenv)->pgrp->pgrpid; release(); return readnum(offset, va, n, grpid, NUMSIZE); case Qpgrp: acquire(); p = progpid(PID(c->qid)); if(p == nil) { release(); error(Ethread); } grpid = p->group!=nil? p->group->id: 0; release(); return readnum(offset, va, n, grpid, NUMSIZE); case Qstack: acquire(); p = progpid(PID(c->qid)); if(p == nil || p->state == Pexiting) { release(); error(Ethread); } if(p->state == Pready) { release(); error(Estopped); } n = progstack(&p->R, p->state, va, n, offset); release(); return n; case Qheap: acquire(); if(waserror()){ release(); nexterror(); } n = progheap(c->aux, va, n, offset); if(n == -1) error(Emisalign); poperror(); release(); return n; case Qfd: acquire(); if(waserror()) { release(); nexterror(); } p = progpid(PID(c->qid)); if(p == nil) error(Ethread); o = p->osenv; n = progfds(o, va, n, offset); poperror(); release(); return n; case Qexception: acquire(); p = progpid(PID(c->qid)); if(p == nil) { release(); error(Ethread); } if(p->exstr == nil) up->genbuf[0] = 0; else snprint(up->genbuf, sizeof(up->genbuf), p->exstr); release(); return readstr(offset, va, n, up->genbuf); } error(Egreg); return 0; }
static long consread(Chan *c, void *va, long n, vlong offset) { ulong l; int i, send; char *p, buf[64], ch; if(c->qid.type & QTDIR) return devdirread(c, va, n, contab, nelem(contab), devgen); switch((ulong)c->qid.path) { default: error(Egreg); case Qsysctl: return readstr(offset, va, n, VERSION); case Qsysname: if(ossysname == nil) return 0; return readstr(offset, va, n, ossysname); case Qrandom: return randomread(va, n); case Qnotquiterandom: genrandom(va, n); return n; case Qpin: p = "pin set"; if(up->env->pgrp->pin == Nopin) p = "no pin"; return readstr(offset, va, n, p); case Qhostowner: return readstr(offset, va, n, eve); case Qhoststdin: return read(0, va, n); /* should be pread */ case Quser: return readstr(offset, va, n, up->env->user); case Qjit: snprint(buf, sizeof(buf), "%d", cflag); return readstr(offset, va, n, buf); case Qtime: snprint(buf, sizeof(buf), "%.lld", timeoffset + osusectime()); return readstr(offset, va, n, buf); case Qdrivers: p = malloc(READSTR); if(p == nil) error(Enomem); l = 0; for(i = 0; devtab[i] != nil; i++) l += snprint(p+l, READSTR-l, "#%C %s\n", devtab[i]->dc, devtab[i]->name); if(waserror()){ free(p); nexterror(); } n = readstr(offset, va, n, p); poperror(); free(p); return n; case Qmemory: return poolread(va, n, offset); case Qnull: return 0; case Qmsec: return readnum(offset, va, n, osmillisec(), NUMSIZE); case Qcons: qlock(&kbd.q); if(waserror()){ qunlock(&kbd.q); nexterror(); } if(dflag) error(Enonexist); while(!qcanread(lineq)) { if(qread(kbdq, &ch, 1) == 0) continue; send = 0; if(ch == 0){ /* flush output on rawoff -> rawon */ if(kbd.x > 0) send = !qcanread(kbdq); }else if(kbd.raw){ kbd.line[kbd.x++] = ch; send = !qcanread(kbdq); }else{ switch(ch){ case '\b': if(kbd.x) kbd.x--; break; case 0x15: kbd.x = 0; break; case 0x04: send = 1; break; case '\n': send = 1; default: kbd.line[kbd.x++] = ch; break; } } if(send || kbd.x == sizeof kbd.line){ qwrite(lineq, kbd.line, kbd.x); kbd.x = 0; } } n = qread(lineq, va, n); qunlock(&kbd.q); poperror(); return n; case Qscancode: if(offset == 0) return readstr(0, va, n, gkscanid); return qread(gkscanq, va, n); case Qkeyboard: return qread(gkbdq, va, n); case Qkprint: rlock(&kprintq.l); if(waserror()){ runlock(&kprintq.l); nexterror(); } n = qread(kprintq.q, va, n); poperror(); runlock(&kprintq.l); return n; } }
void pexit(char *exitstr, int freemem) { Proc *p; Segment **s, **es; long utime, stime; Waitq *wq, *f, *next; Fgrp *fgrp; Egrp *egrp; Rgrp *rgrp; Pgrp *pgrp; Chan *dot; void (*pt)(Proc*, int, vlong); if(up->syscalltrace) free(up->syscalltrace); up->alarm = 0; if (up->tt) timerdel(up); pt = proctrace; if(pt) pt(up, SDead, 0); /* nil out all the resources under lock (free later) */ qlock(&up->debug); fgrp = up->fgrp; up->fgrp = nil; egrp = up->egrp; up->egrp = nil; rgrp = up->rgrp; up->rgrp = nil; pgrp = up->pgrp; up->pgrp = nil; dot = up->dot; up->dot = nil; qunlock(&up->debug); if(fgrp) closefgrp(fgrp); if(egrp) closeegrp(egrp); if(rgrp) closergrp(rgrp); if(dot) cclose(dot); if(pgrp) closepgrp(pgrp); /* * if not a kernel process and have a parent, * do some housekeeping. */ if(up->kp == 0) { p = up->parent; if(p == 0) { if(exitstr == 0) exitstr = "unknown"; panic("boot process died: %s", exitstr); } while(waserror()) ; wq = smalloc(sizeof(Waitq)); poperror(); wq->w.pid = up->pid; utime = up->time[TUser] + up->time[TCUser]; stime = up->time[TSys] + up->time[TCSys]; wq->w.time[TUser] = tk2ms(utime); wq->w.time[TSys] = tk2ms(stime); wq->w.time[TReal] = tk2ms(MACHP(0)->ticks - up->time[TReal]); if(exitstr && exitstr[0]) snprint(wq->w.msg, sizeof(wq->w.msg), "%s %lud: %s", up->text, up->pid, exitstr); else wq->w.msg[0] = '\0'; lock(&p->exl); /* * Check that parent is still alive. */ if(p->pid == up->parentpid && p->state != Broken) { p->nchild--; p->time[TCUser] += utime; p->time[TCSys] += stime; /* * If there would be more than 128 wait records * processes for my parent, then don't leave a wait * record behind. This helps prevent badly written * daemon processes from accumulating lots of wait * records. */ if(p->nwait < 128) { wq->next = p->waitq; p->waitq = wq; p->nwait++; wq = nil; wakeup(&p->waitr); } } unlock(&p->exl); if(wq) free(wq); } if(!freemem) addbroken(up); qlock(&up->seglock); es = &up->seg[NSEG]; for(s = up->seg; s < es; s++) { if(*s) { putseg(*s); *s = 0; } } qunlock(&up->seglock); lock(&up->exl); /* Prevent my children from leaving waits */ pidunhash(up); up->pid = 0; wakeup(&up->waitr); unlock(&up->exl); for(f = up->waitq; f; f = next) { next = f->next; free(f); } /* release debuggers */ qlock(&up->debug); if(up->pdbg) { wakeup(&up->pdbg->sleep); up->pdbg = 0; } qunlock(&up->debug); /* Sched must not loop for these locks */ lock(&procalloc); lock(&palloc); edfstop(up); up->state = Moribund; sched(); panic("pexit"); }
static char * doauth(char *methods) { char *buf, *base64; int n; DS ds; UserPasswd *p; dial_string_parse(ddomain, &ds); if(user != nil) p = auth_getuserpasswd(nil, "proto=pass service=smtp server=%q user=%q", ds.host, user); else p = auth_getuserpasswd(nil, "proto=pass service=smtp server=%q", ds.host); if (p == nil) return Giveup; if (strstr(methods, "LOGIN")){ dBprint("AUTH LOGIN\r\n"); if (getreply() != 3) return Retry; n = strlen(p->user); base64 = malloc(2*n); if (base64 == nil) return Retry; /* Out of memory */ enc64(base64, 2*n, (uchar *)p->user, n); dBprint("%s\r\n", base64); if (getreply() != 3) return Retry; n = strlen(p->passwd); base64 = malloc(2*n); if (base64 == nil) return Retry; /* Out of memory */ enc64(base64, 2*n, (uchar *)p->passwd, n); dBprint("%s\r\n", base64); if (getreply() != 2) return Retry; free(base64); } else if (strstr(methods, "PLAIN")){ n = strlen(p->user) + strlen(p->passwd) + 3; buf = malloc(n); base64 = malloc(2 * n); if (buf == nil || base64 == nil) { free(buf); return Retry; /* Out of memory */ } snprint(buf, n, "%c%s%c%s", 0, p->user, 0, p->passwd); enc64(base64, 2 * n, (uchar *)buf, n - 1); free(buf); dBprint("AUTH PLAIN %s\r\n", base64); free(base64); if (getreply() != 2) return Retry; } else return "No supported AUTH method"; return(0); }