aboutsummaryrefslogtreecommitdiffstats
path: root/glougloud/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'glougloud/util.c')
-rw-r--r--glougloud/util.c188
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]);
+}
+