From f15aa3a552022743398a652165d76bf912c715e5 Mon Sep 17 00:00:00 2001 From: Guillaume Cottenceau Date: Mon, 14 May 2001 13:47:49 +0000 Subject: Initial revision --- mdk-stage1/dietlibc/libugly/logging.c | 211 ++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 mdk-stage1/dietlibc/libugly/logging.c (limited to 'mdk-stage1/dietlibc/libugly/logging.c') diff --git a/mdk-stage1/dietlibc/libugly/logging.c b/mdk-stage1/dietlibc/libugly/logging.c new file mode 100644 index 000000000..69c2c2337 --- /dev/null +++ b/mdk-stage1/dietlibc/libugly/logging.c @@ -0,0 +1,211 @@ +#include "dietfeatures.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _PATH_CONSOLE "/dev/console" +#define BUF_SIZE 512 /* messagebuffer size (>= 200) */ + +#define MAX_LOGTAG 80 + +/* those have to be global *sigh* */ +static volatile int connected = 0; /* have done connect */ +static volatile int LogMask = 0xff; /* mask of priorities to be logged */ +static char LogTag[MAX_LOGTAG]; /* string to tag the entry with */ +static int LogFile = -1; /* fd for log */ +static int LogType = SOCK_DGRAM; /* type of socket connection */ +static int LogFacility = LOG_USER; /* default facility code */ +static int LogStat; /* status bits, set by openlog() */ +extern char *__progname; /* Program name, from crt0. */ +static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ + +static void closelog_intern(void) +{ + if (!connected) return; + close(LogFile); + LogFile = -1; + connected = 0; +} + +void closelog(void) +{ + closelog_intern(); + + LogTag[0]=0; + LogType = SOCK_DGRAM; +} + +static void openlog_intern(int option, int facility) +{ + LogStat = option; + if (facility && ((facility & ~LOG_FACMASK) == 0)) + LogFacility = facility; + + /* yep, there is a continue inside ;) */ + while(1) { + if (LogFile == -1) { + SyslogAddr.sa_family = AF_UNIX; + strncpy(SyslogAddr.sa_data, _PATH_LOG, sizeof(SyslogAddr.sa_data)); + if (LogStat & LOG_NDELAY) + { + if ((LogFile = socket(AF_UNIX, LogType, 0)) == -1) return; + fcntl(LogFile, F_SETFD, 1); + } + } + if ((LogFile != -1) && !connected) { +#ifdef WANT_THREAD_SAFE + int old_errno = (*(__errno_location())); +#else + int old_errno=errno; +#endif + if(connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) == -1) { +#ifdef WANT_THREAD_SAFE + int saved_errno = (*(__errno_location())); +#else + int saved_errno=errno; +#endif + close(LogFile); + LogFile = -1; + if((LogType == SOCK_DGRAM) && (saved_errno == EPROTOTYPE)) { + /* retry with SOCK_STREAM instead of SOCK_DGRAM */ + LogType = SOCK_STREAM; +#ifdef WANT_THREAD_SAFE + (*(__errno_location()))=old_errno; +#else + errno=old_errno; +#endif + continue; + } + } + else connected = 1; + } + break; + } +} + +/* has to be secured against multiple, simultanious call's in threaded environment */ +void openlog(const char *ident, int option, int facility) +{ + if (ident) { + strncpy(LogTag,ident,MAX_LOGTAG); + LogTag[MAX_LOGTAG-1]=0; + } + openlog_intern(option, facility); +} + +int setlogmask(int mask) +{ + int old = LogMask; + if (mask) LogMask = mask; + return old; +} + +void vsyslog(int priority, const char *format, va_list arg_ptr) +{ + char buffer[BUF_SIZE]; + char time_buf[20]; + int buflen, headerlen; + time_t now; + struct tm now_tm; + pid_t pid; + int fd; + int sigpipe; + struct sigaction action, oldaction; + struct sigaction *oldaction_ptr = NULL; +#ifdef WANT_THREAD_SAFE + int saved_errno = (*(__errno_location())); +#else + int saved_errno = errno; +#endif + + /* check for invalid priority/facility bits */ + if (priority & ~(LOG_PRIMASK|LOG_FACMASK)) { + syslog(LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID, "syslog: unknown facility/priorityority: %x", priority); + priority &= LOG_PRIMASK|LOG_FACMASK; + } + + /* check priority against setlogmask */ + if ((LOG_MASK(LOG_PRI(priority)) && LogMask) == 0) return; + + /* Set default facility if none specified. */ + if ((priority & LOG_FACMASK) == 0) priority |= LogFacility; + + pid = getpid(); + time(&now); + strftime(time_buf, 20, "%h %e %T", localtime_r (&now, &now_tm)); + + if (LogStat & LOG_PID) + headerlen = snprintf(buffer, 130, "<%d>%s %s[%d]: ", priority, time_buf, LogTag, pid); + else + headerlen = snprintf(buffer, 130, "<%d>%s %s: ", priority, time_buf, LogTag); + + if (!LogTag[0]) { + if ((LogStat & LOG_PID) != LOG_PID) + headerlen = snprintf(buffer, 130, "<%d>%s (unknown)[%d]: ", priority, time_buf, pid); + strcat(buffer+headerlen, "syslog without openlog w/ ident, please check code!"); + buflen = 41; + } + else { +#ifdef WANT_THREAD_SAFE + (*(__errno_location()))=saved_errno; +#else + errno=saved_errno; +#endif + buflen = vsnprintf(buffer+headerlen, BUF_SIZE - headerlen, format, arg_ptr); + } + if (LogStat & LOG_PERROR) { + write(1, buffer+headerlen, buflen); + if (buffer[headerlen+buflen] != '\n') write(1,"\n", 1); + } + + /* prepare for broken connection */ + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigemptyset(&action.sa_mask); + + if ((sigpipe = sigaction (SIGPIPE, &action, &oldaction))==0) + oldaction_ptr = &oldaction; + + if (!connected) openlog_intern(LogStat | LOG_NDELAY, 0); + + /* If we have a SOCK_STREAM connection, also send ASCII NUL as a + * record terminator. */ + if (LogType == SOCK_STREAM) buflen++; + + if (!connected || (send(LogFile, buffer, buflen+headerlen, 0) != buflen+headerlen)) { + if (LogType == SOCK_STREAM) buflen--; + closelog_intern(); + /* + * Output the message to the console; don't worry about blocking, + * if console blocks everything will. Make sure the error reported + * is the one from the syslogd failure. + */ + if ((LogStat & LOG_CONS) && + ((fd = open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0)) + { + write(fd, buffer, buflen+headerlen); + write(fd, "\r\n", 2); + } + } + + if (sigpipe == 0) + sigaction(SIGPIPE, &oldaction, (struct sigaction *) NULL); +} + +void syslog(int priority, const char *format, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, format); + vsyslog(priority, format, arg_ptr); + va_end(arg_ptr); +} -- cgit v1.2.1