Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/sysklogd/syslogd.c

    r1765 r2725  
    1111 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
    1212 *
    13  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     13 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1414 */
    1515
     16/*
     17 * Done in syslogd_and_logger.c:
    1618#include "libbb.h"
    17 #include <paths.h>
     19#define SYSLOG_NAMES
     20#define SYSLOG_NAMES_CONST
     21#include <syslog.h>
     22*/
     23
    1824#include <sys/un.h>
    19 
    20 /* SYSLOG_NAMES defined to pull prioritynames[] and facilitynames[]
    21  * from syslog.h. Grrrr - glibc puts those in _rwdata_! :( */
    22 #define SYSLOG_NAMES
    23 #define SYSLOG_NAMES_CONST /* uclibc is saner :) */
    24 #include <sys/syslog.h>
    2525#include <sys/uio.h>
    2626
     
    4343#undef SYSLOGD_MARK
    4444
    45 enum { MAX_READ = 256 };
     45/* Write locking does not seem to be useful either */
     46#undef SYSLOGD_WRLOCK
     47
     48enum {
     49    MAX_READ = CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE,
     50    DNS_WAIT_SEC = 2 * 60,
     51};
    4652
    4753/* Semaphore operation structures */
     
    5157    char data[1];   /* data/messages */
    5258};
     59
     60#if ENABLE_FEATURE_REMOTE_LOG
     61typedef struct {
     62    int remoteFD;
     63    unsigned last_dns_resolve;
     64    len_and_sockaddr *remoteAddr;
     65    const char *remoteHostname;
     66} remoteHost_t;
     67#endif
    5368
    5469/* Allows us to have smaller initializer. Ugly. */
     
    6075    /* level of messages to be logged */    \
    6176    int logLevel;                           \
    62 USE_FEATURE_ROTATE_LOGFILE( \
     77IF_FEATURE_ROTATE_LOGFILE( \
    6378    /* max size of file before rotation */  \
    6479    unsigned logFileSize;                   \
     
    6883    smallint isRegular;                     \
    6984) \
    70 USE_FEATURE_REMOTE_LOG( \
    71     /* udp socket for remote logging */     \
    72     int remoteFD;                           \
    73     len_and_sockaddr* remoteAddr;           \
    74 ) \
    75 USE_FEATURE_IPC_SYSLOG( \
     85IF_FEATURE_IPC_SYSLOG( \
    7686    int shmid; /* ipc shared memory id */   \
    7787    int s_semid; /* ipc semaphore id */     \
     
    8797struct globals {
    8898    GLOBALS
     99
     100#if ENABLE_FEATURE_REMOTE_LOG
     101    llist_t *remoteHosts;
     102#endif
    89103#if ENABLE_FEATURE_IPC_SYSLOG
    90104    struct shbuf_ds *shbuf;
    91105#endif
    92106    time_t last_log_time;
    93     /* localhost's name */
    94     char localHostName[64];
     107    /* localhost's name. We print only first 64 chars */
     108    char *hostname;
    95109
    96110    /* We recv into recvbuf... */
    97     char recvbuf[MAX_READ];
     111    char recvbuf[MAX_READ * (1 + ENABLE_FEATURE_SYSLOGD_DUP)];
    98112    /* ...then copy to parsebuf, escaping control chars */
    99113    /* (can grow x2 max) */
     
    116130    .logFileRotate = 1,
    117131#endif
    118 #if ENABLE_FEATURE_REMOTE_LOG
    119     .remoteFD = -1,
    120 #endif
    121132#if ENABLE_FEATURE_IPC_SYSLOG
    122133    .shmid = -1,
     
    129140
    130141#define G (*ptr_to_globals)
     142#define INIT_G() do { \
     143    SET_PTR_TO_GLOBALS(memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data))); \
     144} while (0)
    131145
    132146
     
    138152    OPTBIT_loglevel, // -l
    139153    OPTBIT_small, // -S
    140     USE_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize   ,) // -s
    141     USE_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt  ,) // -b
    142     USE_FEATURE_REMOTE_LOG(    OPTBIT_remote     ,) // -R
    143     USE_FEATURE_REMOTE_LOG(    OPTBIT_localtoo   ,) // -L
    144     USE_FEATURE_IPC_SYSLOG(    OPTBIT_circularlog,) // -C
     154    IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize   ,)  // -s
     155    IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt  ,)  // -b
     156    IF_FEATURE_REMOTE_LOG(    OPTBIT_remotelog  ,)  // -R
     157    IF_FEATURE_REMOTE_LOG(    OPTBIT_locallog   ,)  // -L
     158    IF_FEATURE_IPC_SYSLOG(    OPTBIT_circularlog,)  // -C
     159    IF_FEATURE_SYSLOGD_DUP(   OPTBIT_dup        ,)  // -D
    145160
    146161    OPT_mark        = 1 << OPTBIT_mark    ,
     
    149164    OPT_loglevel    = 1 << OPTBIT_loglevel,
    150165    OPT_small       = 1 << OPTBIT_small   ,
    151     OPT_filesize    = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize   )) + 0,
    152     OPT_rotatecnt   = USE_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt  )) + 0,
    153     OPT_remotelog   = USE_FEATURE_REMOTE_LOG(    (1 << OPTBIT_remote     )) + 0,
    154     OPT_locallog    = USE_FEATURE_REMOTE_LOG(    (1 << OPTBIT_localtoo   )) + 0,
    155     OPT_circularlog = USE_FEATURE_IPC_SYSLOG(    (1 << OPTBIT_circularlog)) + 0,
     166    OPT_filesize    = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize   )) + 0,
     167    OPT_rotatecnt   = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt  )) + 0,
     168    OPT_remotelog   = IF_FEATURE_REMOTE_LOG(    (1 << OPTBIT_remotelog  )) + 0,
     169    OPT_locallog    = IF_FEATURE_REMOTE_LOG(    (1 << OPTBIT_locallog   )) + 0,
     170    OPT_circularlog = IF_FEATURE_IPC_SYSLOG(    (1 << OPTBIT_circularlog)) + 0,
     171    OPT_dup         = IF_FEATURE_SYSLOGD_DUP(   (1 << OPTBIT_dup        )) + 0,
    156172};
    157173#define OPTION_STR "m:nO:l:S" \
    158     USE_FEATURE_ROTATE_LOGFILE("s:" ) \
    159     USE_FEATURE_ROTATE_LOGFILE("b:" ) \
    160     USE_FEATURE_REMOTE_LOG(    "R:" ) \
    161     USE_FEATURE_REMOTE_LOG(    "L"  ) \
    162     USE_FEATURE_IPC_SYSLOG(    "C::")
     174    IF_FEATURE_ROTATE_LOGFILE("s:" ) \
     175    IF_FEATURE_ROTATE_LOGFILE("b:" ) \
     176    IF_FEATURE_REMOTE_LOG(    "R:" ) \
     177    IF_FEATURE_REMOTE_LOG(    "L"  ) \
     178    IF_FEATURE_IPC_SYSLOG(    "C::") \
     179    IF_FEATURE_SYSLOGD_DUP(   "D"  )
    163180#define OPTION_DECL *opt_m, *opt_l \
    164     USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \
    165     USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \
    166     USE_FEATURE_REMOTE_LOG(    ,*opt_R) \
    167     USE_FEATURE_IPC_SYSLOG(    ,*opt_C = NULL)
     181    IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \
     182    IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \
     183    IF_FEATURE_IPC_SYSLOG(    ,*opt_C = NULL)
    168184#define OPTION_PARAM &opt_m, &G.logFilePath, &opt_l \
    169     USE_FEATURE_ROTATE_LOGFILE(,&opt_s) \
    170     USE_FEATURE_ROTATE_LOGFILE(,&opt_b) \
    171     USE_FEATURE_REMOTE_LOG(    ,&opt_R) \
    172     USE_FEATURE_IPC_SYSLOG(    ,&opt_C)
     185    IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \
     186    IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \
     187    IF_FEATURE_REMOTE_LOG(    ,&remoteAddrList) \
     188    IF_FEATURE_IPC_SYSLOG(    ,&opt_C)
    173189
    174190
     
    181197#endif
    182198
    183 /* our shared key */
    184 #define KEY_ID ((long)0x414e4547) /* "GENA" */
     199/* our shared key (syslogd.c and logread.c must be in sync) */
     200enum { KEY_ID = 0x414e4547 }; /* "GENA" */
    185201
    186202static void ipcsyslog_cleanup(void)
     
    200216{
    201217    if (DEBUG)
    202         printf("shmget(%lx, %d,...)\n", KEY_ID, G.shm_size);
     218        printf("shmget(%x, %d,...)\n", (int)KEY_ID, G.shm_size);
    203219
    204220    G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644);
     
    208224
    209225    G.shbuf = shmat(G.shmid, NULL, 0);
    210     if (!G.shbuf) {
     226    if (G.shbuf == (void*) -1L) { /* shmat has bizarre error return */
    211227        bb_perror_msg_and_die("shmat");
    212228    }
     
    275291
    276292/* Print a message to the log file. */
    277 static void log_locally(char *msg)
    278 {
     293static void log_locally(time_t now, char *msg)
     294{
     295#ifdef SYSLOGD_WRLOCK
    279296    struct flock fl;
     297#endif
    280298    int len = strlen(msg);
    281299
     
    287305#endif
    288306    if (G.logFD >= 0) {
    289         time_t cur;
    290         time(&cur);
    291         if (G.last_log_time != cur) {
    292             G.last_log_time = cur; /* reopen log file every second */
     307        /* Reopen log file every second. This allows admin
     308         * to delete the file and not worry about restarting us.
     309         * This costs almost nothing since it happens
     310         * _at most_ once a second.
     311         */
     312        if (!now)
     313            now = time(NULL);
     314        if (G.last_log_time != now) {
     315            G.last_log_time = now;
    293316            close(G.logFD);
    294317            goto reopen;
     
    296319    } else {
    297320 reopen:
    298         G.logFD = device_open(G.logFilePath, O_WRONLY | O_CREAT
    299                     | O_NOCTTY | O_APPEND | O_NONBLOCK);
     321        G.logFD = open(G.logFilePath, O_WRONLY | O_CREAT
     322                    | O_NOCTTY | O_APPEND | O_NONBLOCK,
     323                    0666);
    300324        if (G.logFD < 0) {
    301325            /* cannot open logfile? - print to /dev/console then */
    302             int fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
     326            int fd = device_open(DEV_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
    303327            if (fd < 0)
    304328                fd = 2; /* then stderr, dammit */
     
    318342    }
    319343
     344#ifdef SYSLOGD_WRLOCK
    320345    fl.l_whence = SEEK_SET;
    321346    fl.l_start = 0;
     
    323348    fl.l_type = F_WRLCK;
    324349    fcntl(G.logFD, F_SETLKW, &fl);
     350#endif
    325351
    326352#if ENABLE_FEATURE_ROTATE_LOGFILE
     
    336362                if (i == 0) break;
    337363                sprintf(oldFile, "%s.%d", G.logFilePath, --i);
     364                /* ignore errors - file might be missing */
    338365                rename(oldFile, newFile);
    339366            }
    340367            /* newFile == "f.0" now */
    341368            rename(G.logFilePath, newFile);
     369#ifdef SYSLOGD_WRLOCK
    342370            fl.l_type = F_UNLCK;
    343371            fcntl(G.logFD, F_SETLKW, &fl);
     372#endif
    344373            close(G.logFD);
    345374            goto reopen;
     
    349378    G.curFileSize +=
    350379#endif
    351                     full_write(G.logFD, msg, len);
     380            full_write(G.logFD, msg, len);
     381#ifdef SYSLOGD_WRLOCK
    352382    fl.l_type = F_UNLCK;
    353383    fcntl(G.logFD, F_SETLKW, &fl);
     384#endif
    354385}
    355386
     
    362393        while (c_fac->c_name) {
    363394            if (c_fac->c_val != (LOG_FAC(pri) << 3)) {
    364                 c_fac++; continue;
     395                c_fac++;
     396                continue;
    365397            }
    366398            /* facility is found, look for prio */
     
    368400            while (c_pri->c_name) {
    369401                if (c_pri->c_val != LOG_PRI(pri)) {
    370                     c_pri++; continue;
     402                    c_pri++;
     403                    continue;
    371404                }
    372405                snprintf(res20, 20, "%s.%s",
     
    382415
    383416/* len parameter is used only for "is there a timestamp?" check.
    384  * NB: some callers cheat and supply 0 when they know
    385  * that there is no timestamp, short-cutting the test. */
     417 * NB: some callers cheat and supply len==0 when they know
     418 * that there is no timestamp, short-circuiting the test. */
    386419static void timestamp_and_log(int pri, char *msg, int len)
    387420{
    388421    char *timestamp;
    389 
     422    time_t now;
     423
     424    /* Jan 18 00:11:22 msg... */
     425    /* 01234567890123456 */
    390426    if (len < 16 || msg[3] != ' ' || msg[6] != ' '
    391427     || msg[9] != ':' || msg[12] != ':' || msg[15] != ' '
    392428    ) {
    393         time_t now;
    394429        time(&now);
    395         timestamp = ctime(&now) + 4;
     430        timestamp = ctime(&now) + 4; /* skip day of week */
    396431    } else {
     432        now = 0;
    397433        timestamp = msg;
    398434        msg += 16;
     
    400436    timestamp[15] = '\0';
    401437
     438    if (option_mask32 & OPT_small)
     439        sprintf(G.printbuf, "%s %s\n", timestamp, msg);
     440    else {
     441        char res[20];
     442        parse_fac_prio_20(pri, res);
     443        sprintf(G.printbuf, "%s %.64s %s %s\n", timestamp, G.hostname, res, msg);
     444    }
     445
    402446    /* Log message locally (to file or shared mem) */
    403     if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
    404         if (LOG_PRI(pri) < G.logLevel) {
    405             if (option_mask32 & OPT_small)
    406                 sprintf(G.printbuf, "%s %s\n", timestamp, msg);
    407             else {
    408                 char res[20];
    409                 parse_fac_prio_20(pri, res);
    410                 sprintf(G.printbuf, "%s %s %s %s\n", timestamp, G.localHostName, res, msg);
    411             }
    412             log_locally(G.printbuf);
    413         }
    414     }
    415 }
    416 
     447    log_locally(now, G.printbuf);
     448}
     449
     450static void timestamp_and_log_internal(const char *msg)
     451{
     452    /* -L, or no -R */
     453    if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_locallog))
     454        return;
     455    timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)msg, 0);
     456}
     457
     458/* tmpbuf[len] is a NUL byte (set by caller), but there can be other,
     459 * embedded NULs. Split messages on each of these NULs, parse prio,
     460 * escape control chars and log each locally. */
    417461static void split_escape_and_log(char *tmpbuf, int len)
    418462{
     
    428472            /* Parse the magic priority number */
    429473            pri = bb_strtou(p + 1, &p, 10);
    430             if (*p == '>') p++;
    431             if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
     474            if (*p == '>')
     475                p++;
     476            if (pri & ~(LOG_FACMASK | LOG_PRIMASK))
    432477                pri = (LOG_USER | LOG_NOTICE);
    433             }
    434478        }
    435479
     
    444488        }
    445489        *q = '\0';
     490
    446491        /* Now log it */
    447         timestamp_and_log(pri, G.parsebuf, q - G.parsebuf);
    448     }
    449 }
    450 
    451 static void quit_signal(int sig)
    452 {
    453     timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"syslogd exiting", 0);
     492        if (LOG_PRI(pri) < G.logLevel)
     493            timestamp_and_log(pri, G.parsebuf, q - G.parsebuf);
     494    }
     495}
     496
     497#ifdef SYSLOGD_MARK
     498static void do_mark(int sig)
     499{
     500    if (G.markInterval) {
     501        timestamp_and_log_internal("-- MARK --");
     502        alarm(G.markInterval);
     503    }
     504}
     505#endif
     506
     507/* Don't inline: prevent struct sockaddr_un to take up space on stack
     508 * permanently */
     509static NOINLINE int create_socket(void)
     510{
     511    struct sockaddr_un sunx;
     512    int sock_fd;
     513    char *dev_log_name;
     514
     515    memset(&sunx, 0, sizeof(sunx));
     516    sunx.sun_family = AF_UNIX;
     517
     518    /* Unlink old /dev/log or object it points to. */
     519    /* (if it exists, bind will fail) */
     520    strcpy(sunx.sun_path, "/dev/log");
     521    dev_log_name = xmalloc_follow_symlinks("/dev/log");
     522    if (dev_log_name) {
     523        safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));
     524        free(dev_log_name);
     525    }
     526    unlink(sunx.sun_path);
     527
     528    sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
     529    xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx));
     530    chmod("/dev/log", 0666);
     531
     532    return sock_fd;
     533}
     534
     535#if ENABLE_FEATURE_REMOTE_LOG
     536static int try_to_resolve_remote(remoteHost_t *rh)
     537{
     538    if (!rh->remoteAddr) {
     539        unsigned now = monotonic_sec();
     540
     541        /* Don't resolve name too often - DNS timeouts can be big */
     542        if ((now - rh->last_dns_resolve) < DNS_WAIT_SEC)
     543            return -1;
     544        rh->last_dns_resolve = now;
     545        rh->remoteAddr = host2sockaddr(rh->remoteHostname, 514);
     546        if (!rh->remoteAddr)
     547            return -1;
     548    }
     549    return xsocket(rh->remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0);
     550}
     551#endif
     552
     553static void do_syslogd(void) NORETURN;
     554static void do_syslogd(void)
     555{
     556    int sock_fd;
     557#if ENABLE_FEATURE_REMOTE_LOG
     558    llist_t *item;
     559#endif
     560#if ENABLE_FEATURE_SYSLOGD_DUP
     561    int last_sz = -1;
     562    char *last_buf;
     563    char *recvbuf = G.recvbuf;
     564#else
     565#define recvbuf (G.recvbuf)
     566#endif
     567
     568    /* Set up signal handlers (so that they interrupt read()) */
     569    signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo);
     570    signal_no_SA_RESTART_empty_mask(SIGINT, record_signo);
     571    //signal_no_SA_RESTART_empty_mask(SIGQUIT, record_signo);
     572    signal(SIGHUP, SIG_IGN);
     573#ifdef SYSLOGD_MARK
     574    signal(SIGALRM, do_mark);
     575    alarm(G.markInterval);
     576#endif
     577    sock_fd = create_socket();
     578
     579    if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) {
     580        ipcsyslog_init();
     581    }
     582
     583    timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER);
     584
     585    while (!bb_got_signal) {
     586        ssize_t sz;
     587
     588#if ENABLE_FEATURE_SYSLOGD_DUP
     589        last_buf = recvbuf;
     590        if (recvbuf == G.recvbuf)
     591            recvbuf = G.recvbuf + MAX_READ;
     592        else
     593            recvbuf = G.recvbuf;
     594#endif
     595 read_again:
     596        sz = read(sock_fd, recvbuf, MAX_READ - 1);
     597        if (sz < 0) {
     598            if (!bb_got_signal)
     599                bb_perror_msg("read from /dev/log");
     600            break;
     601        }
     602
     603        /* Drop trailing '\n' and NULs (typically there is one NUL) */
     604        while (1) {
     605            if (sz == 0)
     606                goto read_again;
     607            /* man 3 syslog says: "A trailing newline is added when needed".
     608             * However, neither glibc nor uclibc do this:
     609             * syslog(prio, "test")   sends "test\0" to /dev/log,
     610             * syslog(prio, "test\n") sends "test\n\0".
     611             * IOW: newline is passed verbatim!
     612             * I take it to mean that it's syslogd's job
     613             * to make those look identical in the log files. */
     614            if (recvbuf[sz-1] != '\0' && recvbuf[sz-1] != '\n')
     615                break;
     616            sz--;
     617        }
     618#if ENABLE_FEATURE_SYSLOGD_DUP
     619        if ((option_mask32 & OPT_dup) && (sz == last_sz))
     620            if (memcmp(last_buf, recvbuf, sz) == 0)
     621                continue;
     622        last_sz = sz;
     623#endif
     624#if ENABLE_FEATURE_REMOTE_LOG
     625        /* Stock syslogd sends it '\n'-terminated
     626         * over network, mimic that */
     627        recvbuf[sz] = '\n';
     628
     629        /* We are not modifying log messages in any way before send */
     630        /* Remote site cannot trust _us_ anyway and need to do validation again */
     631        for (item = G.remoteHosts; item != NULL; item = item->link) {
     632            remoteHost_t *rh = (remoteHost_t *)item->data;
     633
     634            if (rh->remoteFD == -1) {
     635                rh->remoteFD = try_to_resolve_remote(rh);
     636                if (rh->remoteFD == -1)
     637                    continue;
     638            }
     639
     640            /* Send message to remote logger.
     641             * On some errors, close and set remoteFD to -1
     642             * so that DNS resolution is retried.
     643             */
     644            if (sendto(rh->remoteFD, recvbuf, sz+1,
     645                    MSG_DONTWAIT | MSG_NOSIGNAL,
     646                    &(rh->remoteAddr->u.sa), rh->remoteAddr->len) == -1
     647            ) {
     648                switch (errno) {
     649                case ECONNRESET:
     650                case ENOTCONN: /* paranoia */
     651                case EPIPE:
     652                    close(rh->remoteFD);
     653                    rh->remoteFD = -1;
     654                    free(rh->remoteAddr);
     655                    rh->remoteAddr = NULL;
     656                }
     657            }
     658        }
     659#endif
     660        if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
     661            recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */
     662            split_escape_and_log(recvbuf, sz);
     663        }
     664    } /* while (!bb_got_signal) */
     665
     666    timestamp_and_log_internal("syslogd exiting");
    454667    puts("syslogd exiting");
    455668    if (ENABLE_FEATURE_IPC_SYSLOG)
    456669        ipcsyslog_cleanup();
    457     exit(1);
    458 }
     670    kill_myself_with_sig(bb_got_signal);
     671#undef recvbuf
     672}
     673
     674int syslogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     675int syslogd_main(int argc UNUSED_PARAM, char **argv)
     676{
     677    int opts;
     678    char OPTION_DECL;
     679#if ENABLE_FEATURE_REMOTE_LOG
     680    llist_t *remoteAddrList = NULL;
     681#endif
     682
     683    INIT_G();
     684
     685    /* No non-option params, -R can occur multiple times */
     686    opt_complementary = "=0" IF_FEATURE_REMOTE_LOG(":R::");
     687    opts = getopt32(argv, OPTION_STR, OPTION_PARAM);
     688#if ENABLE_FEATURE_REMOTE_LOG
     689    while (remoteAddrList) {
     690        remoteHost_t *rh = xzalloc(sizeof(*rh));
     691        rh->remoteHostname = llist_pop(&remoteAddrList);
     692        rh->remoteFD = -1;
     693        rh->last_dns_resolve = monotonic_sec() - DNS_WAIT_SEC - 1;
     694        llist_add_to(&G.remoteHosts, rh);
     695    }
     696#endif
    459697
    460698#ifdef SYSLOGD_MARK
    461 static void do_mark(int sig)
    462 {
    463     if (G.markInterval) {
    464         timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"-- MARK --", 0);
    465         alarm(G.markInterval);
    466     }
    467 }
    468 #endif
    469 
    470 static void do_syslogd(void) ATTRIBUTE_NORETURN;
    471 static void do_syslogd(void)
    472 {
    473     struct sockaddr_un sunx;
    474     int sock_fd;
    475     fd_set fds;
    476     char *dev_log_name;
    477 
    478     /* Set up signal handlers */
    479     signal(SIGINT, quit_signal);
    480     signal(SIGTERM, quit_signal);
    481     signal(SIGQUIT, quit_signal);
    482     signal(SIGHUP, SIG_IGN);
    483     signal(SIGCHLD, SIG_IGN);
    484 #ifdef SIGCLD
    485     signal(SIGCLD, SIG_IGN);
    486 #endif
    487 #ifdef SYSLOGD_MARK
    488     signal(SIGALRM, do_mark);
    489     alarm(G.markInterval);
    490 #endif
    491     remove_pidfile("/var/run/syslogd.pid");
    492 
    493     memset(&sunx, 0, sizeof(sunx));
    494     sunx.sun_family = AF_UNIX;
    495     strcpy(sunx.sun_path, "/dev/log");
    496 
    497     /* Unlink old /dev/log or object it points to. */
    498     /* (if it exists, bind will fail) */
    499     logmode = LOGMODE_NONE;
    500     dev_log_name = xmalloc_readlink_or_warn("/dev/log");
    501     logmode = LOGMODE_STDIO;
    502     if (dev_log_name) {
    503         int fd = xopen(".", O_NONBLOCK);
    504         xchdir("/dev");
    505         /* we do not check whether this is a link also */
    506         unlink(dev_log_name);
    507         fchdir(fd);
    508         close(fd);
    509         safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));
    510         free(dev_log_name);
    511     } else {
    512         unlink("/dev/log");
    513     }
    514 
    515     sock_fd = xsocket(AF_UNIX, SOCK_DGRAM, 0);
    516     xbind(sock_fd, (struct sockaddr *) &sunx, sizeof(sunx));
    517 
    518     if (chmod("/dev/log", 0666) < 0) {
    519         bb_perror_msg_and_die("cannot set permission on /dev/log");
    520     }
    521     if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) {
    522         ipcsyslog_init();
    523     }
    524 
    525     timestamp_and_log(LOG_SYSLOG | LOG_INFO,
    526             (char*)"syslogd started: BusyBox v" BB_VER, 0);
    527 
    528     for (;;) {
    529         FD_ZERO(&fds);
    530         FD_SET(sock_fd, &fds);
    531 
    532         if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
    533             if (errno == EINTR) {
    534                 /* alarm may have happened */
    535                 continue;
    536             }
    537             bb_perror_msg_and_die("select");
    538         }
    539 
    540         if (FD_ISSET(sock_fd, &fds)) {
    541             int i;
    542             i = recv(sock_fd, G.recvbuf, MAX_READ - 1, 0);
    543             if (i <= 0)
    544                 bb_perror_msg_and_die("UNIX socket error");
    545             /* TODO: maybe suppress duplicates? */
    546 #if ENABLE_FEATURE_REMOTE_LOG
    547             /* We are not modifying log messages in any way before send */
    548             /* Remote site cannot trust _us_ anyway and need to do validation again */
    549             if (G.remoteAddr) {
    550                 if (-1 == G.remoteFD) {
    551                     G.remoteFD = socket(G.remoteAddr->sa.sa_family, SOCK_DGRAM, 0);
    552                 }
    553                 if (-1 != G.remoteFD) {
    554                     /* send message to remote logger, ignore possible error */
    555                     sendto(G.remoteFD, G.recvbuf, i, MSG_DONTWAIT,
    556                         &G.remoteAddr->sa, G.remoteAddr->len);
    557                 }
    558             }
    559 #endif
    560             G.recvbuf[i] = '\0';
    561             split_escape_and_log(G.recvbuf, i);
    562         } /* FD_ISSET() */
    563     } /* for */
    564 }
    565 
    566 int syslogd_main(int argc, char **argv);
    567 int syslogd_main(int argc, char **argv)
    568 {
    569     char OPTION_DECL;
    570     char *p;
    571 
    572     PTR_TO_GLOBALS = memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data));
    573 
    574     /* do normal option parsing */
    575     opt_complementary = "=0"; /* no non-option params */
    576     getopt32(argv, OPTION_STR, OPTION_PARAM);
    577 #ifdef SYSLOGD_MARK
    578     if (option_mask32 & OPT_mark) // -m
     699    if (opts & OPT_mark) // -m
    579700        G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60;
    580701#endif
    581     //if (option_mask32 & OPT_nofork) // -n
    582     //if (option_mask32 & OPT_outfile) // -O
    583     if (option_mask32 & OPT_loglevel) // -l
     702    //if (opts & OPT_nofork) // -n
     703    //if (opts & OPT_outfile) // -O
     704    if (opts & OPT_loglevel) // -l
    584705        G.logLevel = xatou_range(opt_l, 1, 8);
    585     //if (option_mask32 & OPT_small) // -S
     706    //if (opts & OPT_small) // -S
    586707#if ENABLE_FEATURE_ROTATE_LOGFILE
    587     if (option_mask32 & OPT_filesize) // -s
     708    if (opts & OPT_filesize) // -s
    588709        G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024;
    589     if (option_mask32 & OPT_rotatecnt) // -b
     710    if (opts & OPT_rotatecnt) // -b
    590711        G.logFileRotate = xatou_range(opt_b, 0, 99);
    591 #endif
    592 #if ENABLE_FEATURE_REMOTE_LOG
    593     if (option_mask32 & OPT_remotelog) { // -R
    594         G.remoteAddr = xhost2sockaddr(opt_R, 514);
    595     }
    596     //if (option_mask32 & OPT_locallog) // -L
    597712#endif
    598713#if ENABLE_FEATURE_IPC_SYSLOG
     
    602717
    603718    /* If they have not specified remote logging, then log locally */
    604     if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_remotelog))
     719    if (ENABLE_FEATURE_REMOTE_LOG && !(opts & OPT_remotelog)) // -R
    605720        option_mask32 |= OPT_locallog;
    606721
    607722    /* Store away localhost's name before the fork */
    608     gethostname(G.localHostName, sizeof(G.localHostName));
    609     p = strchr(G.localHostName, '.');
    610     if (p) {
    611         *p = '\0';
    612     }
    613 
    614     if (!(option_mask32 & OPT_nofork)) {
     723    G.hostname = safe_gethostname();
     724    *strchrnul(G.hostname, '.') = '\0';
     725
     726    if (!(opts & OPT_nofork)) {
    615727        bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
    616728    }
    617     umask(0);
     729    //umask(0); - why??
    618730    write_pidfile("/var/run/syslogd.pid");
    619731    do_syslogd();
    620732    /* return EXIT_SUCCESS; */
    621733}
     734
     735/* Clean up. Needed because we are included from syslogd_and_logger.c */
     736#undef DEBUG
     737#undef SYSLOGD_MARK
     738#undef SYSLOGD_WRLOCK
     739#undef G
     740#undef GLOBALS
     741#undef INIT_G
     742#undef OPTION_STR
     743#undef OPTION_DECL
     744#undef OPTION_PARAM
Note: See TracChangeset for help on using the changeset viewer.