Changeset 1200


Ignore:
Timestamp:
Feb 7, 2004, 3:58:28 AM (22 years ago)
Author:
bird
Message:

Reprogrammed the port to being based on FreeBSD 5.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/libsyslog/syslog.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1199 r1200  
    3333
    3434#if defined(LIBC_SCCS) && !defined(lint)
    35 static char sccsid[] = "@(#)syslog.c    8.8 (Berkeley) 8/30/95";
     35static char sccsid[] = "@(#)syslog.c    8.5 (Berkeley) 4/29/95";
    3636#endif /* LIBC_SCCS and not lint */
    37 
    38 #include <sys/param.h>
     37#include <sys/cdefs.h>
     38__FBSDID("$FreeBSD: src/lib/libc/gen/syslog.c,v 1.29 2003/02/10 08:31:28 alfred Exp $");
     39
     40#include "namespace.h"
    3941#include <sys/types.h>
    4042#include <sys/socket.h>
     43#include <sys/syslog.h>
    4144#include <sys/uio.h>
    42 #include <sys/syslog.h>
     45#include <sys/un.h>
    4346#include <netdb.h>
    4447#ifdef __EMX__
    45 #include <netinet/in.h>
     48# include <netinet/in.h>
    4649#endif
    4750
    4851#include <errno.h>
    4952#include <fcntl.h>
     53#ifndef __EMX__
     54# include <paths.h>
     55#else
     56# define _PATH_CONSOLE "/dev/con"
     57#endif
    5058#include <stdio.h>
     59#include <stdlib.h>
    5160#include <string.h>
    5261#include <time.h>
    5362#include <unistd.h>
    5463
    55 #if defined(BSD4_4) && !defined(__EMX__)
    56 # include <paths.h>
    57 #else
    58 # if defined(__EMX__)
    59 #  define _PATH_CONSOLE "con"
    60 # endif
    61 
    62 # ifndef _PATH_CONSOLE
    63 #  define _PATH_CONSOLE "/dev/console"
    64 # endif
    65 # ifndef _PATH_LOG
    66 #  define _PATH_LOG     "/dev/log"
    67 # endif
    68 #endif
    69 
    70 #if __STDC__
    71 # include <stdarg.h>
    72 #else
    73 # include <varargs.h>
    74 # define const  /* */
    75 #endif
    76 
    77 #ifndef USESNPRINTF
    78 # if defined(BSD4_4) || defined(__EMX__)
    79 #  define USESNPRINTF   1       /* has snprintf(3), vsnprintf(3), etc. */
    80 # else
    81 #  define USESNPRINTF   0       /* cheesy old C library */
    82 # endif
    83 #endif
    84 
    85 #ifndef LOG_PRI
    86 # define LOG_PRI(p)     ((p) & LOG_PRIMASK)
    87 #endif
    88 
    89 #ifndef LOG_PERROR
    90 # define LOG_PERROR     0
    91 #endif
    92 
    93 #define BUFSLOP         1024    /* overflow space */
     64#include <stdarg.h>
     65#include "un-namespace.h"
     66
     67#include "libc_private.h"
    9468
    9569static int      LogFile = -1;           /* fd for log */
    9670static int      connected;              /* have done connect */
     71static int      opened;                 /* have done openlog() */
    9772static int      LogStat = 0;            /* status bits, set by openlog() */
    9873static const char *LogTag = NULL;       /* string to tag the entry with */
    9974static int      LogFacility = LOG_USER; /* default facility code */
    10075static int      LogMask = 0xff;         /* mask of priorities to be logged */
    101 #if defined(BSD4_4) && !defined(__EMX__)
    102 extern char     *__progname;            /* Program name, from crt0. */
    103 #else
    104 char            *__progname = NULL;
     76
     77static void     disconnectlog(void); /* disconnect from syslogd */
     78static void     connectlog(void);       /* (re)connect to syslogd */
     79
     80#ifndef __EMX__
     81/*
     82 * Format of the magic cookie passed through the stdio hook
     83 */
     84struct bufcookie {
     85        char    *base;  /* start of buffer */
     86        int     left;
     87};
     88
     89/*
     90 * stdio write hook for writing to a static string buffer
     91 * XXX: Maybe one day, dynamically allocate it so that the line length
     92 *      is `unlimited'.
     93 */
     94static
     95int writehook(cookie, buf, len)
     96        void    *cookie;        /* really [struct bufcookie *] */
     97        char    *buf;           /* characters to copy */
     98        int     len;            /* length to copy */
     99{
     100        struct bufcookie *h;    /* private `handle' */
     101
     102        h = (struct bufcookie *)cookie;
     103        if (len > h->left) {
     104                /* clip in case of wraparound */
     105                len = h->left;
     106        }
     107        if (len > 0) {
     108                (void)memcpy(h->base, buf, len); /* `write' it. */
     109                h->base += len;
     110                h->left -= len;
     111        }
     112        return 0;
     113}
    105114#endif
    106115
     
    110119 */
    111120void
    112 #if __STDC__
    113121syslog(int pri, const char *fmt, ...)
    114 #else
    115 syslog(pri, fmt, va_alist)
    116         int pri;
    117         char *fmt;
    118         va_dcl
    119 #endif
    120122{
    121123        va_list ap;
    122         extern void vsyslog();
    123 
    124 #if __STDC__
    125         va_start(ap, fmt);
    126 #else
    127         va_start(ap);
    128 #endif
    129         vsyslog(pri, fmt, ap);
    130         va_end(ap);
     124
     125        va_start(ap, fmt);
     126        vsyslog(pri, fmt, ap);
     127        va_end(ap);
    131128}
    132129
    133130void
    134131vsyslog(pri, fmt, ap)
    135         int pri;
    136         register const char *fmt;
    137         va_list ap;
    138 {
    139         register int cnt;
    140         register char ch, *p, *t;
     132        int pri;
     133        const char *fmt;
     134        va_list ap;
     135{
     136        int cnt;
     137        char ch, *p;
    141138        time_t now;
    142139        int fd, saved_errno;
    143         int panic = 0;
    144         static int maxsend = BUFSIZ;
    145         char *stdp, fmt_cpy[1024], tbuf[BUFSIZ + BUFSLOP];
    146         extern void openlog();
     140        char *stdp, tbuf[2048], fmt_cpy[1024], timbuf[26];
     141#ifndef __EMX__
     142        FILE *fp, *fmt_fp;
     143        struct bufcookie tbuf_cookie;
     144        struct bufcookie fmt_cookie;
     145#endif
    147146
    148147#define INTERNALLOG     LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
     
    164163                pri |= LogFacility;
    165164
    166         /* Get connected. */
    167         if (!connected)
    168                 openlog(LogTag, LogStat | LOG_NDELAY, 0);
     165#ifndef __EMX__
     166        /* Create the primary stdio hook */
     167        tbuf_cookie.base = tbuf;
     168        tbuf_cookie.left = sizeof(tbuf);
     169        fp = fwopen(&tbuf_cookie, writehook);
     170        if (fp == NULL)
     171                return;
     172#endif
    169173
    170174        /* Build the message. */
    171175        (void)time(&now);
    172         sprintf(tbuf, "<%d>", pri);
    173         p = tbuf + strlen(tbuf);
    174         strftime(p, sizeof (tbuf) - (p - tbuf), "%h %d %T ", localtime(&now));
    175         p += strlen(p);
    176         stdp = p;
     176#ifndef __EMX__
     177        (void)fprintf(fp, "<%d>", pri);
     178        (void)fprintf(fp, "%.15s ", ctime_r(&now, timbuf) + 4);
     179#else
     180        p = tbuf + sprintf(tbuf, "<%d>", pri);
     181        p += sprintf(p, "%.15s ", ctime_r(&now, timbuf) + 4);
     182#endif
     183        if (LogStat & LOG_PERROR) {
     184#ifndef __EMX__
     185                /* Transfer to string buffer */
     186                (void)fflush(fp);
     187                stdp = tbuf + (sizeof(tbuf) - tbuf_cookie.left);
     188#else
     189                stdp = p;
     190#endif
     191        }
    177192        if (LogTag == NULL)
    178                 LogTag = __progname;
     193                LogTag = _getprogname();
     194        if (LogTag != NULL)
     195#ifndef __EMX__
     196            (void)fprintf(fp, "%s", LogTag);
     197#else
     198            p += sprintf(p, "%s", LogTag);
     199#endif
     200        if (LogStat & LOG_PID)
     201#ifndef __EMX__
     202            (void)fprintf(fp, "[%d]", getpid());
     203#else
     204            p += sprintf(p, "[%d]", getpid());
     205#endif
    179206        if (LogTag != NULL) {
    180                 sprintf(p, "%s", LogTag);
    181                 p += strlen(p);
    182         }
    183         if (LogStat & LOG_PID) {
    184                 sprintf(p, "[%d]", getpid());
    185                 p += strlen(p);
    186         }
    187         if (LogTag != NULL) {
     207#ifndef __EMX__
     208            (void)fprintf(fp, ": ");
     209#else
    188210                *p++ = ':';
    189211                *p++ = ' ';
     212#endif
    190213        }
    191214
    192         /* Substitute error message for %m. */
    193         for (t = fmt_cpy; ch = *fmt; ++fmt)
    194                 if (ch == '%' && fmt[1] == 'm') {
    195                         ++fmt;
    196                         sprintf(t, "%s", strerror(saved_errno));
    197                         t += strlen(t);
    198                 } else
    199                         *t++ = ch;
    200         *t = '\0';
    201 
    202 #if USESNPRINTF
    203         cnt = maxsend - (p - tbuf) + 1;
    204         p += vsnprintf(p, cnt, fmt_cpy, ap);
     215        /* Check to see if we can skip expanding the %m */
     216        if (strstr(fmt, "%m")) {
     217#ifndef __EMX__
     218                /* Create the second stdio hook */
     219                fmt_cookie.base = fmt_cpy;
     220                fmt_cookie.left = sizeof(fmt_cpy) - 1;
     221                fmt_fp = fwopen(&fmt_cookie, writehook);
     222                if (fmt_fp == NULL) {
     223                        fclose(fp);
     224                        return;
     225                }
     226#else
     227            char *t = fmt_cpy;
     228#endif
     229
     230            /*
     231             * Substitute error message for %m.  Be careful not to
     232             * molest an escaped percent "%%m".  We want to pass it
     233             * on untouched as the format is later parsed by vfprintf.
     234             */
     235            for ( ; (ch = *fmt); ++fmt) {
     236                    if (ch == '%' && fmt[1] == 'm') {
     237                            ++fmt;
     238#ifndef __EMX__
     239                            fputs(strerror(saved_errno), fmt_fp);
     240#else
     241                            t += sprintf(t, "%s", strerror(saved_errno));
     242#endif
     243                    } else if (ch == '%' && fmt[1] == '%') {
     244                            ++fmt;
     245#ifndef __EMX__
     246                            fputc(ch, fmt_fp);
     247                            fputc(ch, fmt_fp);
     248#else
     249                            *t++ = ch;
     250                            *t++ = ch;
     251#endif
     252                    } else {
     253#ifndef __EMX__
     254                        fputc(ch, fmt_fp);
     255#else
     256                            *t++ = ch;
     257#endif
     258                    }
     259            }
     260
     261            /* Null terminate if room */
     262#ifndef __EMX__
     263            /* Null terminate if room */
     264            fputc(0, fmt_fp);
     265            fclose(fmt_fp);
     266#else
     267            *t = '\0';
     268#endif
     269            /* Guarantee null termination */
     270            fmt_cpy[sizeof(fmt_cpy) - 1] = '\0';
     271
     272            fmt = fmt_cpy;
     273        }
     274
     275#ifndef __EMX__
     276        (void)vfprintf(fp, fmt, ap);
     277        (void)fclose(fp);
     278
     279        cnt = sizeof(tbuf) - tbuf_cookie.left;
     280#else
    205281        cnt = p - tbuf;
    206 #else
    207         vsprintf(p, fmt_cpy, ap);
    208         p += strlen(p);
    209         cnt = p - tbuf;
    210         if (cnt > sizeof tbuf) {
    211                 /* Panic condition. */
    212                 panic = 1;
    213         }
    214         if (cnt > maxsend)
    215                 cnt = maxsend;
     282        cnt += vsnprintf(p, sizeof(tbuf) - cnt - 1, fmt, ap);
    216283#endif
    217284
     
    219286        if (LogStat & LOG_PERROR) {
    220287                struct iovec iov[2];
    221                 register struct iovec *v = iov;
     288                struct iovec *v = iov;
    222289
    223290                v->iov_base = stdp;
     
    226293                v->iov_base = "\n";
    227294                v->iov_len = 1;
    228                 (void)writev(STDERR_FILENO, iov, 2);
     295                (void)_writev(STDERR_FILENO, iov, 2);
    229296        }
    230297
    231         /* Output the message to the local logger. */
    232         for (;;) {
    233                 if (send(LogFile, tbuf, cnt, 0) >= 0)
    234                         goto done;
    235                 if (errno != EMSGSIZE || maxsend <= 256)
    236                         break;
    237 
    238                 /* Message was too large -- back it off. */
    239                 do {
    240                         maxsend -= 128;
    241                 } while (cnt < maxsend && maxsend > 256);
    242                 cnt = maxsend;
    243         }
     298        /* Get connected, output the message to the local logger. */
     299        if (!opened)
     300                openlog(LogTag, LogStat | LOG_NDELAY, 0);
     301        connectlog();
     302        if (send(LogFile, tbuf, cnt, 0) >= 0)
     303                return;
     304
     305        /*
     306         * If the send() failed, the odds are syslogd was restarted.
     307         * Make one (only) attempt to reconnect to /dev/log.
     308         */
     309        disconnectlog();
     310        connectlog();
     311        if (send(LogFile, tbuf, cnt, 0) >= 0)
     312                return;
    244313
    245314        /*
    246          * Output the message to the console; don't worry about blocking,
    247          * if console blocks everything will.  Make sure the error reported
    248          * is the one from the syslogd failure.
     315         * Output the message to the console; try not to block
     316         * as a blocking console should not stop other processes.
     317         * Make sure the error reported is the one from the syslogd failure.
    249318         */
    250319        if (LogStat & LOG_CONS &&
    251             (fd = open(_PATH_CONSOLE, O_WRONLY, 0)) >= 0) {
    252                 (void)strcat(tbuf, "\r\n");
    253                 cnt += 2;
     320#ifndef __EMX__
     321            (fd = _open(_PATH_CONSOLE, O_WRONLY|O_NONBLOCK, 0)) >= 0) {
     322#else
     323            (fd = _open(_PATH_CONSOLE, O_WRONLY/*|O_NONBLOCK*/, 0)) >= 0) {
     324#endif
     325
     326                struct iovec iov[2];
     327                struct iovec *v = iov;
     328
    254329                p = strchr(tbuf, '>') + 1;
    255                 (void)write(fd, p, cnt - (p - tbuf));
    256                 (void)close(fd);
     330                v->iov_base = p;
     331                v->iov_len = cnt - (p - tbuf);
     332                ++v;
     333                v->iov_base = "\r\n";
     334                v->iov_len = 2;
     335                (void)_writev(fd, iov, 2);
     336                (void)_close(fd);
    257337        }
    258 
    259   done:
    260 #if !USESNPRINTF
    261         /*
    262          * If we had a buffer overrun, log a panic and abort.
    263          * We can't return because our stack is probably toast.
    264          */
    265         if (panic) {
    266                 syslog(LOG_EMERG, "SYSLOG BUFFER OVERRUN -- EXITING");
    267                 abort();
    268         }
    269 #endif
    270 }
    271 
    272 #ifdef __EMX__
    273 static struct sockaddr_in SyslogAddr;   /* AF_INET address of local logger */
    274 #else
    275 static struct sockaddr SyslogAddr;      /* AF_UNIX address of local logger */
    276 #endif
     338}
     339static void
     340disconnectlog()
     341{
     342        /*
     343         * If the user closed the FD and opened another in the same slot,
     344         * that's their problem.  They should close it before calling on
     345         * system services.
     346         */
     347        if (LogFile != -1) {
     348                _close(LogFile);
     349                LogFile = -1;
     350        }
     351        connected = 0;                  /* retry connect */
     352}
     353
     354static void
     355connectlog()
     356{
     357#ifndef __EMX__
     358        struct sockaddr_un SyslogAddr;  /* AF_UNIX address of local logger */
     359#else
     360        struct sockaddr_in SyslogAddr;  /* AF_INET address of local logger */
     361#endif
     362
     363        if (LogFile == -1) {
     364#ifndef __EMX__
     365                if ((LogFile = _socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
     366#else
     367                if ((LogFile = _socket(AF_INET, SOCK_DGRAM, 0)) == -1)
     368#endif
     369                        return;
     370                (void)_fcntl(LogFile, F_SETFD, 1);
     371        }
     372        if (LogFile != -1 && !connected) {
     373#ifndef __EMX__
     374                SyslogAddr.sun_len = sizeof(SyslogAddr);
     375                SyslogAddr.sun_family = AF_UNIX;
     376                (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
     377                    sizeof SyslogAddr.sun_path);
     378#else
     379                memset(&SyslogAddr, 0, sizeof(SyslogAddr));
     380#ifndef TCPV40HDRS
     381                SyslogAddr.sin_len = sizeof(SyslogAddr);
     382#endif
     383                SyslogAddr.sin_family = AF_INET;
     384                SyslogAddr.sin_port = htons(514);
     385                SyslogAddr.sin_addr.s_addr = INADDR_ANY;
     386#endif
     387                connected = _connect(LogFile, (struct sockaddr *)&SyslogAddr,
     388                        sizeof(SyslogAddr)) != -1;
     389
     390#ifndef __EMX__
     391                if (!connected) {
     392                        /*
     393                         * Try the old "/dev/log" path, for backward
     394                         * compatibility.
     395                         */
     396                        (void)strncpy(SyslogAddr.sun_path, _PATH_OLDLOG,
     397                            sizeof SyslogAddr.sun_path);
     398                        connected = _connect(LogFile,
     399                                (struct sockaddr *)&SyslogAddr,
     400                                sizeof(SyslogAddr)) != -1;
     401                }
     402#endif
     403
     404                if (!connected) {
     405                        (void)_close(LogFile);
     406                        LogFile = -1;
     407                }
     408        }
     409}
    277410
    278411void
     
    281414        int logstat, logfac;
    282415{
    283         if (ident != NULL)
    284                 LogTag = ident;
    285         LogStat = logstat;
    286         if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
    287                 LogFacility = logfac;
    288 
    289         if (LogFile == -1) {
    290 #ifdef __EMX__
    291                 memset(&SyslogAddr, 0, sizeof(SyslogAddr));
    292                 SyslogAddr.sin_len = sizeof(SyslogAddr);
    293                 SyslogAddr.sin_family = AF_INET;
    294                 SyslogAddr.sin_port = htons(514);
    295                 SyslogAddr.sin_addr.s_addr = INADDR_ANY;
    296 #else
    297                 SyslogAddr.sa_family = AF_UNIX;
    298                 (void)strncpy(SyslogAddr.sa_data, _PATH_LOG,
    299                     sizeof(SyslogAddr.sa_data));
    300 #endif
    301                 if (LogStat & LOG_NDELAY) {
    302 #ifdef __EMX__
    303                         if ((LogFile = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    304 #else
    305                         if ((LogFile = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
    306 #endif
    307                                 return;
    308 #ifndef __EMX__
    309                         (void)fcntl(LogFile, F_SETFD, 1);
    310 #endif
    311                 }
    312         }
    313         if (LogFile != -1 && !connected)
    314                 if (connect(LogFile, (struct sockaddr*) &SyslogAddr, sizeof(SyslogAddr)) == -1) {
    315                         (void)close(LogFile);
    316                         LogFile = -1;
    317                 } else
    318                         connected = 1;
     416    if (ident != NULL)
     417            LogTag = ident;
     418    LogStat = logstat;
     419    if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
     420            LogFacility = logfac;
     421
     422    if (LogStat & LOG_NDELAY)   /* open immediately */
     423            connectlog();
     424
     425    opened = 1; /* ident and facility has been set */
    319426}
    320427
     
    322429closelog()
    323430{
    324         (void)close(LogFile);
     431        (void)_close(LogFile);
    325432        LogFile = -1;
     433        LogTag = NULL;
    326434        connected = 0;
    327435}
     
    339447        return (omask);
    340448}
    341 
Note: See TracChangeset for help on using the changeset viewer.