X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/tripe/blobdiff_plain/73189848e83a15269a9c3af541ec32537db647b9..0617b6e7bd26c53349e9f457cdf86ccd6a4e8fbf:/client.c diff --git a/client.c b/client.c index e78f86e7..019d68f1 100644 --- a/client.c +++ b/client.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: client.c,v 1.2 2001/02/04 01:17:54 mdw Exp $ + * $Id: client.c,v 1.5 2001/02/16 21:23:39 mdw Exp $ * * Client for TrIPE * @@ -29,6 +29,16 @@ /*----- Revision history --------------------------------------------------* * * $Log: client.c,v $ + * Revision 1.5 2001/02/16 21:23:39 mdw + * Use reliable signal handling for reopening logs. + * + * Revision 1.4 2001/02/06 09:34:53 mdw + * Change ERR response to FAIL for consistency with other programs. + * + * Revision 1.3 2001/02/04 17:10:15 mdw + * Reopen logfiles on receipt of @SIGHUP@ (not done very well). Don't + * change directory -- just mangle pathnames instead. + * * Revision 1.2 2001/02/04 01:17:54 mdw * Create a configuration header file to tidy up command lines. * @@ -64,12 +74,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include "util.h" @@ -87,6 +97,7 @@ static FILE *logfp = 0; static unsigned f = 0; +static const char *logname = 0; static int fd; #define f_bogus 1u @@ -151,7 +162,7 @@ static void cline(char *p, void *b) writelog("error", d.buf); dstr_destroy(&d); } - } else if (strcmp(q, "ERR") == 0) + } else if (strcmp(q, "FAIL") == 0) die(EXIT_FAILURE, "%s", p); else if (strcmp(q, "INFO") == 0) puts(p); @@ -185,6 +196,22 @@ static void uline(char *p, void *b) } } +static void logfile(const char *name) +{ + if (logfp) + fclose(logfp); + if ((logfp = fopen(name, "a")) == 0) { + die(EXIT_FAILURE, "error opening logfile `%s': %s", + name, strerror(errno)); + } + setvbuf(logfp, 0, _IOLBF, BUFSIZ); +} + +static void sighup(int sig, void *v) +{ + logfile(logname); +} + static void version(FILE *fp) { pquis(fp, "$, TrIPE version " VERSION "\n"); @@ -301,12 +328,8 @@ int main(int argc, char *argv[]) f |= f_warn; break; case 'f': - if (logfp) - fclose(logfp); - if ((logfp = fopen(optarg, "a")) == 0) { - die(EXIT_FAILURE, "error opening logfile `%s': %s", - optarg, strerror(errno)); - } + logname = optarg; + logfile(logname); f |= f_noinput; break; default: @@ -319,13 +342,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - /* --- Set the world up --- */ - - if (chdir(dir)) { - die(EXIT_FAILURE, "couldn't set current directory to `%s': %s", - dir, strerror(errno)); - } - /* --- Connect to the server --- */ if (f & f_spawn) { @@ -344,7 +360,8 @@ int main(int argc, char *argv[]) DA_UNSHIFT(&spawnopts, (char *)spawnpath); if (!(f & f_spawnopts)) { - DA_PUSH(&spawnopts, "-d."); + DA_PUSH(&spawnopts, "-d"); + DA_PUSH(&spawnopts, (char *)dir); DA_PUSH(&spawnopts, "-a"); DA_PUSH(&spawnopts, (char *)sock); } @@ -361,6 +378,9 @@ int main(int argc, char *argv[]) dup2(pfd[1], STDOUT_FILENO); close(pfd[1]); close(pfd[0]); + if (logfp) + fclose(logfp); + closelog(); execvp(DA(&spawnopts)[0], DA(&spawnopts)); die(127, "couldn't exec `%s': %s", spawnpath, strerror(errno)); } @@ -370,17 +390,20 @@ int main(int argc, char *argv[]) } else { struct sockaddr_un sun; size_t sz = strlen(sock) + 1; - if (sz > sizeof(sun.sun_path)) + dstr d = DSTR_INIT; + dstr_putf(&d, "%s/%s", dir, sock); + if (d.sz + 1 > sizeof(sun.sun_path)) die(EXIT_FAILURE, "socket name `%s' too long", sock); memset(&sun, 0, sizeof(sun)); sun.sun_family = AF_UNIX; - memcpy(sun.sun_path, sock, sz); - sz += offsetof(struct sockaddr_un, sun_path); + memcpy(sun.sun_path, d.buf, d.sz + 1); + sz = d.sz + offsetof(struct sockaddr_un, sun_path) + 1; + dstr_destroy(&d); if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) die(EXIT_FAILURE, "error making socket: %s", strerror(errno)); if (connect(fd, (struct sockaddr *)&sun, sz)) { die(EXIT_FAILURE, "error connecting to `%s': %s", - sock, strerror(errno)); + sun.sun_path, strerror(errno)); } } @@ -399,7 +422,7 @@ int main(int argc, char *argv[]) selbuf_init(&bu, &sel, STDIN_FILENO, uline, &bu); selbuf_init(&bs, &sel, fd, sline, &bs); for (;;) { - if (sel_select(&sel)) + if (sel_select(&sel) && errno != EINTR && errno != EAGAIN) die(EXIT_FAILURE, "select failed: %s", strerror(errno)); } } @@ -423,20 +446,23 @@ int main(int argc, char *argv[]) /* --- Pull everything else out of the box --- */ { - lbuf b; - lbuf_init(&b, cline, 0); + sel_state sel; + selbuf b; + sig hup; + + sel_init(&sel); + selbuf_init(&b, &sel, fd, cline, 0); + if (f & f_syslog) openlog(QUIS, 0, LOG_DAEMON); + if (logfp) { + sig_init(&sel); + sig_add(&hup, SIGHUP, sighup, 0); + } for (;;) { - size_t sz = lbuf_free(&b, &p); - ssize_t n = read(fd, p, sz); - if (n < 0) - die(EXIT_FAILURE, "read failed: %s", strerror(errno)); - if (n == 0) - break; - lbuf_flush(&b, p, n); + if (sel_select(&sel) && errno != EINTR && errno != EAGAIN) + die(EXIT_FAILURE, "select failed: %s", strerror(errno)); } - lbuf_close(&b); } return (0);