Logo Search packages:      
Sourcecode: ldapdns version File versions  Download package

error.c

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#include "version.h"
#include "str.h"

int use_syslog = 0;
static FILE *logfp = 0;

#ifdef HAVE_SYSLOG
#include <syslog.h>

const int log_debug = LOG_DEBUG;
const int log_info = LOG_INFO;
const int log_warning = LOG_WARNING;
const int log_fatal = LOG_CRIT;

#else

const int log_debug = -1;
const int log_info = 0;
const int log_warning = 1;
const int log_fatal = 2;

#endif

static void log_pipe(const char *s)
{
      int fds[2];

      if (pipe(fds) == -1) {
            cfatal("Could not create pipe: %s");
      }

      switch (fork()) {
      case -1:
            cfatal("Could not fork: %s");
            break;
      case 0:
            close(0);
            close(1);
            close(2);
            dup2(fds[0], 0);
            execl("/bin/sh", "/bin/sh", "-c", s);
            exit(1);
      };
      close(fds[0]);
      logfp = fdopen(fds[1], "w");
      if (!logfp) {
            logfp = stderr;
            cfatal("Could not attach fd to logger: %s");
      }
}
static void log_file(const char *s)
{
      int fd;

      fd = open(s, O_CREAT|O_WRONLY|O_APPEND, 0666);
      if (fd == -1) {
            cfatal("Could not open `%s' for writing: %s", s);
      }

      logfp = fdopen(fd, "w");
      if (!logfp) {
            logfp = stderr;
            cfatal("Could not attach fd to logger: %s");
      }
}

void log_init(char *s)
{
      int fd;

      use_syslog = 0;
      logfp = stderr;
      if (s && str_equali(s, "quiet")) {
            logfp = fopen("/dev/null", "w");
      } else if (s && *s == '/') {
            log_file(s);
      } else if (s && *s == '|') {
            log_pipe(s+1);
      } else if (s && str_starti(s, "file:/")) {
            log_file(s+5);
      } else if (s && str_starti(s, "pipe:/")) {
            log_pipe(s+5);
      } else if (s && str_starti(s, "exec:/")) {
            log_pipe(s+5);
      } else if (s && str_starti(s, "prog:/")) {
            log_pipe(s+5);
      } else if (s && str_starti(s, "program:/")) {
            log_pipe(s+8);

      } else if (s && str_equali(s, "syslog")) {
#ifdef HAVE_SYSLOG
            use_syslog = 1;
            openlog(PROGRAM, LOG_CONS | LOG_NDELAY 
#ifdef LOG_PERROR
                        | LOG_PERROR 
#endif
                        | LOG_PID, LOG_DAEMON);
            logfp = 0;
#else
            use_syslog = 0;
            warning("You do not have syslog() support compiled in, defaulting to stderr");
#endif
      }
}
static void _log_helper(int lev, int clib_flag, const char *m, va_list ap)
{
      str_t buf;
      char lbuf[32];

      str_init(buf);
      while (*m) {
            if (*m == '%') {
                  switch (m[1]) {
                  case '%':
                        str_addch(buf, '%');
                        break;
                  case 's':
                        if (clib_flag) {/* Clib */
                              clib_flag = 0;
                              str_cat(buf, strerror(errno));
                        } else
                              str_cat(buf, va_arg(ap, char *));
                        break;
                  case 'd':
                        sprintf(lbuf, "%d", va_arg(ap, int));
                        str_cat(buf, lbuf);
                        break;
                  case 'c':
                        str_addch(buf, va_arg(ap, int));
                        break;
                  default:
                        fatal("unknown log() specifier %%%c", m[1]);
                  };
                  m++; m++;
            } else {
                  str_addch(buf, m[0]);
                  m++;
            }
      }
#ifdef HAVE_SYSLOG
      if (use_syslog) {
            fprintf(stderr, "level = %d: %s\n", lev, str(buf));
            syslog(lev, "%s", str(buf));
      } else
#endif
      if (logfp) {
            fprintf(logfp, "%s %s: %s\n", PROGRAM,
                  (lev == log_info ? "info"
                  :lev == log_warning ? "warning"
                  :lev == log_debug ? "debug"
                  :"fatal"),
                  str(buf));
            fflush(logfp);
      }
      mem_free(str(buf));
}
void inline status(const char *s, ...)
{
      va_list ap;

      if (!logfp) return;
      va_start(ap, s);
      vfprintf(logfp, s, ap);
      fputc('\n', logfp);
      fflush(logfp);
      va_end(ap);
}
void inline log(int lev, const char *m, ...)
{
      va_list ap;
      va_start(ap, m);
      _log_helper(lev, 0, m, ap);
      va_end(ap);
}
#define MAKE_LOGGING_FUNCTION(A,B) \
void inline A(const char *m, ...) \
{ \
      va_list ap; \
      va_start(ap, m); \
      _log_helper(log_ ## A, 0, m, ap); \
      va_end(ap); B; \
} \
void inline c ## A(const char *m, ...) \
{ \
      va_list ap; \
      va_start(ap, m); \
      _log_helper(log_ ## A, 1, m, ap); \
      va_end(ap); B; \
}
MAKE_LOGGING_FUNCTION(fatal,exit(1))
MAKE_LOGGING_FUNCTION(warning,return)
MAKE_LOGGING_FUNCTION(debug,return)
#undef MAKE_LOGGING_FUNCTION

Generated by  Doxygen 1.6.0   Back to index