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

error_msg.c

/* Distributed Checksum Clearinghouse
 *
 * Copyright (c) 2005 by Rhyolite Software
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE
 * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 *
 * Rhyolite Software DCC 1.2.74-1.28 $Revision$
 */

#include "dcc_defs.h"
#include "dcc_paths.h"
#ifndef DCC_WIN32
#include <syslog.h>
#endif

extern void dcc_syslog_lock(void);
extern void dcc_syslog_unlock(void);

u_char dcc_no_syslog;

int dcc_error_priority = LOG_ERR | LOG_MAIL;
int dcc_trace_priority = LOG_NOTICE | LOG_MAIL;


/* commonly used, but not thread safe */
int dcc_ex_code = EX_UNAVAILABLE;


DCC_PATH dcc_progname;

#ifdef HAVE___PROGNAME
extern const char *__progname;
#endif

void
dcc_syslog_init(u_char use_syslog,
            const char *argv0 UATTRIB, const char *suffix)
{
      const char *p;
#ifndef DCC_WIN32
      struct stat sb;
      int fd;
#endif

      /* Solaris defaults to "syslog" with a null identification string,
       * but does not seem to have __progname set by crt0. */
#undef GOT_PROGNAME
#ifdef HAVE_GETPROGNAME
      p = getprogname();
#     define GOT_PROGNAME
#endif
#if defined(HAVE___PROGNAME) && !defined(GOT_PROGNAME)
      p = __progname;
#     define GOT_PROGNAME
#endif
#ifndef GOT_PROGNAME
      p = strrchr(argv0, '/');
      if (!p)
            p = argv0;
      else
            ++p;
#endif
      snprintf(dcc_progname, sizeof(dcc_progname), "%s%s",
             p, suffix ? suffix : "");

#ifdef DCC_WIN32
      dcc_no_syslog = 1;
#else
      /* Don't wait for the console if somehow we must use it,
       * because that messes up dccm. */
#ifndef LOG_NOWAIT
#define LOG_NOWAIT 0
#endif
      openlog(dcc_progname, LOG_PID | LOG_NOWAIT, LOG_MAIL);
      dcc_no_syslog = !use_syslog;

      /* ensure that stdout and stderr exist so that when we open
       * database or other files, we don't get file descriptor 1 or 2
       * and then later write error messages to them. */
      if (0 > fstat(STDOUT_FILENO, &sb) && errno == EBADF) {
            fd = open(_PATH_DEVNULL, 0, O_RDWR);
            if (fd < 0)
                  return;
            if (fd != STDOUT_FILENO) {
                  dup2(fd, STDOUT_FILENO);
                  close(fd);
            }
      }
      if (0 > fstat(STDERR_FILENO, &sb) && errno == EBADF) {
            fd = open(_PATH_DEVNULL, 0, O_RDWR);
            if (fd < 0)
                  return;
            if (fd != STDERR_FILENO) {
                  dup2(fd, STDERR_FILENO);
                  close(fd);
            }
      }
#endif /* DCC_WIN32 */
}



void
dcc_vfatal_msg(const char *p, va_list args)
{
      char sbuf[200];
      int i;
      COPY_DCC_ARGS2();

      fflush(stdout);               /* keep stderr and stdout straight */
      vfprintf(stderr, p, DCC_ARGS2);
      fputs("; fatal error\n", stderr);
      fflush(stderr);
      END_DCC_ARGS2();

      if (dcc_no_syslog)
            return;

      dcc_syslog_lock();
      /* try to write the message with the "fatal error" addition as
       * a single message */
      i = vsnprintf(sbuf, sizeof(sbuf), p, args);
      if (i < ISZ(sbuf)-ISZ("fatal error")) {
            syslog(dcc_error_priority, "%s; fatal error", sbuf);
      } else {
            vsyslog(dcc_error_priority, p, args);
            syslog(dcc_error_priority, "fatal error");
      }
      dcc_syslog_unlock();
}



void
dcc_verror_msg(const char *p, va_list args)
{
      COPY_DCC_ARGS2();

      fflush(stdout);               /* keep stderr and stdout straight */
      vfprintf(stderr, p, DCC_ARGS2);
      fputc('\n', stderr);
      END_DCC_ARGS2();

      if (dcc_no_syslog)
            return;
      dcc_syslog_lock();
      vsyslog(dcc_error_priority, p, args);
      dcc_syslog_unlock();
}



void PATTRIB(1,2)
dcc_error_msg(const char *p, ...)
{
      va_list args;

      va_start(args, p);
      dcc_verror_msg(p, args);
      va_end(args);
}



void
dcc_vtrace_msg(const char *p, va_list args)
{
      COPY_DCC_ARGS2();

      fflush(stdout);               /* keep stderr and stdout straight */
      vfprintf(stderr, p, DCC_ARGS2);
      fputc('\n', stderr);
      END_DCC_ARGS2();

      if (dcc_no_syslog)
            return;
      dcc_syslog_lock();
      vsyslog(dcc_trace_priority, p, args);
      dcc_syslog_unlock();
}



void PATTRIB(1,2)
dcc_trace_msg(const char *p, ...)
{
      va_list args;

      va_start(args, p);
      dcc_vtrace_msg(p, args);
      va_end(args);
}



void
dcc_vpemsg(int ex_code, DCC_EMSG emsg, const char *msg, va_list args)
{
      if (!emsg) {
            dcc_verror_msg(msg, args);
      } else {
            dcc_ex_code = ex_code;
            vsnprintf(emsg, sizeof(DCC_EMSG), msg, args);
      }
}



void PATTRIB(3,4)
dcc_pemsg(int ex_code, DCC_EMSG emsg, const char *msg, ...)
{
      va_list args;

      va_start(args, msg);
      dcc_vpemsg(ex_code, emsg, msg, args);
      va_end(args);
}

Generated by  Doxygen 1.6.0   Back to index