diff options
Diffstat (limited to 'glougloud/util.c')
-rw-r--r-- | glougloud/util.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/glougloud/util.c b/glougloud/util.c new file mode 100644 index 0000000..83d55a0 --- /dev/null +++ b/glougloud/util.c @@ -0,0 +1,188 @@ +#include <sys/types.h> +#include <sys/stat.h> + +#include <stdlib.h> +#include <stdarg.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <time.h> +#include <pwd.h> +#include <string.h> + +#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); +} +void __dead +fatal(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + logit(LOG_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]); +} + |