#include #include #include #include #include #include #include #include #include "util.h" int warn(const char *msg, ...) { va_list al; va_start(al, msg); fprintf(stderr, "%s: ", progname); vfprintf(stderr, msg, al); va_end(al); return 1; } void die(const char *msg, ...) { va_list al; va_start(al, msg); fprintf(stderr, "%s: ", progname); vfprintf(stderr, msg, al); va_end(al); exit(1); } void die_hard(const char *msg, ...) { va_list al; va_start(al, msg); fprintf(stderr, "%s: ", progname); vfprintf(stderr, msg, al); va_end(al); abort(); } void setprogname(const char *name) { char *slash=strrchr(name, '/'); progname=slash? slash+1: name; } void *xmalloc(size_t size) { void *data; if (!size) return NULL; data=malloc(size); if (!data) die("malloc %li: %s\n", (long)size, strerror(errno)); return data; } char *xstrdup(const char *s) { void *data; if (!s) return NULL; data=strdup(s); if (!data) die("strdup(%i chars): %s\n", strlen(s), strerror(errno)); return data; } int getushort(const char *s, unsigned short *svalp) { char *endptr; long lval; unsigned short sval; int err; err=errno; errno=0; lval=strtol(s, &endptr, 10); if ((lval==LONG_MIN || lval==LONG_MAX) && errno==ERANGE) return -1; errno=err; sval=lval; if (sval!=lval || lval<0) { errno=ERANGE; return -1; } if (!*s || *endptr) { errno=EINVAL; return -1; } *svalp=sval; return 0; } void inout_program(const char *command, fd_t **in, fd_t **out) { int toprog[2], fromprog[2]; pid_t pid; if (pipe(toprog) || pipe(fromprog)) die("pipe: %s\n", strerror(errno)); if ((pid=fork())==-1) die("fork: %s\n", strerror(errno)); if (!pid) { const char *accept="0123456789-=_+:,./" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int status; dup2(toprog[0], STDIN_FILENO); dup2(fromprog[1], STDOUT_FILENO); dup2(fromprog[1], STDERR_FILENO); close(toprog[0]); close(toprog[1]); close(fromprog[0]); close(fromprog[1]); if (strspn(command, accept)==strlen(command)) { execlp(command, NULL); _exit(1); } status=system(command); /* XXX */ _exit(!!status); } close(toprog[0]); close(fromprog[1]); *in=fd_alloc(); *out=fd_alloc(); fd_init(*out, toprog[1], 0, 1, "(to program)"); fd_init(*in, fromprog[0], 1, 0, "(from program)"); }