X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/fa4bef8080b75d2c8c75169667c7ba1b4a124232..ef4a1ab72d88f8790c367b513863d4f9a101a34d:/client.c diff --git a/client.c b/client.c index c1abe68e..1910ef74 100644 --- a/client.c +++ b/client.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: client.c,v 1.6 2001/02/22 09:06:08 mdw Exp $ + * $Id: client.c,v 1.13 2003/11/29 23:49:32 mdw Exp $ * * Client for TrIPE * @@ -29,6 +29,30 @@ /*----- Revision history --------------------------------------------------* * * $Log: client.c,v $ + * Revision 1.13 2003/11/29 23:49:32 mdw + * Debianization. + * + * Revision 1.12 2003/10/15 09:29:38 mdw + * Cosmetic fix to changelog comment. + * + * Revision 1.11 2003/07/13 11:19:49 mdw + * Incompatible protocol fix! Include message type code under MAC tag to + * prevent cut-and-paste from key-exchange messages to general packet + * transport. + * + * Revision 1.10 2003/05/17 10:59:19 mdw + * Put a newline in the pidfile. + * + * Revision 1.9 2002/01/13 14:57:18 mdw + * Track @lbuf@ changes in mLib. + * + * Revision 1.8 2001/06/19 22:09:37 mdw + * Move the program name to the right place when constructing the arguments + * to pass to a new server. + * + * Revision 1.7 2001/02/22 09:07:54 mdw + * Write a pidfile on request, and delete it when finished. + * * Revision 1.6 2001/02/22 09:06:08 mdw * Fix logfile rotation to avoid program collapse. * @@ -98,9 +122,10 @@ /*----- Static variables --------------------------------------------------*/ +static const char *pidfile = 0; +static const char *logname = 0; static FILE *logfp = 0; static unsigned f = 0; -static const char *logname = 0; static int fd; #define f_bogus 1u @@ -117,9 +142,8 @@ static int fd; static void reap(int sig) { - int s; int e = errno; - while (waitpid(-1, &s, WNOHANG) > 0) + while (waitpid(-1, 0, WNOHANG) > 0) ; errno = e; } @@ -133,7 +157,7 @@ static void writelog(const char *cat, const char *msg) fprintf(logfp, "%s %s: %s\n", buf, cat, msg); } -static void cline(char *p, void *b) +static void cline(char *p, size_t len, void *b) { char *q; if (!p) { @@ -175,7 +199,7 @@ static void cline(char *p, void *b) die(EXIT_FAILURE, "unexpected output `%s %s'", q, p); } -static void sline(char *p, void *b) +static void sline(char *p, size_t len, void *b) { if (!p) { if (!(f & f_uclose)) @@ -185,17 +209,15 @@ static void sline(char *p, void *b) puts(p); } -static void uline(char *p, void *b) +static void uline(char *p, size_t len, void *b) { - size_t sz; if (!p) { selbuf_destroy(b); shutdown(fd, 1); f |= f_uclose; } else { - sz = strlen(p); - p[sz] = '\n'; - write(fd, p, sz + 1); + p[len] = '\n'; + write(fd, p, len + 1); } } @@ -226,6 +248,19 @@ static void sighup(int sig, void *v) logfile(logname); } +static void cleanup(void) +{ + if (pidfile) + unlink(pidfile); +} + +static void sigdie(int sig) +{ + cleanup(); + signal(sig, SIG_DFL); + raise(sig); +} + static void version(FILE *fp) { pquis(fp, "$, TrIPE version " VERSION "\n"); @@ -238,7 +273,8 @@ Usage:\n\ $ [-w] [-options] [command [args]...]\n\ $ [-Dl] [-f file] [-options]\n\ Options:\n\ - [-s] [-d directory] [-a socket] [-p program] [-S arg,arg,...]\n\ + [-s] [-d directory] [-a socket] [-P pidfile]\n\ + [-p program] [-S arg,arg,...]\n\ "); } @@ -256,8 +292,10 @@ Options in full:\n\ -u, --usage Show brief usage message.\n\ \n\ -D, --daemon Become a background task after connecting.\n\ --d, --directory=DIR Select current directory [default /var/lib/tripe]\n\ --a, --admin-socket=FILE Select socket to connect to.\n\ +-d, --directory=DIR Select current directory [default " CONFIGDIR "].\n\ +-a, --admin-socket=FILE Select socket to connect to + [default " SOCKETDIR "/tripesock].\n\ +-P, --pidfile=FILE Write process-id to FILE.\n\ \n\ -s, --spawn Start server rather than connecting.\n\ -p, --spawn-path=PATH Specify path to executable.\n\ @@ -271,11 +309,12 @@ Options in full:\n\ int main(int argc, char *argv[]) { - const char *dir = "/var/lib/tripe"; - const char *sock = "tripesock"; + const char *dir = CONFIGDIR; + const char *sock = SOCKETDIR "/tripesock"; const char *spawnpath = "tripe"; string_v spawnopts = DA_INIT; char *p; + FILE *pidfp = 0; ego(argv[0]); @@ -298,10 +337,11 @@ int main(int argc, char *argv[]) { "syslog", 0, 0, 'l' }, { "logfile", OPTF_ARGREQ, 0, 'f' }, { "warnings", 0, 0, 'w' }, + { "pidfile", OPTF_ARGREQ, 0, 'P' }, { 0, 0, 0, 0 } }; - int i = mdwopt(argc, argv, "hvuDd:a:sp:S:lwf:n", opts, 0, 0, 0); + int i = mdwopt(argc, argv, "+hvuDd:a:sp:S:lwf:nP:", opts, 0, 0, 0); if (i < 0) break; switch (i) { @@ -343,9 +383,11 @@ int main(int argc, char *argv[]) break; case 'f': logname = optarg; - logfile(logname); f |= f_noinput; break; + case 'P': + pidfile = optarg; + break; default: f |= f_bogus; break; @@ -356,6 +398,25 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + /* --- Set various things up --- */ + + if (chdir(dir)) { + die(EXIT_FAILURE, "couldn't set `%s' as current directory: %s", + dir, strerror(errno)); + } + if (logname) + logfile(logname); + if (!pidfile && (f & f_daemon) && ((f & f_syslog) || logname)) + pidfile = "tripectl.pid"; + if (pidfile && (pidfp = fopen(pidfile, "w")) == 0) { + die(EXIT_FAILURE, "couldn't open `%s' for writing: %s", + pidfile, strerror(errno)); + } + signal(SIGINT, sigdie); + signal(SIGQUIT, sigdie); + signal(SIGTERM, sigdie); + atexit(cleanup); + /* --- Connect to the server --- */ if (f & f_spawn) { @@ -372,13 +433,10 @@ int main(int argc, char *argv[]) #endif sigaction(SIGCHLD, &sa, 0); + DA_UNSHIFT(&spawnopts, (char *)sock); + DA_UNSHIFT(&spawnopts, "-a"); + DA_UNSHIFT(&spawnopts, "-d."); DA_UNSHIFT(&spawnopts, (char *)spawnpath); - if (!(f & f_spawnopts)) { - DA_PUSH(&spawnopts, "-d"); - DA_PUSH(&spawnopts, (char *)dir); - DA_PUSH(&spawnopts, "-a"); - DA_PUSH(&spawnopts, (char *)sock); - } DA_PUSH(&spawnopts, 0); if (socketpair(PF_UNIX, SOCK_STREAM, 0, pfd)) die(EXIT_FAILURE, "error from socketpair: %s", strerror(errno)); @@ -394,7 +452,11 @@ int main(int argc, char *argv[]) close(pfd[0]); if (logfp) fclose(logfp); + if (pidfp) + fclose(pidfp); closelog(); + if (f & f_daemon) + u_detach(); execvp(DA(&spawnopts)[0], DA(&spawnopts)); die(127, "couldn't exec `%s': %s", spawnpath, strerror(errno)); } @@ -404,15 +466,12 @@ int main(int argc, char *argv[]) } else { struct sockaddr_un sun; size_t sz = strlen(sock) + 1; - dstr d = DSTR_INIT; - dstr_putf(&d, "%s/%s", dir, sock); - if (d.sz + 1 > sizeof(sun.sun_path)) + if (sz > 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, d.buf, d.sz + 1); - sz = d.sz + offsetof(struct sockaddr_un, sun_path) + 1; - dstr_destroy(&d); + memcpy(sun.sun_path, sock, sz); + sz = sz + offsetof(struct sockaddr_un, sun_path); 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)) { @@ -425,6 +484,10 @@ int main(int argc, char *argv[]) if (u_daemon()) die(EXIT_FAILURE, "error becoming daemon: %s", strerror(errno)); } + if (pidfp) { + fprintf(pidfp, "%li\n", (long)getpid()); + fclose(pidfp); + } /* --- If we're meant to be interactive, do that --- */