/*----- Event logging -----------------------------------------------------*/
-/* --- @log@ --- *
+/* --- @pxlog@ --- *
*
* Arguments: @const char *p@ = @printf@-style format string
* @...@ = extra arguments to fill in
* Use: Writes out a timestamped log message.
*/
-static void log(const char *p, ...)
+static void pxlog(const char *p, ...)
{
dstr d = DSTR_INIT;
va_list ap;
/* --- Data structures --- */
typedef struct phrase {
- struct phrase *next;
- struct phrase *prev;
+ struct phrase *next, *prev;
char *tag;
char *p;
unsigned long t;
/* --- Variables --- */
-#define P_ROOT ((phrase *)&p_root)
-static struct { phrase *next; phrase *prev; } p_root = { P_ROOT, P_ROOT };
+static phrase *p_head = 0, *p_tail = 0;
+
+/* --- Utility macros --- */
+
+#define P_LINKTAIL(p) do { \
+ (p)->next = 0; \
+ (p)->prev = p_tail; \
+ *(p_tail ? &p_tail->next : &p_head) = (p); \
+ p_tail = (p); \
+} while (0)
+
+#define P_UNLINK(p) do { \
+ *((p)->next ? &(p)->next->prev : &p_tail) = (p)->prev; \
+ *((p)->prev ? &(p)->prev->next : &p_head) = (p)->next; \
+} while (0)
/* --- @p_free@ --- *
*
sel_rmtimer(&p->timer);
xfree(p->tag);
l_free(&lm, p->p);
- p->next->prev = p->prev;
- p->prev->next = p->next;
+ P_UNLINK(p);
DESTROY(p);
}
{
phrase *pp = p;
if (verbose)
- log("expiring passphrase `%s'", pp->tag);
+ pxlog("expiring passphrase `%s'", pp->tag);
p_free(pp);
}
char *p;
if ((p = l_alloc(&lm, sz)) != 0)
return (p);
- if (P_ROOT->next == P_ROOT)
+ if (!p_head)
return (0);
if (verbose) {
- log("flushing passphrase `%s' to free up needed space",
- P_ROOT->next->tag);
+ pxlog("flushing passphrase `%s' to free up needed space",
+ p_head->tag);
}
- p_free(P_ROOT->next);
+ p_free(p_head);
}
}
{
phrase *p;
- for (p = P_ROOT->next; p != P_ROOT; p = p->next) {
+ for (p = p_head; p; p = p->next) {
if (strcmp(p->tag, tag) == 0) {
if (p->t) {
struct timeval tv;
tv.tv_sec += p->t;
sel_addtimer(&sel, &p->timer, &tv, p_timer, p);
}
- p->next->prev = p->prev;
- p->prev->next = p->next;
- p->next = P_ROOT;
- p->prev = P_ROOT->prev;
- P_ROOT->prev->next = p;
- P_ROOT->prev = p;
+ P_UNLINK(p);
+ P_LINKTAIL(p);
return (p);
}
}
/* --- Link the block into the chain --- */
- pp->next = P_ROOT;
- pp->prev = P_ROOT->prev;
- P_ROOT->prev->next = pp;
- P_ROOT->prev = pp;
+ P_LINKTAIL(pp);
return (pp);
}
phrase *p;
if (!tag && verbose > 1)
- log("flushing all passphrases");
- p = P_ROOT->next;
- while (p != P_ROOT) {
+ pxlog("flushing all passphrases");
+ p = p_head;
+ while (p) {
phrase *pp = p->next;
if (!tag)
p_free(p);
else if (strcmp(p->tag, tag) == 0) {
if (verbose > 1)
- log("flushing passphrase `%s'", tag);
+ pxlog("flushing passphrase `%s'", tag);
p_free(p);
break;
}
/* --- Write a log message --- */
if (verbose > 1)
- log("passphrase `%s' requested", tag);
+ pxlog("passphrase `%s' requested", tag);
/* --- If there is no fetcher, life is simpler --- */
goto fail;
if (strcmp(pp, p->p) != 0) {
if (verbose)
- log("passphrases for `%s' don't match", tag);
+ pxlog("passphrases for `%s' don't match", tag);
p_free(p);
goto fail;
}
else if (strcmp(q, "list") == 0) {
phrase *p;
- for (p = P_ROOT->next; p != P_ROOT; p = p->next) {
+ for (p = p_head; p; p = p->next) {
if (!p->t)
pixserv_write(px, "ITEM %s no-expire\n", p->tag);
else {
else if (strcmp(q, "quit") == 0) {
if (verbose)
- log("%s client requested shutdown",
- px->f & px_stdin ? "local" : "remote");
+ pxlog("%s client requested shutdown",
+ px->f & px_stdin ? "local" : "remote");
pixserv_write(px, "OK\n");
exit(0);
}
if ((nfd = accept(fd, (struct sockaddr *)&sun, &sunsz)) < 0) {
if (verbose && errno != EAGAIN && errno != EWOULDBLOCK &&
errno != ECONNABORTED && errno != EPROTO && errno != EINTR)
- log("new connection failed: %s", strerror(errno));
+ pxlog("new connection failed: %s", strerror(errno));
return;
}
pixserv_create(nfd, nfd);
p = buf;
break;
}
- log("shutting down on %s", p);
+ pxlog("shutting down on %s", p);
}
exit(0);
}
p = buf;
break;
}
- log("received %s; flushing passphrases", p);
+ pxlog("received %s; flushing passphrases", p);
}
p_flush(0);
}
if (!S_ISSOCK(st.st_mode))
die(1, "object `%s' isn't a socket", sun->sun_path);
if (verbose)
- log("stale socket found; removing it");
+ pxlog("stale socket found; removing it");
unlink(sun->sun_path);
close(fd);
} else {
if (verbose)
- log("server already running; shutting it down");
+ pxlog("server already running; shutting it down");
write(fd, "QUIT\n", 5);
sleep(1);
close(fd);
if (rc < 0)
die(EXIT_FAILURE, d.buf);
else if (rc && verbose) {
- log(d.buf);
- log("couldn't lock passphrase buffer");
+ pxlog(d.buf);
+ pxlog("couldn't lock passphrase buffer");
}
dstr_destroy(&d);
arena_setsecure(&lm.a);
}
if (verbose)
- log("initialized ok");
+ pxlog("initialized ok");
{
int selerr = 0;
if (!sel_select(&sel))
selerr = 0;
else if (errno != EINTR && errno != EAGAIN) {
- log("error from select: %s", strerror(errno));
+ pxlog("error from select: %s", strerror(errno));
selerr++;
if (selerr > 8) {
- log("too many consecutive select errors: bailing out");
+ pxlog("too many consecutive select errors: bailing out");
exit(EXIT_FAILURE);
}
}