diff options
author | Omar Polo <op@omarpolo.com> | 2023-06-06 08:50:54 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2023-06-06 08:50:54 +0000 |
commit | 281a8852b3a2d76c10d2fb6476a706746d05509b (patch) | |
tree | a9c5a73adf8e85597f0eb87d1865e28249c2b8a1 /log.c | |
parent | 3dd89fbb44f7f61b8c89db12f4469ca49c17bc68 (diff) |
rename log.[ch] to logger.[ch]
Diffstat (limited to 'log.c')
-rw-r--r-- | log.c | 382 |
1 files changed, 0 insertions, 382 deletions
@@ -1,382 +0,0 @@ -/* - * Copyright (c) 2021 Omar Polo <op@omarpolo.com> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "gmid.h" - -#include <sys/types.h> -#include <sys/uio.h> - -#include <errno.h> -#include <event.h> -#include <imsg.h> -#include <netdb.h> -#include <poll.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <syslog.h> -#include <time.h> - -#include "log.h" - -static struct event imsgev; - -static FILE *log; - -static void handle_imsg_quit(struct imsgbuf*, struct imsg*, size_t); -static void handle_imsg_log(struct imsgbuf*, struct imsg*, size_t); -static void handle_imsg_log_type(struct imsgbuf*, struct imsg*, size_t); -static void handle_dispatch_imsg(int, short, void*); - -static imsg_handlerfn *handlers[] = { - [IMSG_QUIT] = handle_imsg_quit, - [IMSG_LOG] = handle_imsg_log, - [IMSG_LOG_REQUEST] = handle_imsg_log, - [IMSG_LOG_TYPE] = handle_imsg_log_type, -}; - -static inline void -print_date(FILE *f) -{ - struct tm tminfo; - time_t t; - char buf[20]; - - time(&t); - strftime(buf, sizeof(buf), "%F %T", - localtime_r(&t, &tminfo)); - fprintf(f, "[%s] ", buf); -} - -static inline int -should_log(int priority) -{ - switch (priority) { - case LOG_ERR: - return 1; - case LOG_WARNING: - return 1; - case LOG_NOTICE: - return conf.verbose >= 1; - case LOG_INFO: - return conf.verbose >= 2; - case LOG_DEBUG: - return conf.verbose >= 3; - default: - return 0; - } -} - -static inline void -send_log(int type, int priority, const char *msg, size_t len) -{ - imsg_compose(&logibuf, type, priority, 0, -1, msg, len); - imsg_flush(&logibuf); -} - -static __dead void -fatal_impl(int use_err, const char *fmt, va_list ap) -{ - struct pollfd pfd; - char *str, *tmp; - int r, t, err; - - err = errno; - - if ((r = vasprintf(&str, fmt, ap)) != -1) { - if (use_err && - (t = asprintf(&tmp, "%s: %s", str, strerror(err))) != - -1) { - free(str); - str = tmp; - r = t; - } - } else - str = NULL, r = 0; - - send_log(IMSG_LOG, LOG_CRIT, str, r + 1); - free(str); - - /* wait for the logger process to shut down */ - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = logibuf.fd; - pfd.events = POLLIN; - poll(&pfd, 1, 1000); - - exit(1); -} - -void __dead -fatal(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fatal_impl(1, fmt, ap); - va_end(ap); -} - -void __dead -fatalx(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fatal_impl(0, fmt, ap); - va_end(ap); -} - -static inline void -vlog(int priority, struct client *c, - const char *fmt, va_list ap) -{ - char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; - char *fmted, *s; - size_t len; - int ec; - - if (!should_log(priority)) - return; - - if (c != NULL) { - len = sizeof(c->addr); - ec = getnameinfo((struct sockaddr*)&c->addr, len, - hbuf, sizeof(hbuf), - sbuf, sizeof(sbuf), - NI_NUMERICHOST | NI_NUMERICSERV); - if (ec != 0) - fatal("getnameinfo: %s", gai_strerror(ec)); - } - - if (vasprintf(&fmted, fmt, ap) == -1) - fatal("vasprintf: %s", strerror(errno)); - - if (c == NULL) - ec = asprintf(&s, "internal: %s", fmted); - else - ec = asprintf(&s, "%s:%s %s", hbuf, sbuf, fmted); - - if (ec < 0) - fatal("asprintf: %s", strerror(errno)); - - send_log(IMSG_LOG, priority, s, ec+1); - - free(fmted); - free(s); -} - -void -log_err(struct client *c, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(LOG_ERR, c, fmt, ap); - va_end(ap); -} - -void -log_warn(struct client *c, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(LOG_WARNING, c, fmt, ap); - va_end(ap); -} - -void -log_notice(struct client *c, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(LOG_NOTICE, c, fmt, ap); - va_end(ap); -} - -void -log_info(struct client *c, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(LOG_INFO, c, fmt, ap); - va_end(ap); -} - -void -log_debug(struct client *c, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vlog(LOG_DEBUG, c, fmt, ap); - va_end(ap); -} - -/* strchr, but with a bound */ -static char * -gmid_strnchr(char *s, int c, size_t len) -{ - size_t i; - - for (i = 0; i < len; ++i) - if (s[i] == c) - return &s[i]; - return NULL; -} - -void -log_request(struct client *c, char *meta, size_t l) -{ - char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV], b[GEMINI_URL_LEN]; - char *fmted; - const char *t; - size_t len; - int ec; - - len = sizeof(c->addr); - ec = getnameinfo((struct sockaddr*)&c->addr, len, - hbuf, sizeof(hbuf), - sbuf, sizeof(sbuf), - NI_NUMERICHOST | NI_NUMERICSERV); - if (ec != 0) - fatalx("getnameinfo: %s", gai_strerror(ec)); - - if (c->iri.schema != NULL) { - /* serialize the IRI */ - strlcpy(b, c->iri.schema, sizeof(b)); - strlcat(b, "://", sizeof(b)); - - /* log the decoded host name, but if it was invalid - * use the raw one. */ - if (*c->domain != '\0') - strlcat(b, c->domain, sizeof(b)); - else - strlcat(b, c->iri.host, sizeof(b)); - - if (*c->iri.path != '/') - strlcat(b, "/", sizeof(b)); - strlcat(b, c->iri.path, sizeof(b)); /* TODO: sanitize UTF8 */ - if (*c->iri.query != '\0') { /* TODO: sanitize UTF8 */ - strlcat(b, "?", sizeof(b)); - strlcat(b, c->iri.query, sizeof(b)); - } - } else { - if ((t = c->req) == NULL) - t = ""; - strlcpy(b, t, sizeof(b)); - } - - if ((t = gmid_strnchr(meta, '\r', l)) == NULL) - t = meta + len; - - ec = asprintf(&fmted, "%s:%s GET %s %.*s", hbuf, sbuf, b, - (int)(t-meta), meta); - if (ec < 0) - err(1, "asprintf"); - send_log(IMSG_LOG_REQUEST, LOG_NOTICE, fmted, ec+1); - free(fmted); -} - - - -static void -do_log(int type, int priority, const char *msg) -{ - int quit = 0; - - if (priority == LOG_CRIT) { - quit = 1; - priority = LOG_ERR; - } - - if (log != NULL) { - if (type != IMSG_LOG_REQUEST) - print_date(log); - fprintf(log, "%s\n", msg); - } else - syslog(LOG_DAEMON | priority, "%s", msg); - - if (quit) - exit(1); -} - -static void -handle_imsg_quit(struct imsgbuf *ibuf, struct imsg *imsg, size_t datalen) -{ - event_loopbreak(); -} - -static void -handle_imsg_log(struct imsgbuf *ibuf, struct imsg *imsg, size_t datalen) -{ - int priority; - char *msg; - - msg = imsg->data; - msg[datalen-1] = '\0'; - priority = imsg->hdr.peerid; - do_log(imsg->hdr.type, priority, msg); -} - -static void -handle_imsg_log_type(struct imsgbuf *ibuf, struct imsg *imsg, size_t datalen) -{ - if (log != NULL && log != stderr) { - fflush(log); - fclose(log); - } - log = NULL; - - if (imsg->fd != -1) { - if ((log = fdopen(imsg->fd, "a")) == NULL) { - syslog(LOG_DAEMON | LOG_ERR, "fdopen: %s", - strerror(errno)); - exit(1); - } - } -} - -static void -handle_dispatch_imsg(int fd, short ev, void *d) -{ - struct imsgbuf *ibuf = d; - dispatch_imsg(ibuf, handlers, sizeof(handlers)); -} - -int -logger_main(int fd, struct imsgbuf *ibuf) -{ - log = stderr; - - openlog(getprogname(), LOG_NDELAY, LOG_DAEMON); - tzset(); - - event_init(); - - event_set(&imsgev, fd, EV_READ | EV_PERSIST, &handle_dispatch_imsg, ibuf); - event_add(&imsgev, NULL); - - sandbox_logger_process(); - - event_dispatch(); - - closelog(); - - return 0; -} |