aboutsummaryrefslogblamecommitdiffstats
path: root/glougloud/util.c
blob: c077bd34d95c02c707a0013bae1c91b4f5ef7094 (plain) (tree)






















































































                                                              
                        
           


      




                           
                                         





























































































                                                                                      
#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);
}
#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]);
}