/* -*-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
*
/*----- 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.
*
#include <mLib/alloc.h>
#include <mLib/darray.h>
#include <mLib/dstr.h>
-#include <mLib/lbuf.h>
#include <mLib/mdwopt.h>
#include <mLib/quis.h>
#include <mLib/report.h>
#include <mLib/sel.h>
#include <mLib/selbuf.h>
+#include <mLib/sig.h>
#include <mLib/str.h>
#include "util.h"
static FILE *logfp = 0;
static unsigned f = 0;
+static const char *logname = 0;
static int fd;
#define f_bogus 1u
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);
}
}
+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");
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:
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) {
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);
}
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));
}
} 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));
}
}
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));
}
}
/* --- 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);