From 55923b742832caa9f0301032f7d657de76e2ff0f Mon Sep 17 00:00:00 2001 From: Mike Belopuhov Date: Wed, 5 Mar 2014 16:37:31 +0100 Subject: [PATCH] Add some basic logger framework --- Makefile | 2 +- dns.c | 4 +- icb.c | 2 + icbd.c | 3 ++ icbd.h | 4 ++ logger.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 logger.c diff --git a/Makefile b/Makefile index f20d16c..f78485c 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ BINDIR= ${PREFIX}/sbin MANDIR= ${PREFIX}/man/man PROG= icbd -SRCS= cmd.c dns.c icb.c icbd.c +SRCS= cmd.c dns.c icb.c icbd.c logger.c MAN= icbd.8 CFLAGS+= -W -Wall -Werror diff --git a/dns.c b/dns.c index cf64f86..10dde3e 100644 --- a/dns.c +++ b/dns.c @@ -37,6 +37,7 @@ void dns_dispatch(int, short, void *); void dns_done(int, short, void *); + int dns_pipe; struct icbd_dnsquery { @@ -122,13 +123,12 @@ dns_dispatch(int fd, short event, void *arg __attribute__((unused))) struct icbd_dnsquery q; int gerr; - arg = NULL; if (event != EV_READ) return; if (read(fd, &q, sizeof q) != sizeof q) { syslog(LOG_ERR, "dns read: %m"); - exit(1); + exit(EX_DATAERR); } sa = (struct sockaddr *)&q.u.req; diff --git a/icb.c b/icb.c index b50b29b..ca7a887 100644 --- a/icb.c +++ b/icb.c @@ -234,6 +234,8 @@ icb_groupmsg(struct icb_session *is, char *msg) is->nick, ICB_M_SEP, msg); buf[0] = buflen; + logger(time(NULL), ig->name, is->nick, msg); + LIST_FOREACH(s, &ig->sess, entry) { if (s == is) continue; diff --git a/icbd.c b/icbd.c index 7eeeab3..73dabb4 100644 --- a/icbd.c +++ b/icbd.c @@ -211,6 +211,9 @@ main(int argc, char *argv[]) return (EX_UNAVAILABLE); } + /* start the logger service */ + logger_init(); + /* start a dns resolver thread */ dns_init(); diff --git a/icbd.h b/icbd.h index 66557b8..b748c5e 100644 --- a/icbd.h +++ b/icbd.h @@ -30,3 +30,7 @@ time_t getmonotime(void); struct sockaddr_storage; int dns_init(void); int dns_rresolv(struct icb_session *, struct sockaddr_storage *); + +/* logger.c */ +int logger_init(void); +void logger(time_t, char *, char *, char *); diff --git a/logger.c b/logger.c new file mode 100644 index 0000000..aaa6f18 --- /dev/null +++ b/logger.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2014 Mike Belopuhov + * Copyright (c) 2009 Michael Shalayeff + * + * 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 MIND, 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "icb.h" +#include "icbd.h" + +void logger_dispatch(int, short, void *); + +int logger_pipe; + +struct icbd_logentry { + time_t timestamp; + char group[ICB_MAXGRPLEN]; + char nick[ICB_MAXNICKLEN]; + size_t length; +}; + +int +logger_init(void) +{ + static struct event ev; + struct passwd *pw; + int pipes[2]; + + if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipes) == -1) { + syslog(LOG_ERR, "socketpair: %m"); + exit(EX_OSERR); + } + + switch (fork()) { + case -1: + syslog(LOG_ERR, "fork: %m"); + exit(EX_OSERR); + case 0: + break; + + default: + close(pipes[1]); + logger_pipe = pipes[0]; + return (0); + } + + setproctitle("logger"); + close(pipes[0]); + + if ((pw = getpwnam(ICBD_USER)) == NULL) { + syslog(LOG_ERR, "No passwd entry for %s", ICBD_USER); + exit(EX_NOUSER); + } + + if (setusercontext(NULL, pw, pw->pw_uid, + LOGIN_SETALL & ~LOGIN_SETUSER) < 0) + exit(EX_NOPERM); + + if (setuid(pw->pw_uid) < 0) { + syslog(LOG_ERR, "%d: %m", pw->pw_uid); + exit(EX_NOPERM); + } + + if (chdir(pw->pw_dir) < 0) { + syslog(LOG_ERR, "chdir: %m"); + exit(EX_UNAVAILABLE); + } + + event_init(); + + /* event for message processing */ + event_set(&ev, pipes[1], EV_READ | EV_PERSIST, logger_dispatch, NULL); + if (event_add(&ev, NULL) < 0) { + syslog(LOG_ERR, "event_add: %m"); + exit (EX_UNAVAILABLE); + } + + return event_dispatch(); +} + +void +logger_dispatch(int fd, short event, void *arg __attribute__((unused))) +{ + char buf[512]; + struct icbd_logentry e; + struct iovec iov[2]; + + if (event != EV_READ) + return; + + bzero(&e, sizeof e); + iov[0].iov_base = &e; + iov[0].iov_len = sizeof e; + + iov[1].iov_base = buf; + iov[1].iov_len = sizeof buf; + + if (readv(fd, iov, 2) < (ssize_t)sizeof e) { + syslog(LOG_ERR, "logger read: %m"); + exit(EX_DATAERR); + } + + /* XXX */ + if (iov[1].iov_len < e.length) { + syslog(LOG_ERR, "logger read %lu out of %lu", + iov[1].iov_len, e.length); + } + + /* TODO: check time of the day and open the next file */ + + fprintf(stderr, "%s@%s: %s\n", e.nick, e.group, buf); +} + +void +logger(time_t timestamp, char *group, char *nick, char *what) +{ + struct icbd_logentry e; + struct iovec iov[2]; + + e.timestamp = timestamp; + strlcpy(e.group, group, ICB_MAXGRPLEN); + strlcpy(e.nick, nick, ICB_MAXNICKLEN); + e.length = strlen(what) + 1; + + iov[0].iov_base = &e; + iov[0].iov_len = sizeof e; + + iov[1].iov_base = what; + iov[1].iov_len = e.length; + + if (writev(logger_pipe, iov, 2) == -1) + syslog(LOG_ERR, "logger write: %m"); +}