|  | #include <u.h> | 
|  | #include <sys/types.h> | 
|  | #include <sys/stat.h> | 
|  | #include <sys/wait.h> | 
|  | #include <pwd.h> | 
|  | #include <signal.h> | 
|  | #include <fcntl.h> | 
|  | #include <errno.h> | 
|  |  | 
|  | #include "sam.h" | 
|  |  | 
|  | Rune    samname[] = { '~', '~', 's', 'a', 'm', '~', '~', 0 }; | 
|  |  | 
|  | static Rune l1[] = { '{', '[', '(', '<', 0253, 0}; | 
|  | static Rune l2[] = { '\n', 0}; | 
|  | static Rune l3[] = { '\'', '"', '`', 0}; | 
|  | Rune *left[]= { l1, l2, l3, 0}; | 
|  |  | 
|  | static Rune r1[] = {'}', ']', ')', '>', 0273, 0}; | 
|  | static Rune r2[] = {'\n', 0}; | 
|  | static Rune r3[] = {'\'', '"', '`', 0}; | 
|  | Rune *right[]= { r1, r2, r3, 0}; | 
|  |  | 
|  | #ifndef SAMTERMNAME | 
|  | #define SAMTERMNAME "samterm" | 
|  | #endif | 
|  | #ifndef TMPDIRNAME | 
|  | #define TMPDIRNAME "/tmp" | 
|  | #endif | 
|  | #ifndef SHNAME | 
|  | #define SHNAME "sh" | 
|  | #endif | 
|  | #ifndef SHPATHNAME | 
|  | #define SHPATHNAME "/bin/sh" | 
|  | #endif | 
|  | #ifndef RXNAME | 
|  | #define RXNAME "ssh" | 
|  | #endif | 
|  | #ifndef RXPATHNAME | 
|  | #define RXPATHNAME "ssh" | 
|  | #endif | 
|  |  | 
|  | char	RSAM[] = "sam"; | 
|  | char	SAMTERM[] = SAMTERMNAME; | 
|  | char	HOME[] = "HOME"; | 
|  | char	TMPDIR[] = TMPDIRNAME; | 
|  | char	SH[] = SHNAME; | 
|  | char	SHPATH[] = SHPATHNAME; | 
|  | char	RX[] = RXNAME; | 
|  | char	RXPATH[] = RXPATHNAME; | 
|  |  | 
|  |  | 
|  | void | 
|  | dprint(char *z, ...) | 
|  | { | 
|  | char buf[BLOCKSIZE]; | 
|  | va_list arg; | 
|  |  | 
|  | va_start(arg, z); | 
|  | vseprint(buf, &buf[BLOCKSIZE], z, arg); | 
|  | va_end(arg); | 
|  | termwrite(buf); | 
|  | } | 
|  |  | 
|  | void | 
|  | print_ss(char *s, String *a, String *b) | 
|  | { | 
|  | dprint("?warning: %s: `%.*S' and `%.*S'\n", s, a->n, a->s, b->n, b->s); | 
|  | } | 
|  |  | 
|  | void | 
|  | print_s(char *s, String *a) | 
|  | { | 
|  | dprint("?warning: %s `%.*S'\n", s, a->n, a->s); | 
|  | } | 
|  |  | 
|  | char* | 
|  | getuser(void) | 
|  | { | 
|  | static char user[64]; | 
|  | if(user[0] == 0){ | 
|  | struct passwd *pw = getpwuid(getuid()); | 
|  | strcpy(user, pw ? pw->pw_name : "nobody"); | 
|  | } | 
|  | return user; | 
|  | } | 
|  |  | 
|  | int | 
|  | statfile(char *name, ulong *dev, uvlong *id, long *time, long *length, long *appendonly) | 
|  | { | 
|  | struct stat dirb; | 
|  |  | 
|  | if (stat(name, &dirb) == -1) | 
|  | return -1; | 
|  | if (dev) | 
|  | *dev = dirb.st_dev; | 
|  | if (id) | 
|  | *id = dirb.st_ino; | 
|  | if (time) | 
|  | *time = dirb.st_mtime; | 
|  | if (length) | 
|  | *length = dirb.st_size; | 
|  | if(appendonly) | 
|  | *appendonly = 0; | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | int | 
|  | statfd(int fd, ulong *dev, uvlong *id, long *time, long *length, long *appendonly) | 
|  | { | 
|  | struct stat dirb; | 
|  |  | 
|  | if (fstat(fd, &dirb) == -1) | 
|  | return -1; | 
|  | if (dev) | 
|  | *dev = dirb.st_dev; | 
|  | if (id) | 
|  | *id = dirb.st_ino; | 
|  | if (time) | 
|  | *time = dirb.st_mtime; | 
|  | if (length) | 
|  | *length = dirb.st_size; | 
|  | if(appendonly) | 
|  | *appendonly = 0; | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | void | 
|  | hup(int sig) | 
|  | { | 
|  | panicking = 1; /* ??? */ | 
|  | rescue(); | 
|  | exit(1); | 
|  | } | 
|  |  | 
|  | int | 
|  | notify(void(*f)(void *, char *)) | 
|  | { | 
|  | signal(SIGINT, SIG_IGN); | 
|  | signal(SIGPIPE, SIG_IGN);  /* XXX - bpipeok? */ | 
|  | signal(SIGHUP, hup); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | void | 
|  | notifyf(void *a, char *b)       /* never called; hup is instead */ | 
|  | { | 
|  | } | 
|  |  | 
|  | static int | 
|  | temp_file(char *buf, int bufsize) | 
|  | { | 
|  | char *tmp; | 
|  | int n, fd; | 
|  |  | 
|  | tmp = getenv("TMPDIR"); | 
|  | if (!tmp) | 
|  | tmp = TMPDIR; | 
|  |  | 
|  | n = snprint(buf, bufsize, "%s/sam.%d.XXXXXXX", tmp, getuid()); | 
|  | if (bufsize <= n) | 
|  | return -1; | 
|  | if ((fd = mkstemp(buf)) < 0)  /* SES - linux sometimes uses mode 0666 */ | 
|  | return -1; | 
|  | if (fcntl(fd, F_SETFD, fcntl(fd,F_GETFD,0) | FD_CLOEXEC) < 0) | 
|  | return -1; | 
|  | return fd; | 
|  | } | 
|  |  | 
|  | int | 
|  | tempdisk(void) | 
|  | { | 
|  | char buf[4096]; | 
|  | int fd = temp_file(buf, sizeof buf); | 
|  | if (fd >= 0) | 
|  | remove(buf); | 
|  | return fd; | 
|  | } | 
|  |  | 
|  | #undef waitfor | 
|  | int | 
|  | samwaitfor(int pid) | 
|  | { | 
|  | int r; | 
|  | Waitmsg *w; | 
|  |  | 
|  | w = p9waitfor(pid); | 
|  | if(w == nil) | 
|  | return -1; | 
|  | r = atoi(w->msg); | 
|  | free(w); | 
|  | return r; | 
|  | } | 
|  |  | 
|  | void | 
|  | samerr(char *buf) | 
|  | { | 
|  | sprint(buf, "%s/sam.%s.err", TMPDIR, getuser()); | 
|  | } | 
|  |  | 
|  | void* | 
|  | emalloc(ulong n) | 
|  | { | 
|  | void *p; | 
|  |  | 
|  | p = malloc(n); | 
|  | if(p == 0) | 
|  | panic("malloc fails"); | 
|  | memset(p, 0, n); | 
|  | return p; | 
|  | } | 
|  |  | 
|  | void* | 
|  | erealloc(void *p, ulong n) | 
|  | { | 
|  | p = realloc(p, n); | 
|  | if(p == 0) | 
|  | panic("realloc fails"); | 
|  | return p; | 
|  | } | 
|  |  | 
|  |  |