#include #include #include #include #include #include #include #include #include #include #include "glougloud.h" FILE *logfile; int loglevel; int logpinvalid; #define LOGFILE "/var/log/glougloud" #define LOG_FORCED -2 #define LOG_FATAL -1 #define LOG_WARN 0 #define LOG_INFO 1 #define LOG_DEBUG 2 static void logit(int, const char *, const char *, va_list); void log_init(int level, int pinvalid) { logfile = fopen(LOGFILE, "a+"); if (!logfile) { printf("cannot open log file %s!\n", LOGFILE); exit(1); } loglevel = level; logpinvalid = pinvalid; } void log_tmp(const char *msg, ...) { va_list ap; va_start(ap, msg); logit(LOG_FORCED, "XXX ", msg, ap); va_end(ap); } void log_pinvalid(const char *msg, ...) { va_list ap; if (!logpinvalid) return; va_start(ap, msg); logit(LOG_FORCED, "pinvalid: ", msg, ap); va_end(ap); } void log_debug(const char *msg, ...) { va_list ap; va_start(ap, msg); logit(LOG_DEBUG, "", msg, ap); va_end(ap); } void log_info(const char *msg, ...) { va_list ap; va_start(ap, msg); logit(LOG_INFO, "", msg, ap); va_end(ap); } void log_warn(const char *msg, ...) { va_list ap; va_start(ap, msg); logit(LOG_WARN, "", msg, ap); va_end(ap); } #if defined(__OpenBSD__) void __dead #else void #endif fatal(const char *msg, ...) { va_list ap; va_start(ap, msg); logit(LOG_FATAL, "fatal: ", msg, ap); va_end(ap); exit(1); } /* XXX mpsafe */ static void logit(int level, const char *prefix, const char *msg, va_list ap) { time_t clock; if (level <= loglevel) { time(&clock); fprintf(logfile, "%d ", (int)clock); vfprintf(logfile, prefix, ap); vfprintf(logfile, msg, ap); fprintf(logfile, "\n"); fflush(logfile); } } void * xmalloc(size_t size) { void *ptr; if (size == 0) fatal("xmalloc: zero size"); ptr = malloc(size); if (ptr == NULL) fatal("xmalloc: out of memory (allocating %lu bytes)", (u_long) size); return ptr; } void * xcalloc(size_t nmemb, size_t size) { void *ptr; if (size == 0) fatal("xcalloc: zero size"); ptr = calloc(nmemb, size); if (ptr == NULL) fatal("xcalloc: out of memory (allocating %lu bytes)", (u_long) size); return ptr; } void fd_nonblock(int fd) { int flags = fcntl(fd, F_GETFL, 0); int rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK); if (rc == -1) log_warn("failed to set fd %i non-blocking", fd); } void droppriv() { struct passwd *pw; pw = getpwnam(GLOUGLOUD_USER); if (!pw) fatal("unknown user %s", GLOUGLOUD_USER); if (chroot(pw->pw_dir) != 0) fatal("unable to chroot"); if (chdir("/") != 0) fatal("unable to chdir"); if (setgroups(1, &pw->pw_gid) == -1) fatal("setgroups() failed"); if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) fatal("setresgid failed"); if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) fatal("setresuid() failed"); endpwent(); } void addrcpy(struct sockaddr_in *dst, struct sockaddr_in *src) { dst->sin_addr.s_addr = src->sin_addr.s_addr; dst->sin_port = src->sin_port; dst->sin_family = src->sin_family; } void socketpair_prepare(int fd[2]) { if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fd) == -1) fatal("socketpair_prepare"); fd_nonblock(fd[0]); fd_nonblock(fd[1]); }