summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ssh/util.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ssh/util.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ssh/util.c')
-rwxr-xr-xsys/src/cmd/ssh/util.c269
1 files changed, 269 insertions, 0 deletions
diff --git a/sys/src/cmd/ssh/util.c b/sys/src/cmd/ssh/util.c
new file mode 100755
index 000000000..ff737884a
--- /dev/null
+++ b/sys/src/cmd/ssh/util.c
@@ -0,0 +1,269 @@
+#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");
+ }
+ }
+}