Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/sysklogd


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
Location:
branches/2.2.9/mindi-busybox/sysklogd
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/sysklogd/Config.in

    r1765 r2725  
     1# DO NOT EDIT. This file is generated from Config.src
    12#
    23# For a description of the syntax of this configuration file,
     
    67menu "System Logging Utilities"
    78
     9
     10
    811config SYSLOGD
    912    bool "syslogd"
    10     default n
     13    default y
    1114    help
    1215      The syslogd utility is used to record logs of all the
    13       significant events that occur on a system.  Every
     16      significant events that occur on a system. Every
    1417      message that is logged records the date and time of the
    1518      event, and will generally also record the name of the
    16       application that generated the message.  When used in
     19      application that generated the message. When used in
    1720      conjunction with klogd, messages from the Linux kernel
    18       can also be recorded.  This is terribly useful,
     21      can also be recorded. This is terribly useful,
    1922      especially for finding what happened when something goes
    20       wrong.  And something almost always will go wrong if
     23      wrong. And something almost always will go wrong if
    2124      you wait long enough....
    2225
    2326config FEATURE_ROTATE_LOGFILE
    2427    bool "Rotate message files"
    25     default n
     28    default y
    2629    depends on SYSLOGD
    2730    help
     
    3134config FEATURE_REMOTE_LOG
    3235    bool "Remote Log support"
    33     default n
     36    default y
    3437    depends on SYSLOGD
    3538    help
    3639      When you enable this feature, the syslogd utility can
    3740      be used to send system log messages to another system
    38       connected via a network.  This allows the remote
     41      connected via a network. This allows the remote
    3942      machine to log all the system messages, which can be
    4043      terribly useful for reducing the number of serial
    41       cables you use.  It can also be a very good security
     44      cables you use. It can also be a very good security
    4245      measure to prevent system logs from being tampered with
    4346      by an intruder.
    4447
     48config FEATURE_SYSLOGD_DUP
     49    bool "Support -D (drop dups) option"
     50    default y
     51    depends on SYSLOGD
     52    help
     53      Option -D instructs syslogd to drop consecutive messages
     54      which are totally the same.
     55
     56config FEATURE_SYSLOGD_READ_BUFFER_SIZE
     57    int "Read buffer size in bytes"
     58    default 256
     59    range 256 20000
     60    depends on SYSLOGD
     61    help
     62      This option sets the size of the syslog read buffer.
     63      Actual memory usage increases around five times the
     64      change done here.
     65
    4566config FEATURE_IPC_SYSLOG
    4667    bool "Circular Buffer support"
    47     default n
     68    default y
    4869    depends on SYSLOGD
    4970    help
     
    5172      use a circular buffer to record system log messages.
    5273      When the buffer is filled it will continue to overwrite
    53       the oldest messages.  This can be very useful for
     74      the oldest messages. This can be very useful for
    5475      systems with little or no permanent storage, since
    5576      otherwise system logs can eventually fill up your
     
    5879
    5980config FEATURE_IPC_SYSLOG_BUFFER_SIZE
    60     int "    Circular buffer size in Kbytes (minimum 4KB)"
     81    int "Circular buffer size in Kbytes (minimum 4KB)"
    6182    default 16
    6283    range 4 2147483647
     
    7293    help
    7394      If you enabled Circular Buffer support, you almost
    74       certainly want to enable this feature as well.  This
     95      certainly want to enable this feature as well. This
    7596      utility will allow you to read the messages that are
    7697      stored in the syslogd circular buffer.
    7798
    7899config FEATURE_LOGREAD_REDUCED_LOCKING
    79     bool "logread double buffering"
    80     default n
     100    bool "Double buffering"
     101    default y
    81102    depends on LOGREAD
    82103    help
     
    89110config KLOGD
    90111    bool "klogd"
    91     default n
     112    default y
    92113    help
    93114      klogd is a utility which intercepts and logs all
    94115      messages from the Linux kernel and sends the messages
    95       out to the 'syslogd' utility so they can be logged.  If
     116      out to the 'syslogd' utility so they can be logged. If
    96117      you wish to record the messages produced by the kernel,
    97118      you should enable this option.
    98119
     120config FEATURE_KLOGD_KLOGCTL
     121    bool "Use the klogctl() interface"
     122    default y
     123    depends on KLOGD && PLATFORM_LINUX
     124    help
     125      The klogd applet supports two interfaces for reading
     126      kernel messages. Linux provides the klogctl() interface
     127      which allows reading messages from the kernel ring buffer
     128      independently from the file system.
     129
     130      If you answer 'N' here, klogd will use the more portable
     131      approach of reading them from /proc or a device node.
     132      However, this method requires the file to be available.
     133
     134      If in doubt, say 'Y'.
     135
    99136config LOGGER
    100137    bool "logger"
    101     default n
     138    default y
    102139    select FEATURE_SYSLOG
    103140    help
    104141        The logger utility allows you to send arbitrary text
    105142        messages to the system log (i.e. the 'syslogd' utility) so
    106         they can be logged.  This is generally used to help locate
     143        they can be logged. This is generally used to help locate
    107144        problems that occur within programs and scripts.
    108145
    109146endmenu
    110 
  • branches/2.2.9/mindi-busybox/sysklogd/Kbuild

    r1765 r2725  
     1# DO NOT EDIT. This file is generated from Kbuild.src
    12# Makefile for busybox
    23#
    34# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
    45#
    5 # Licensed under the GPL v2, see the file LICENSE in this tarball.
     6# Licensed under GPLv2, see file LICENSE in this source tree.
    67
    78lib-y:=
     9
     10
    811lib-$(CONFIG_KLOGD)     += klogd.o
    9 lib-$(CONFIG_LOGGER)        += logger.o
     12lib-$(CONFIG_LOGGER)        += syslogd_and_logger.o
    1013lib-$(CONFIG_LOGREAD)       += logread.o
    11 lib-$(CONFIG_SYSLOGD)       += syslogd.o
     14lib-$(CONFIG_SYSLOGD)       += syslogd_and_logger.o
  • branches/2.2.9/mindi-busybox/sysklogd/klogd.c

    r1765 r2725  
    55 * Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>.
    66 * Changes: Made this a standalone busybox module which uses standalone
    7  *                  syslog() client interface.
     7 * syslog() client interface.
    88 *
    99 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
     
    1515 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
    1616 *
    17  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     17 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1818 */
    1919
    2020#include "libbb.h"
    21 #include <sys/syslog.h>
    22 #include <sys/klog.h>
    23 
    24 static void klogd_signal(int sig ATTRIBUTE_UNUSED)
    25 {
    26     klogctl(7, NULL, 0);
    27     klogctl(0, 0, 0);
    28     syslog(LOG_NOTICE, "Kernel log daemon exiting");
    29     exit(EXIT_SUCCESS);
    30 }
    31 
    32 #define OPT_LEVEL        1
    33 #define OPT_FOREGROUND   2
    34 
    35 #define KLOGD_LOGBUF_SIZE BUFSIZ
     21#include <syslog.h>
     22
     23
     24/* The Linux-specific klogctl(3) interface does not rely on the filesystem and
     25 * allows us to change the console loglevel. Alternatively, we read the
     26 * messages from _PATH_KLOG. */
     27
     28#if ENABLE_FEATURE_KLOGD_KLOGCTL
     29
     30# include <sys/klog.h>
     31
     32static void klogd_open(void)
     33{
     34    /* "Open the log. Currently a NOP" */
     35    klogctl(1, NULL, 0);
     36}
     37
     38static void klogd_setloglevel(int lvl)
     39{
     40    /* "printk() prints a message on the console only if it has a loglevel
     41     * less than console_loglevel". Here we set console_loglevel = lvl. */
     42    klogctl(8, NULL, lvl);
     43}
     44
     45static int klogd_read(char *bufp, int len)
     46{
     47    return klogctl(2, bufp, len);
     48}
     49# define READ_ERROR "klogctl(2) error"
     50
     51static void klogd_close(void)
     52{
     53    /* FYI: cmd 7 is equivalent to setting console_loglevel to 7
     54     * via klogctl(8, NULL, 7). */
     55    klogctl(7, NULL, 0); /* "7 -- Enable printk's to console" */
     56    klogctl(0, NULL, 0); /* "0 -- Close the log. Currently a NOP" */
     57}
     58
     59#else
     60
     61# include <paths.h>
     62# ifndef _PATH_KLOG
     63#  ifdef __GNU__
     64#   define _PATH_KLOG "/dev/klog"
     65#  else
     66#   error "your system's _PATH_KLOG is unknown"
     67#  endif
     68# endif
     69# define PATH_PRINTK "/proc/sys/kernel/printk"
     70
     71enum { klogfd = 3 };
     72
     73static void klogd_open(void)
     74{
     75    int fd = xopen(_PATH_KLOG, O_RDONLY);
     76    xmove_fd(fd, klogfd);
     77}
     78
     79static void klogd_setloglevel(int lvl)
     80{
     81    FILE *fp = fopen_or_warn(PATH_PRINTK, "w");
     82    if (fp) {
     83        /* This changes only first value:
     84         * "messages with a higher priority than this
     85         * [that is, with numerically lower value]
     86         * will be printed to the console".
     87         * The other three values in this pseudo-file aren't changed.
     88         */
     89        fprintf(fp, "%u\n", lvl);
     90        fclose(fp);
     91    }
     92}
     93
     94static int klogd_read(char *bufp, int len)
     95{
     96    return read(klogfd, bufp, len);
     97}
     98# define READ_ERROR "read error"
     99
     100static void klogd_close(void)
     101{
     102    klogd_setloglevel(7);
     103    if (ENABLE_FEATURE_CLEAN_UP)
     104        close(klogfd);
     105}
     106
     107#endif
     108
    36109#define log_buffer bb_common_bufsiz1
    37 
    38 int klogd_main(int argc, char **argv);
    39 int klogd_main(int argc, char **argv)
    40 {
    41     int i = i; /* silence gcc */
    42     char *start;
    43 
    44     /* do normal option parsing */
    45     getopt32(argv, "c:n", &start);
    46 
    47     if (option_mask32 & OPT_LEVEL) {
     110enum {
     111    KLOGD_LOGBUF_SIZE = sizeof(log_buffer),
     112    OPT_LEVEL      = (1 << 0),
     113    OPT_FOREGROUND = (1 << 1),
     114};
     115
     116/* TODO: glibc openlog(LOG_KERN) reverts to LOG_USER instead,
     117 * because that's how they interpret word "default"
     118 * in the openlog() manpage:
     119 *      LOG_USER (default)
     120 *              generic user-level messages
     121 * and the fact that LOG_KERN is a constant 0.
     122 * glibc interprets it as "0 in openlog() call means 'use default'".
     123 * I think it means "if openlog wasn't called before syslog() is called,
     124 * use default".
     125 * Convincing glibc maintainers otherwise is, as usual, nearly impossible.
     126 * Should we open-code syslog() here to use correct facility?
     127 */
     128
     129int klogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     130int klogd_main(int argc UNUSED_PARAM, char **argv)
     131{
     132    int i = 0;
     133    char *opt_c;
     134    int opt;
     135    int used;
     136
     137    opt = getopt32(argv, "c:n", &opt_c);
     138    if (opt & OPT_LEVEL) {
    48139        /* Valid levels are between 1 and 8 */
    49         i = xatoul_range(start, 1, 8);
    50     }
    51 
    52     if (!(option_mask32 & OPT_FOREGROUND)) {
     140        i = xatou_range(opt_c, 1, 8);
     141    }
     142    if (!(opt & OPT_FOREGROUND)) {
    53143        bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
    54144    }
    55145
     146    logmode = LOGMODE_SYSLOG;
     147
     148    /* klogd_open() before openlog(), since it might use fixed fd 3,
     149     * and openlog() also may use the same fd 3 if we swap them:
     150     */
     151    klogd_open();
    56152    openlog("kernel", 0, LOG_KERN);
    57153
    58     /* Set up sig handlers */
    59     signal(SIGINT, klogd_signal);
    60     signal(SIGKILL, klogd_signal);
    61     signal(SIGTERM, klogd_signal);
     154    if (i)
     155        klogd_setloglevel(i);
     156
     157    bb_signals(BB_FATAL_SIGS, record_signo);
    62158    signal(SIGHUP, SIG_IGN);
    63159
    64     /* "Open the log. Currently a NOP." */
    65     klogctl(1, NULL, 0);
    66 
    67     /* Set level of kernel console messaging. */
    68     if (option_mask32 & OPT_LEVEL)
    69         klogctl(8, NULL, i);
    70 
    71160    syslog(LOG_NOTICE, "klogd started: %s", bb_banner);
    72161
    73     /* Note: this code does not detect incomplete messages
    74      * (messages not ending with '\n' or just when kernel
    75      * generates too many messages for us to keep up)
    76      * and will split them in two separate lines */
    77     while (1) {
     162    used = 0;
     163    while (!bb_got_signal) {
    78164        int n;
    79165        int priority;
    80 
    81         n = klogctl(2, log_buffer, KLOGD_LOGBUF_SIZE - 1);
     166        char *start;
     167
     168        /* "2 -- Read from the log." */
     169        start = log_buffer + used;
     170        n = klogd_read(start, KLOGD_LOGBUF_SIZE-1 - used);
    82171        if (n < 0) {
    83172            if (errno == EINTR)
    84173                continue;
    85             syslog(LOG_ERR, "klogd: error from klogctl(2): %d - %m",
    86                     errno);
     174            bb_perror_msg(READ_ERROR);
    87175            break;
    88176        }
    89         log_buffer[n] = '\n';
    90         i = 0;
    91         while (i < n) {
     177        start[n] = '\0';
     178
     179        /* Process each newline-terminated line in the buffer */
     180        start = log_buffer;
     181        while (1) {
     182            char *newline = strchrnul(start, '\n');
     183
     184            if (*newline == '\0') {
     185                /* This line is incomplete */
     186
     187                /* move it to the front of the buffer */
     188                overlapping_strcpy(log_buffer, start);
     189                used = newline - start;
     190                if (used < KLOGD_LOGBUF_SIZE-1) {
     191                    /* buffer isn't full */
     192                    break;
     193                }
     194                /* buffer is full, log it anyway */
     195                used = 0;
     196                newline = NULL;
     197            } else {
     198                *newline++ = '\0';
     199            }
     200
     201            /* Extract the priority */
    92202            priority = LOG_INFO;
    93             start = &log_buffer[i];
    94             if (log_buffer[i] == '<') {
    95                 i++;
    96                 // kernel never ganerates multi-digit prios
    97                 //priority = 0;
    98                 //while (log_buffer[i] >= '0' && log_buffer[i] <= '9') {
    99                 //  priority = priority * 10 + (log_buffer[i] - '0');
    100                 //  i++;
    101                 //}
    102                 if (isdigit(log_buffer[i])) {
    103                     priority = (log_buffer[i] - '0');
    104                     i++;
     203            if (*start == '<') {
     204                start++;
     205                if (*start) {
     206                    /* kernel never generates multi-digit prios */
     207                    priority = (*start - '0');
     208                    start++;
    105209                }
    106                 if (log_buffer[i] == '>')
    107                     i++;
    108                 start = &log_buffer[i];
     210                if (*start == '>')
     211                    start++;
    109212            }
    110             while (log_buffer[i] != '\n')
    111                 i++;
    112             log_buffer[i] = '\0';
    113             syslog(priority, "%s", start);
    114             i++;
     213            /* Log (only non-empty lines) */
     214            if (*start)
     215                syslog(priority, "%s", start);
     216
     217            if (!newline)
     218                break;
     219            start = newline;
    115220        }
    116221    }
    117222
     223    klogd_close();
     224    syslog(LOG_NOTICE, "klogd: exiting");
     225    if (bb_got_signal)
     226        kill_myself_with_sig(bb_got_signal);
    118227    return EXIT_FAILURE;
    119228}
  • branches/2.2.9/mindi-busybox/sysklogd/logger.c

    r1772 r2725  
    55 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    66 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    88 */
    99
     10/*
     11 * Done in syslogd_and_logger.c:
    1012#include "libbb.h"
    11 
    12 #if !defined CONFIG_SYSLOGD
    13 
    1413#define SYSLOG_NAMES
    15 #include <sys/syslog.h>
    16 
    17 #else
    18 #include <sys/syslog.h>
    19 #  ifndef __dietlibc__
    20     /* We have to do this since the header file defines static
    21      * structures.  Argh.... bad libc, bad, bad...
    22      */
    23     typedef struct _code {
    24         char *c_name;
    25         int c_val;
    26     } CODE;
    27     extern CODE prioritynames[];
    28     extern CODE facilitynames[];
    29 #  endif
    30 #endif
     14#define SYSLOG_NAMES_CONST
     15#include <syslog.h>
     16*/
    3117
    3218/* Decode a symbolic name to a numeric value
     
    3723 * Original copyright notice is retained at the end of this file.
    3824 */
    39 static int decode(char *name, CODE * codetab)
     25static int decode(char *name, const CODE *codetab)
    4026{
    41     CODE *c;
     27    const CODE *c;
    4228
    4329    if (isdigit(*name))
     
    8167}
    8268
     69#define strbuf bb_common_bufsiz1
    8370
    84 int logger_main(int argc, char **argv);
    85 int logger_main(int argc, char **argv)
     71int logger_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     72int logger_main(int argc UNUSED_PARAM, char **argv)
    8673{
    8774    char *str_p, *str_t;
     75    int opt;
    8876    int i = 0;
    89     char name[80];
    9077
    9178    /* Fill out the name string early (may be overwritten later) */
    92     bb_getpwuid(name, sizeof(name), geteuid());
    93     str_t = name;
     79    str_t = uid2uname_utoa(geteuid());
    9480
    9581    /* Parse any options */
    96     getopt32(argv, "p:st:", &str_p, &str_t);
     82    opt = getopt32(argv, "p:st:", &str_p, &str_t);
    9783
    98     if (option_mask32 & 0x2) /* -s */
     84    if (opt & 0x2) /* -s */
    9985        i |= LOG_PERROR;
    100     //if (option_mask32 & 0x4) /* -t */
     86    //if (opt & 0x4) /* -t */
    10187    openlog(str_t, i, 0);
    10288    i = LOG_USER | LOG_NOTICE;
    103     if (option_mask32 & 0x1) /* -p */
     89    if (opt & 0x1) /* -p */
    10490        i = pencode(str_p);
    10591
    106     argc -= optind;
    10792    argv += optind;
    108     if (!argc) {
    109 #define strbuf bb_common_bufsiz1
     93    if (!argv[0]) {
    11094        while (fgets(strbuf, COMMON_BUFSIZE, stdin)) {
    11195            if (strbuf[0]
     
    133117}
    134118
     119/* Clean up. Needed because we are included from syslogd_and_logger.c */
     120#undef strbuf
    135121
    136122/*-
    137123 * Copyright (c) 1983, 1993
    138  *  The Regents of the University of California.  All rights reserved.
     124 * The Regents of the University of California.  All rights reserved.
    139125 *
    140126 * This is the original license statement for the decode and pencode functions.
     
    149135 *    documentation and/or other materials provided with the distribution.
    150136 *
    151  * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
    152  *      ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
     137 * 3. BSD Advertising Clause omitted per the July 22, 1999 licensing change
     138 *    ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
    153139 *
    154140 * 4. Neither the name of the University nor the names of its contributors
  • branches/2.2.9/mindi-busybox/sysklogd/logread.c

    r1765 r2725  
    77 * Maintainer: Gennady Feldman <gfeldman@gena01.com> as of Mar 12, 2001
    88 *
    9  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     9 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1010 */
    1111
     
    1717#define DEBUG 0
    1818
     19/* our shared key (syslogd.c and logread.c must be in sync) */
    1920enum { KEY_ID = 0x414e4547 }; /* "GENA" */
    2021
    21 static struct shbuf_ds {
     22struct shbuf_ds {
    2223    int32_t size;           // size of data - 1
    2324    int32_t tail;           // end of message list
    2425    char data[1];           // messages
    25 } *shbuf;
     26};
    2627
    27 // Semaphore operation structures
    28 static struct sembuf SMrup[1] = {{0, -1, IPC_NOWAIT | SEM_UNDO}}; // set SMrup
    29 static struct sembuf SMrdn[2] = {{1, 0}, {0, +1, SEM_UNDO}}; // set SMrdn
     28static const struct sembuf init_sem[3] = {
     29    {0, -1, IPC_NOWAIT | SEM_UNDO},
     30    {1, 0}, {0, +1, SEM_UNDO}
     31};
    3032
     33struct globals {
     34    struct sembuf SMrup[1]; // {0, -1, IPC_NOWAIT | SEM_UNDO},
     35    struct sembuf SMrdn[2]; // {1, 0}, {0, +1, SEM_UNDO}
     36    struct shbuf_ds *shbuf;
     37} FIX_ALIASING;
     38#define G (*(struct globals*)&bb_common_bufsiz1)
     39#define SMrup (G.SMrup)
     40#define SMrdn (G.SMrdn)
     41#define shbuf (G.shbuf)
     42#define INIT_G() do { \
     43    memcpy(SMrup, init_sem, sizeof(init_sem)); \
     44} while (0)
    3145
    32 static void error_exit(const char *str) ATTRIBUTE_NORETURN;
     46static void error_exit(const char *str) NORETURN;
    3347static void error_exit(const char *str)
    3448{
     
    4761}
    4862
    49 static void interrupted(int sig ATTRIBUTE_UNUSED)
     63static void interrupted(int sig UNUSED_PARAM)
    5064{
    5165    signal(SIGINT, SIG_IGN);
    5266    shmdt(shbuf);
    53     exit(0);
     67    exit(EXIT_SUCCESS);
    5468}
    5569
    56 int logread_main(int argc, char **argv);
    57 int logread_main(int argc, char **argv)
     70int logread_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     71int logread_main(int argc UNUSED_PARAM, char **argv)
    5872{
    59     int cur;
     73    unsigned cur;
    6074    int log_semid; /* ipc semaphore id */
    6175    int log_shmid; /* ipc shared memory id */
    6276    smallint follow = getopt32(argv, "f");
     77
     78    INIT_G();
    6379
    6480    log_shmid = shmget(KEY_ID, 0, 0);
     
    120136            if (cur == shbuf_tail) {
    121137                sem_up(log_semid);
    122                 fflush(stdout);
     138                fflush_all();
    123139                sleep(1); /* TODO: replace me with a sleep_on */
    124140                continue;
  • 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.