/* -*-c-*-
*
- * $Id: client.c,v 1.2 2001/02/04 01:17:54 mdw Exp $
+ * $Id: client.c,v 1.3 2001/02/04 17:10:15 mdw Exp $
*
* Client for TrIPE
*
/*----- Revision history --------------------------------------------------*
*
* $Log: client.c,v $
+ * 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.
*
static FILE *logfp = 0;
static unsigned f = 0;
static int fd;
+static volatile sig_atomic_t reopen = 0;
#define f_bogus 1u
#define f_spawn 2u
errno = e;
}
+static void sighup(int sig)
+{
+ reopen = 1;
+}
+
static void writelog(const char *cat, const char *msg)
{
char buf[256];
}
}
+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 version(FILE *fp)
{
pquis(fp, "$, TrIPE version " VERSION "\n");
const char *sock = "tripesock";
const char *spawnpath = "tripe";
string_v spawnopts = DA_INIT;
+ const char *logname = 0;
char *p;
ego(argv[0]);
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));
}
}
lbuf_init(&b, cline, 0);
if (f & f_syslog)
openlog(QUIS, 0, LOG_DAEMON);
+ if (logfp) {
+ struct sigaction sa;
+ sa.sa_handler = sighup;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGHUP, &sa, 0);
+ }
for (;;) {
- size_t sz = lbuf_free(&b, &p);
- ssize_t n = read(fd, p, sz);
- if (n < 0)
+ size_t sz;
+ ssize_t n;
+ if (reopen) {
+ logfile(logname);
+ reopen = 0;
+ }
+ sz = lbuf_free(&b, &p);
+ n = read(fd, p, sz);
+ if (n < 0) {
+ if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
+ continue;
die(EXIT_FAILURE, "read failed: %s", strerror(errno));
+ }
if (n == 0)
break;
lbuf_flush(&b, p, n);