/* * Copyright (c) 2003-2005 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. */ #include "sm/generic.h" SM_RCSID("@(#)$Id: errlog.c,v 1.9 2006/10/05 04:27:37 ca Exp $") #include #include "sm/io.h" #include #include "sm/string.h" #include #include #include "sm/log.h" #include "sm/errlog.h" #if MTA_USE_STATETHREADS #include "statethreads/st.h" #endif /* MTA_USE_STATETHREADS */ #define snprintf sm_snprintf #define vsnprintf sm_vsnprintf /* ** Simple error reporting functions. ** Suggested in W. Richard Stevens' "Advanced Programming in UNIX ** Environment". */ #define SM_LOG_MAXLINE (8 * 1024) /* max line length */ #if 0 ///* // * Return a pointer to a string containing current time. // * Warning: uses (local) static variable for result! // */ // //static char * //errlog_tstamp(void) //{ // static char str[32]; // static time_t lastt = 0; //#if MTA_USE_PTHREADS // struct tm tm; //#endif /* MTA_USE_PTHREADS */ // struct tm *tmp; // time_t currt; // // /* XXX statethreads specific... generic solution? */ //#if MTA_USE_STATETHREADS // currt = st_time(); //#else /* MTA_USE_STATETHREADS */ // OOPS... //#endif /* MTA_USE_STATETHREADS */ // if (currt == lastt) // return str; // /* XXX protect access? */ //#if MTA_USE_PTHREADS // tmp = localtime_r(&currt, &tm); //#else /* MTA_USE_PTHREADS */ // tmp = localtime(&currt); //#endif /* MTA_USE_PTHREADS */ // snprintf(str, sizeof(str), "[%d-%02d-%02d/%02d:%02d:%02d] ", // 1900 + tmp->tm_year, /* HACK */ // tmp->tm_mon + 1, // tmp->tm_mday, // tmp->tm_hour, tmp->tm_min, tmp->tm_sec); // lastt = currt; // return str; //} #endif /* 0 */ /* ** Print a message and return to caller. ** Caller specifies "errnoflag". */ static void errlog_doit(sm_log_ctx_P lctx, bool errnoflag, const char *fmt, va_list ap) { int errno_save; #if 0 int n; char buf[SM_LOG_MAXLINE]; #endif /* 0 */ errno_save = errno; /* value caller might want printed */ #if 0 // /* prepend a message with time stamp */ // strlcpy(buf, errlog_tstamp(), sizeof(buf)); // n = strlen(buf); // vsnprintf(buf + n, sizeof(buf) - n, fmt, ap); // n = strlen(buf); // // /* XXX ignored for now... */ // if (errnoflag) // snprintf(buf + n, sizeof(buf) - n, ": %s", // strerror(errno_save)); #endif /* 0 */ #define LCAT NULL #define LMOD NULL sm_log_vwrite(lctx, LCAT, /* XXX */ LMOD, /* XXX */ SM_LOG_ERR, /* XXX */ 0, /* XXX */ fmt, ap); errno = errno_save; } /* ** Nonfatal error related to a system call. ** Print a message and return. */ void errlog_sys_report(sm_log_ctx_P lctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); errlog_doit(lctx, true, fmt, ap); va_end(ap); } /* ** Fatal error related to a system call. ** Print a message and terminate. */ void errlog_sys_quit(sm_log_ctx_P lctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); errlog_doit(lctx, true, fmt, ap); va_end(ap); exit(1); } /* ** Fatal error related to a system call. ** Print a message, dump core, and terminate. */ void errlog_sys_dump(sm_log_ctx_P lctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); errlog_doit(lctx, true, fmt, ap); va_end(ap); abort(); /* dump core and terminate */ /* NOTREACHED */ exit(1); /* shouldn't get here */ } /* ** Nonfatal error unrelated to a system call. ** Print a message and return. */ void errlog_report(sm_log_ctx_P lctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); errlog_doit(lctx, false, fmt, ap); va_end(ap); } /* ** Fatal error unrelated to a system call. ** Print a message and terminate. */ void errlog_quit(sm_log_ctx_P lctx, const char *fmt, ...) { va_list ap; va_start(ap, fmt); errlog_doit(lctx, false, fmt, ap); va_end(ap); exit(1); }