X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a..23bbea75793621e6b21fbb13c00d8223113cf7b5:/progs/pixie.c diff --git a/progs/pixie.c b/progs/pixie.c index 4a5e9ab..c501236 100644 --- a/progs/pixie.c +++ b/progs/pixie.c @@ -86,7 +86,7 @@ static unsigned flags = 0; /*----- Event logging -----------------------------------------------------*/ -/* --- @log@ --- * +/* --- @pxlog@ --- * * * Arguments: @const char *p@ = @printf@-style format string * @...@ = extra arguments to fill in @@ -96,7 +96,7 @@ static unsigned flags = 0; * Use: Writes out a timestamped log message. */ -static void log(const char *p, ...) +static void PRINTF_LIKE(1, 2) pxlog(const char *p, ...) { dstr d = DSTR_INIT; va_list ap; @@ -125,8 +125,7 @@ static void log(const char *p, ...) /* --- Data structures --- */ typedef struct phrase { - struct phrase *next; - struct phrase *prev; + struct phrase *next, *prev; char *tag; char *p; unsigned long t; @@ -136,8 +135,21 @@ typedef struct phrase { /* --- 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@ --- * * @@ -154,8 +166,7 @@ static void p_free(phrase *p) 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); } @@ -173,7 +184,7 @@ static void p_timer(struct timeval *tv, void *p) { phrase *pp = p; if (verbose) - log("expiring passphrase `%s'", pp->tag); + pxlog("expiring passphrase `%s'", pp->tag); p_free(pp); } @@ -193,13 +204,13 @@ static void *p_alloc(size_t sz) 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); } } @@ -216,7 +227,7 @@ static phrase *p_find(const char *tag) { 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; @@ -225,12 +236,8 @@ static phrase *p_find(const char *tag) 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); } } @@ -279,10 +286,7 @@ static phrase *p_add(const char *tag, const char *p, unsigned long t) /* --- 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); } @@ -300,15 +304,15 @@ static void p_flush(const char *tag) 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; } @@ -477,7 +481,7 @@ static int p_get(const char **q, const char *tag, unsigned mode, time_t exp) /* --- 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 --- */ @@ -514,7 +518,7 @@ static int p_get(const char **q, const char *tag, unsigned mode, time_t exp) 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; } @@ -588,7 +592,7 @@ static void pixserv_expire(struct timeval *tv, void *p) * Use: Formats a string and emits it to the output file. */ -static void pixserv_write(pixserv *px, const char *p, ...) +static void PRINTF_LIKE(2, 3) pixserv_write(pixserv *px, const char *p, ...) { dstr d = DSTR_INIT; va_list ap; @@ -695,14 +699,14 @@ OK\n\ 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 { struct timeval tv; gettimeofday(&tv, 0); TV_SUB(&tv, &p->timer.tv, &tv); - pixserv_write(px, "ITEM %s %i\n", p->tag, tv.tv_sec); + pixserv_write(px, "ITEM %s %lu\n", p->tag, (unsigned long)tv.tv_sec); } } pixserv_write(px, "OK\n"); @@ -775,8 +779,8 @@ OK\n\ 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); } @@ -837,7 +841,7 @@ static void pixserv_accept(int fd, unsigned mode, void *p) 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); @@ -886,7 +890,7 @@ static void pix_sigdie(int sig, void *p) p = buf; break; } - log("shutting down on %s", p); + pxlog("shutting down on %s", p); } exit(0); } @@ -915,7 +919,7 @@ static void pix_sigflush(int sig, void *p) p = buf; break; } - log("received %s; flushing passphrases", p); + pxlog("received %s; flushing passphrases", p); } p_flush(0); } @@ -984,12 +988,12 @@ static void pix_setup(struct sockaddr_un *sun, size_t sz) 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); @@ -1376,8 +1380,8 @@ int main(int argc, char *argv[]) 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); @@ -1437,7 +1441,7 @@ int main(int argc, char *argv[]) } if (verbose) - log("initialized ok"); + pxlog("initialized ok"); { int selerr = 0; @@ -1445,10 +1449,10 @@ int main(int argc, char *argv[]) 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); } }