ref: a8d00e5d56b261376410c3c87c46327362763bd8
dir: /sys/src/cmd/ssh/util.c/
#include "ssh.h" #include <bio.h> #include <ndb.h> char Edecode[] = "error decoding input packet"; char Eencode[] = "out of space encoding output packet (BUG)"; char Ehangup[] = "hungup connection"; char Ememory[] = "out of memory"; int debuglevel; int doabort; void error(char *fmt, ...) { va_list arg; char buf[2048]; va_start(arg, fmt); vseprint(buf, buf+sizeof(buf), fmt, arg); va_end(arg); fprint(2, "%s: %s\n", argv0, buf); if(doabort) abort(); exits(buf); } void debug(int level, char *fmt, ...) { va_list arg; if((level&debuglevel) == 0) return; va_start(arg, fmt); vfprint(2, fmt, arg); va_end(arg); } void* emalloc(long n) { void *a; a = mallocz(n, 1); if(a == nil) error(Ememory); setmalloctag(a, getcallerpc(&n)); return a; } void* erealloc(void *v, long n) { v = realloc(v, n); if(v == nil) error(Ememory); setrealloctag(v, getcallerpc(&v)); return v; } static int killpid[32]; static int nkillpid; void atexitkiller(void) { int i, pid; pid = getpid(); debug(DBG, "atexitkiller: nkillpid=%d mypid=%d\n", nkillpid, pid); for(i=0; i<nkillpid; i++) if(pid != killpid[i]){ debug(DBG, "killing %d\n", killpid[i]); postnote(PNPROC, killpid[i], "kill"); } } void atexitkill(int pid) { killpid[nkillpid++] = pid; } int readstrnl(int fd, char *buf, int nbuf) { int i; for(i=0; i<nbuf; i++){ switch(read(fd, buf+i, 1)){ case -1: return -1; case 0: werrstr("unexpected EOF"); return -1; default: if(buf[i]=='\n'){ buf[i] = '\0'; return 0; } break; } } werrstr("line too long"); return -1; } void calcsessid(Conn *c) { int n; uchar buf[1024]; n = mptobe(c->hostkey->n, buf, sizeof buf, nil); n += mptobe(c->serverkey->n, buf+n, sizeof buf-n, nil); memmove(buf+n, c->cookie, COOKIELEN); n += COOKIELEN; md5(buf, n, c->sessid, nil); } void sshlog(char *f, ...) { char *s; va_list arg; Fmt fmt; static int pid; if(pid == 0) pid = getpid(); va_start(arg, f); va_end(arg); if(fmtstrinit(&fmt) < 0) sysfatal("fmtstrinit: %r"); fmtprint(&fmt, "[%d] ", pid); fmtvprint(&fmt, f, arg); s = fmtstrflush(&fmt); if(s == nil) sysfatal("fmtstrflush: %r"); syslog(0, "ssh", "%s", s); free(s); } /* * this is far too smart. */ static int pstrcmp(const void *a, const void *b) { return strcmp(*(char**)a, *(char**)b); } static char* trim(char *s) { char *t; int i, last, n, nf; char **f; char *p; t = emalloc(strlen(s)+1); t[0] = '\0'; n = 1; for(p=s; *p; p++) if(*p == ' ') n++; f = emalloc((n+1)*sizeof(f[0])); nf = tokenize(s, f, n+1); qsort(f, nf, sizeof(f[0]), pstrcmp); last=-1; for(i=0; i<nf; i++){ if(last==-1 || strcmp(f[last], f[i])!=0){ if(last >= 0) strcat(t, ","); strcat(t, f[i]); last = i; } } return t; } static void usetuple(Conn *c, Ndbtuple *t, int scanentries) { int first; Ndbtuple *l, *e; char *s; first=1; s = c->host; for(l=t; first||l!=t; l=l->line, first=0){ if(scanentries){ for(e=l; e; e=e->entry){ if(strcmp(e->val, c->host) != 0 && (strcmp(e->attr, "ip")==0 || strcmp(e->attr, "dom")==0 || strcmp(e->attr, "sys")==0)){ s = smprint("%s %s", s, e->val); if(s == nil) error("out of memory"); } } } if(strcmp(l->val, c->host) != 0 && (strcmp(l->attr, "ip")==0 || strcmp(l->attr, "dom")==0 || strcmp(l->attr, "sys")==0)){ s = smprint("%s %s", s, l->val); if(s == nil) error("out of memory"); } } s = trim(s); c->aliases = s; } void setaliases(Conn *c, char *name) { char *p, *net; char *attr[2]; Ndbtuple *t; net = "/net"; if(name[0]=='/'){ p = strchr(name+1, '/'); if(p){ net = emalloc(p-name+1); memmove(net, name, p-name); } } if(p = strchr(name, '!')) name = p+1; c->host = emalloc(strlen(name)+1); strcpy(c->host, name); c->aliases = c->host; attr[0] = "dom"; attr[1] = "ip"; t = csipinfo(nil, ipattr(name), name, attr, 2); if(t != nil){ usetuple(c, t, 0); ndbfree(t); }else{ t = dnsquery(net, name, "ip"); if(t != nil){ usetuple(c, t, 1); ndbfree(t); } } } void privatefactotum(void) { char *user; Dir *d; if((user=getuser()) && (d=dirstat("/mnt/factotum/rpc")) && strcmp(user, d->uid)!=0){ /* grab the terminal's factotum */ rfork(RFNAMEG); /* was RFNOTEG, which makes little sense */ if(access("/mnt/term/mnt/factotum", AEXIST) >= 0){ // fprint(2, "binding terminal's factotum\n"); if(bind("/mnt/term/mnt/factotum", "/mnt/factotum", MREPL) < 0) sysfatal("cannot find factotum"); } } }