Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (12 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod? silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian? keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René? Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

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

    r821 r1770  
    1414 */
    1515
    16 #include "busybox.h"
    17 #include <stdio.h>
    18 #include <stdlib.h>
    19 #include <ctype.h>
    20 #include <errno.h>
    21 #include <fcntl.h>
    22 #include <getopt.h>
    23 #include <netdb.h>
     16#include "libbb.h"
    2417#include <paths.h>
    25 #include <signal.h>
    26 #include <stdarg.h>
    27 #include <stdbool.h>
    28 #include <time.h>
    29 #include <string.h>
    30 #include <unistd.h>
    31 #include <sys/socket.h>
    32 #include <sys/types.h>
    3318#include <sys/un.h>
    34 #include <sys/param.h>
    35 
    36 /* SYSLOG_NAMES defined to pull some extra junk from syslog.h */
     19
     20/* SYSLOG_NAMES defined to pull prioritynames[] and facilitynames[]
     21 * from syslog.h. Grrrr - glibc puts those in _rwdata_! :( */
    3722#define SYSLOG_NAMES
     23#define SYSLOG_NAMES_CONST /* uclibc is saner :) */
    3824#include <sys/syslog.h>
    3925#include <sys/uio.h>
    4026
    41 /* Path for the file where all log messages are written */
    42 #define __LOG_FILE "/var/log/messages"
    43 
    44 /* Path to the unix socket */
    45 static char lfile[MAXPATHLEN];
    46 
    47 static const char *logFilePath = __LOG_FILE;
    48 
    49 #ifdef CONFIG_FEATURE_ROTATE_LOGFILE
    50 /* max size of message file before being rotated */
    51 static int logFileSize = 200 * 1024;
    52 
    53 /* number of rotated message files */
    54 static int logFileRotate = 1;
    55 #endif
    56 
    57 /* interval between marks in seconds */
    58 static int MarkInterval = 20 * 60;
    59 
    60 /* localhost's name */
    61 static char LocalHostName[64];
    62 
    63 #ifdef CONFIG_FEATURE_REMOTE_LOG
     27#if ENABLE_FEATURE_REMOTE_LOG
    6428#include <netinet/in.h>
    65 /* udp socket for logging to remote host */
    66 static int remotefd = -1;
    67 static struct sockaddr_in remoteaddr;
    68 
    69 /* where do we log? */
    70 static char *RemoteHost;
    71 
    72 /* what port to log to? */
    73 static int RemotePort = 514;
    74 
    75 /* To remote log or not to remote log, that is the question. */
    76 static int doRemoteLog = FALSE;
    77 static int local_logging = FALSE;
    78 #endif
    79 
    80 /* Make loging output smaller. */
    81 static bool small = false;
    82 
    83 
    84 #define MAXLINE         1024    /* maximum line length */
     29#endif
     30
     31#if ENABLE_FEATURE_IPC_SYSLOG
     32#include <sys/ipc.h>
     33#include <sys/sem.h>
     34#include <sys/shm.h>
     35#endif
     36
     37
     38#define DEBUG 0
     39
     40/* MARK code is not very useful, is bloat, and broken:
     41 * can deadlock if alarmed to make MARK while writing to IPC buffer
     42 * (semaphores are down but do_mark routine tries to down them again) */
     43#undef SYSLOGD_MARK
     44
     45enum { MAX_READ = 256 };
     46
     47/* Semaphore operation structures */
     48struct shbuf_ds {
     49    int32_t size;   /* size of data - 1 */
     50    int32_t tail;   /* end of message list */
     51    char data[1];   /* data/messages */
     52};
     53
     54/* Allows us to have smaller initializer. Ugly. */
     55#define GLOBALS \
     56    const char *logFilePath;                \
     57    int logFD;                              \
     58    /* interval between marks in seconds */ \
     59    /*int markInterval;*/                   \
     60    /* level of messages to be logged */    \
     61    int logLevel;                           \
     62USE_FEATURE_ROTATE_LOGFILE( \
     63    /* max size of file before rotation */  \
     64    unsigned logFileSize;                   \
     65    /* number of rotated message files */   \
     66    unsigned logFileRotate;                 \
     67    unsigned curFileSize;                   \
     68    smallint isRegular;                     \
     69) \
     70USE_FEATURE_REMOTE_LOG( \
     71    /* udp socket for remote logging */     \
     72    int remoteFD;                           \
     73    len_and_sockaddr* remoteAddr;           \
     74) \
     75USE_FEATURE_IPC_SYSLOG( \
     76    int shmid; /* ipc shared memory id */   \
     77    int s_semid; /* ipc semaphore id */     \
     78    int shm_size;                           \
     79    struct sembuf SMwup[1];                 \
     80    struct sembuf SMwdn[3];                 \
     81)
     82
     83struct init_globals {
     84    GLOBALS
     85};
     86
     87struct globals {
     88    GLOBALS
     89#if ENABLE_FEATURE_IPC_SYSLOG
     90    struct shbuf_ds *shbuf;
     91#endif
     92    time_t last_log_time;
     93    /* localhost's name */
     94    char localHostName[64];
     95
     96    /* We recv into recvbuf... */
     97    char recvbuf[MAX_READ];
     98    /* ...then copy to parsebuf, escaping control chars */
     99    /* (can grow x2 max) */
     100    char parsebuf[MAX_READ*2];
     101    /* ...then sprintf into printbuf, adding timestamp (15 chars),
     102     * host (64), fac.prio (20) to the message */
     103    /* (growth by: 15 + 64 + 20 + delims = ~110) */
     104    char printbuf[MAX_READ*2 + 128];
     105};
     106
     107static const struct init_globals init_data = {
     108    .logFilePath = "/var/log/messages",
     109    .logFD = -1,
     110#ifdef SYSLOGD_MARK
     111    .markInterval = 20 * 60,
     112#endif
     113    .logLevel = 8,
     114#if ENABLE_FEATURE_ROTATE_LOGFILE
     115    .logFileSize = 200 * 1024,
     116    .logFileRotate = 1,
     117#endif
     118#if ENABLE_FEATURE_REMOTE_LOG
     119    .remoteFD = -1,
     120#endif
     121#if ENABLE_FEATURE_IPC_SYSLOG
     122    .shmid = -1,
     123    .s_semid = -1,
     124    .shm_size = ((CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE)*1024), // default shm size
     125    .SMwup = { {1, -1, IPC_NOWAIT} },
     126    .SMwdn = { {0, 0}, {1, 0}, {1, +1} },
     127#endif
     128};
     129
     130#define G (*ptr_to_globals)
     131
     132
     133/* Options */
     134enum {
     135    OPTBIT_mark = 0, // -m
     136    OPTBIT_nofork, // -n
     137    OPTBIT_outfile, // -O
     138    OPTBIT_loglevel, // -l
     139    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
     145
     146    OPT_mark        = 1 << OPTBIT_mark    ,
     147    OPT_nofork      = 1 << OPTBIT_nofork  ,
     148    OPT_outfile     = 1 << OPTBIT_outfile ,
     149    OPT_loglevel    = 1 << OPTBIT_loglevel,
     150    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,
     156};
     157#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::")
     163#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)
     168#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)
    85173
    86174
    87175/* circular buffer variables/structures */
    88 #ifdef CONFIG_FEATURE_IPC_SYSLOG
     176#if ENABLE_FEATURE_IPC_SYSLOG
    89177
    90178#if CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE < 4
     
    93181#endif
    94182
    95 #include <sys/ipc.h>
    96 #include <sys/sem.h>
    97 #include <sys/shm.h>
    98 
    99183/* our shared key */
    100 static const long KEY_ID = 0x414e4547;  /*"GENA" */
    101 
    102 // Semaphore operation structures
    103 static struct shbuf_ds {
    104     int size;           // size of data written
    105     int head;           // start of message list
    106     int tail;           // end of message list
    107     char data[1];       // data/messages
    108 } *buf = NULL;          // shared memory pointer
    109 
    110 static struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} };    // set SMwup
    111 static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };    // set SMwdn
    112 
    113 static int shmid = -1;  // ipc shared memory id
    114 static int s_semid = -1;    // ipc semaphore id
    115 static int shm_size = ((CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE)*1024);   // default shm size
    116 static int circular_logging = FALSE;
    117 
    118 /*
    119  * sem_up - up()'s a semaphore.
    120  */
    121 static inline void sem_up(int semid)
    122 {
    123     if (semop(semid, SMwup, 1) == -1) {
    124         bb_perror_msg_and_die("semop[SMwup]");
    125     }
    126 }
    127 
    128 /*
    129  * sem_down - down()'s a semaphore
    130  */
    131 static inline void sem_down(int semid)
    132 {
    133     if (semop(semid, SMwdn, 3) == -1) {
    134         bb_perror_msg_and_die("semop[SMwdn]");
    135     }
    136 }
    137 
     184#define KEY_ID ((long)0x414e4547) /* "GENA" */
    138185
    139186static void ipcsyslog_cleanup(void)
    140187{
    141     printf("Exiting Syslogd!\n");
    142     if (shmid != -1) {
    143         shmdt(buf);
    144     }
    145 
    146     if (shmid != -1) {
    147         shmctl(shmid, IPC_RMID, NULL);
    148     }
    149     if (s_semid != -1) {
    150         semctl(s_semid, 0, IPC_RMID, 0);
     188    if (G.shmid != -1) {
     189        shmdt(G.shbuf);
     190    }
     191    if (G.shmid != -1) {
     192        shmctl(G.shmid, IPC_RMID, NULL);
     193    }
     194    if (G.s_semid != -1) {
     195        semctl(G.s_semid, 0, IPC_RMID, 0);
    151196    }
    152197}
     
    154199static void ipcsyslog_init(void)
    155200{
    156     if (buf == NULL) {
    157         if ((shmid = shmget(KEY_ID, shm_size, IPC_CREAT | 1023)) == -1) {
    158             bb_perror_msg_and_die("shmget");
    159         }
    160 
    161         if ((buf = shmat(shmid, NULL, 0)) == NULL) {
    162             bb_perror_msg_and_die("shmat");
    163         }
    164 
    165         buf->size = shm_size - sizeof(*buf);
    166         buf->head = buf->tail = 0;
    167 
    168         // we'll trust the OS to set initial semval to 0 (let's hope)
    169         if ((s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023)) == -1) {
    170             if (errno == EEXIST) {
    171                 if ((s_semid = semget(KEY_ID, 2, 0)) == -1) {
    172                     bb_perror_msg_and_die("semget");
    173                 }
    174             } else {
    175                 bb_perror_msg_and_die("semget");
    176             }
    177         }
     201    if (DEBUG)
     202        printf("shmget(%lx, %d,...)\n", KEY_ID, G.shm_size);
     203
     204    G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644);
     205    if (G.shmid == -1) {
     206        bb_perror_msg_and_die("shmget");
     207    }
     208
     209    G.shbuf = shmat(G.shmid, NULL, 0);
     210    if (!G.shbuf) {
     211        bb_perror_msg_and_die("shmat");
     212    }
     213
     214    memset(G.shbuf, 0, G.shm_size);
     215    G.shbuf->size = G.shm_size - offsetof(struct shbuf_ds, data) - 1;
     216    /*G.shbuf->tail = 0;*/
     217
     218    // we'll trust the OS to set initial semval to 0 (let's hope)
     219    G.s_semid = semget(KEY_ID, 2, IPC_CREAT | IPC_EXCL | 1023);
     220    if (G.s_semid == -1) {
     221        if (errno == EEXIST) {
     222            G.s_semid = semget(KEY_ID, 2, 0);
     223            if (G.s_semid != -1)
     224                return;
     225        }
     226        bb_perror_msg_and_die("semget");
     227    }
     228}
     229
     230/* Write message to shared mem buffer */
     231static void log_to_shmem(const char *msg, int len)
     232{
     233    int old_tail, new_tail;
     234
     235    if (semop(G.s_semid, G.SMwdn, 3) == -1) {
     236        bb_perror_msg_and_die("SMwdn");
     237    }
     238
     239    /* Circular Buffer Algorithm:
     240     * --------------------------
     241     * tail == position where to store next syslog message.
     242     * tail's max value is (shbuf->size - 1)
     243     * Last byte of buffer is never used and remains NUL.
     244     */
     245    len++; /* length with NUL included */
     246 again:
     247    old_tail = G.shbuf->tail;
     248    new_tail = old_tail + len;
     249    if (new_tail < G.shbuf->size) {
     250        /* store message, set new tail */
     251        memcpy(G.shbuf->data + old_tail, msg, len);
     252        G.shbuf->tail = new_tail;
    178253    } else {
    179         printf("Buffer already allocated just grab the semaphore?");
    180     }
    181 }
    182 
    183 /* write message to buffer */
    184 static void circ_message(const char *msg)
    185 {
    186     int l = strlen(msg) + 1;    /* count the whole message w/ '\0' included */
    187 
    188     sem_down(s_semid);
    189 
    190     /*
    191      * Circular Buffer Algorithm:
    192      * --------------------------
    193      *
    194      * Start-off w/ empty buffer of specific size SHM_SIZ
    195      * Start filling it up w/ messages. I use '\0' as separator to break up messages.
    196      * This is also very handy since we can do printf on message.
    197      *
    198      * Once the buffer is full we need to get rid of the first message in buffer and
    199      * insert the new message. (Note: if the message being added is >1 message then
    200      * we will need to "remove" >1 old message from the buffer). The way this is done
    201      * is the following:
    202      *      When we reach the end of the buffer we set a mark and start from the beginning.
    203      *      Now what about the beginning and end of the buffer? Well we have the "head"
    204      *      index/pointer which is the starting point for the messages and we have "tail"
    205      *      index/pointer which is the ending point for the messages. When we "display" the
    206      *      messages we start from the beginning and continue until we reach "tail". If we
    207      *      reach end of buffer, then we just start from the beginning (offset 0). "head" and
    208      *      "tail" are actually offsets from the beginning of the buffer.
    209      *
    210      * Note: This algorithm uses Linux IPC mechanism w/ shared memory and semaphores to provide
    211      *       a threadsafe way of handling shared memory operations.
    212      */
    213     if ((buf->tail + l) < buf->size) {
    214         /* before we append the message we need to check the HEAD so that we won't
    215            overwrite any of the message that we still need and adjust HEAD to point
    216            to the next message! */
    217         if (buf->tail < buf->head) {
    218             if ((buf->tail + l) >= buf->head) {
    219                 /* we need to move the HEAD to point to the next message
    220                  * Theoretically we have enough room to add the whole message to the
    221                  * buffer, because of the first outer IF statement, so we don't have
    222                  * to worry about overflows here!
    223                  */
    224                 int k = buf->tail + l - buf->head;  /* we need to know how many bytes
    225                                                        we are overwriting to make
    226                                                        enough room */
    227                 char *c =
    228                     memchr(buf->data + buf->head + k, '\0',
    229                            buf->size - (buf->head + k));
    230                 if (c != NULL) {    /* do a sanity check just in case! */
    231                     buf->head = c - buf->data + 1;  /* we need to convert pointer to
    232                                                        offset + skip the '\0' since
    233                                                        we need to point to the beginning
    234                                                        of the next message */
    235                     /* Note: HEAD is only used to "retrieve" messages, it's not used
    236                        when writing messages into our buffer */
    237                 } else {    /* show an error message to know we messed up? */
    238                     printf("Weird! Can't find the terminator token?\n");
    239                     buf->head = 0;
    240                 }
    241             }
    242         }
    243 
    244         /* in other cases no overflows have been done yet, so we don't care! */
    245         /* we should be ok to append the message now */
    246         strncpy(buf->data + buf->tail, msg, l); /* append our message */
    247         buf->tail += l; /* count full message w/ '\0' terminating char */
     254        /* k == available buffer space ahead of old tail */
     255        int k = G.shbuf->size - old_tail;
     256        /* copy what fits to the end of buffer, and repeat */
     257        memcpy(G.shbuf->data + old_tail, msg, k);
     258        msg += k;
     259        len -= k;
     260        G.shbuf->tail = 0;
     261        goto again;
     262    }
     263    if (semop(G.s_semid, G.SMwup, 1) == -1) {
     264        bb_perror_msg_and_die("SMwup");
     265    }
     266    if (DEBUG)
     267        printf("tail:%d\n", G.shbuf->tail);
     268}
     269#else
     270void ipcsyslog_cleanup(void);
     271void ipcsyslog_init(void);
     272void log_to_shmem(const char *msg);
     273#endif /* FEATURE_IPC_SYSLOG */
     274
     275
     276/* Print a message to the log file. */
     277static void log_locally(char *msg)
     278{
     279    struct flock fl;
     280    int len = strlen(msg);
     281
     282#if ENABLE_FEATURE_IPC_SYSLOG
     283    if ((option_mask32 & OPT_circularlog) && G.shbuf) {
     284        log_to_shmem(msg, len);
     285        return;
     286    }
     287#endif
     288    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 */
     293            close(G.logFD);
     294            goto reopen;
     295        }
    248296    } else {
    249         /* we need to break up the message and "circle" it around */
    250         char *c;
    251         int k = buf->tail + l - buf->size;  /* count # of bytes we don't fit */
    252 
    253         /* We need to move HEAD! This is always the case since we are going
    254          * to "circle" the message.
    255          */
    256         c = memchr(buf->data + k, '\0', buf->size - k);
    257 
    258         if (c != NULL) {    /* if we don't have '\0'??? weird!!! */
    259             /* move head pointer */
    260             buf->head = c - buf->data + 1;
    261 
    262             /* now write the first part of the message */
    263             strncpy(buf->data + buf->tail, msg, l - k - 1);
    264 
    265             /* ALWAYS terminate end of buffer w/ '\0' */
    266             buf->data[buf->size - 1] = '\0';
    267 
    268             /* now write out the rest of the string to the beginning of the buffer */
    269             strcpy(buf->data, &msg[l - k - 1]);
    270 
    271             /* we need to place the TAIL at the end of the message */
    272             buf->tail = k + 1;
    273         } else {
    274             printf
    275                 ("Weird! Can't find the terminator token from the beginning?\n");
    276             buf->head = buf->tail = 0;  /* reset buffer, since it's probably corrupted */
    277         }
    278 
    279     }
    280     sem_up(s_semid);
    281 }
    282 #endif                          /* CONFIG_FEATURE_IPC_SYSLOG */
    283 
    284 /* Note: There is also a function called "message()" in init.c */
    285 /* Print a message to the log file. */
    286 static void message(char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
    287 static void message(char *fmt, ...)
    288 {
    289     int fd;
    290     struct flock fl;
    291     va_list arguments;
     297 reopen:
     298        G.logFD = device_open(G.logFilePath, O_WRONLY | O_CREAT
     299                    | O_NOCTTY | O_APPEND | O_NONBLOCK);
     300        if (G.logFD < 0) {
     301            /* cannot open logfile? - print to /dev/console then */
     302            int fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
     303            if (fd < 0)
     304                fd = 2; /* then stderr, dammit */
     305            full_write(fd, msg, len);
     306            if (fd != 2)
     307                close(fd);
     308            return;
     309        }
     310#if ENABLE_FEATURE_ROTATE_LOGFILE
     311        {
     312            struct stat statf;
     313            G.isRegular = (fstat(G.logFD, &statf) == 0 && S_ISREG(statf.st_mode));
     314            /* bug (mostly harmless): can wrap around if file > 4gb */
     315            G.curFileSize = statf.st_size;
     316        }
     317#endif
     318    }
    292319
    293320    fl.l_whence = SEEK_SET;
    294321    fl.l_start = 0;
    295322    fl.l_len = 1;
    296 
    297 #ifdef CONFIG_FEATURE_IPC_SYSLOG
    298     if ((circular_logging == TRUE) && (buf != NULL)) {
    299         char b[1024];
    300 
    301         va_start(arguments, fmt);
    302         vsnprintf(b, sizeof(b) - 1, fmt, arguments);
    303         va_end(arguments);
    304         circ_message(b);
    305 
    306     } else
    307 #endif
    308     if ((fd = device_open(logFilePath,
    309                     O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
    310                              O_NONBLOCK)) >= 0) {
    311         fl.l_type = F_WRLCK;
    312         fcntl(fd, F_SETLKW, &fl);
    313 #ifdef CONFIG_FEATURE_ROTATE_LOGFILE
    314         if ( logFileSize > 0 ) {
    315             struct stat statf;
    316             int r = fstat(fd, &statf);
    317             if( !r && (statf.st_mode & S_IFREG)
    318                 && (lseek(fd,0,SEEK_END) > logFileSize) ) {
    319                 if(logFileRotate > 0) {
    320                     int i;
    321                     char oldFile[(strlen(logFilePath)+4)], newFile[(strlen(logFilePath)+4)];
    322                     for(i=logFileRotate-1;i>0;i--) {
    323                         sprintf(oldFile, "%s.%d", logFilePath, i-1);
    324                         sprintf(newFile, "%s.%d", logFilePath, i);
    325                         rename(oldFile, newFile);
    326                     }
    327                     sprintf(newFile, "%s.%d", logFilePath, 0);
    328                     fl.l_type = F_UNLCK;
    329                     fcntl (fd, F_SETLKW, &fl);
    330                     close(fd);
    331                     rename(logFilePath, newFile);
    332                     fd = device_open (logFilePath,
    333                            O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND |
    334                            O_NONBLOCK);
    335                     fl.l_type = F_WRLCK;
    336                     fcntl (fd, F_SETLKW, &fl);
    337                 } else {
    338                     ftruncate( fd, 0 );
     323    fl.l_type = F_WRLCK;
     324    fcntl(G.logFD, F_SETLKW, &fl);
     325
     326#if ENABLE_FEATURE_ROTATE_LOGFILE
     327    if (G.logFileSize && G.isRegular && G.curFileSize > G.logFileSize) {
     328        if (G.logFileRotate) { /* always 0..99 */
     329            int i = strlen(G.logFilePath) + 3 + 1;
     330            char oldFile[i];
     331            char newFile[i];
     332            i = G.logFileRotate - 1;
     333            /* rename: f.8 -> f.9; f.7 -> f.8; ... */
     334            while (1) {
     335                sprintf(newFile, "%s.%d", G.logFilePath, i);
     336                if (i == 0) break;
     337                sprintf(oldFile, "%s.%d", G.logFilePath, --i);
     338                rename(oldFile, newFile);
     339            }
     340            /* newFile == "f.0" now */
     341            rename(G.logFilePath, newFile);
     342            fl.l_type = F_UNLCK;
     343            fcntl(G.logFD, F_SETLKW, &fl);
     344            close(G.logFD);
     345            goto reopen;
     346        }
     347        ftruncate(G.logFD, 0);
     348    }
     349    G.curFileSize +=
     350#endif
     351                    full_write(G.logFD, msg, len);
     352    fl.l_type = F_UNLCK;
     353    fcntl(G.logFD, F_SETLKW, &fl);
     354}
     355
     356static void parse_fac_prio_20(int pri, char *res20)
     357{
     358    const CODE *c_pri, *c_fac;
     359
     360    if (pri != 0) {
     361        c_fac = facilitynames;
     362        while (c_fac->c_name) {
     363            if (c_fac->c_val != (LOG_FAC(pri) << 3)) {
     364                c_fac++; continue;
     365            }
     366            /* facility is found, look for prio */
     367            c_pri = prioritynames;
     368            while (c_pri->c_name) {
     369                if (c_pri->c_val != LOG_PRI(pri)) {
     370                    c_pri++; continue;
    339371                }
    340             }
    341         }
    342 #endif
    343         va_start(arguments, fmt);
    344         vdprintf(fd, fmt, arguments);
    345         va_end(arguments);
    346         fl.l_type = F_UNLCK;
    347         fcntl(fd, F_SETLKW, &fl);
    348         close(fd);
    349     } else {
    350         /* Always send console messages to /dev/console so people will see them. */
    351         if ((fd = device_open(_PATH_CONSOLE,
    352                          O_WRONLY | O_NOCTTY | O_NONBLOCK)) >= 0) {
    353             va_start(arguments, fmt);
    354             vdprintf(fd, fmt, arguments);
    355             va_end(arguments);
    356             close(fd);
    357         } else {
    358             fprintf(stderr, "Bummer, can't print: ");
    359             va_start(arguments, fmt);
    360             vfprintf(stderr, fmt, arguments);
    361             fflush(stderr);
    362             va_end(arguments);
    363         }
    364     }
    365 }
    366 
    367 #ifdef CONFIG_FEATURE_REMOTE_LOG
    368 static void init_RemoteLog(void)
    369 {
    370     memset(&remoteaddr, 0, sizeof(remoteaddr));
    371     remotefd = bb_xsocket(AF_INET, SOCK_DGRAM, 0);
    372     remoteaddr.sin_family = AF_INET;
    373     remoteaddr.sin_addr = *(struct in_addr *) *(xgethostbyname(RemoteHost))->h_addr_list;
    374     remoteaddr.sin_port = htons(RemotePort);
    375 }
    376 #endif
    377 
    378 static void logMessage(int pri, char *msg)
    379 {
    380     time_t now;
     372                snprintf(res20, 20, "%s.%s",
     373                        c_fac->c_name, c_pri->c_name);
     374                return;
     375            }
     376            /* prio not found, bail out */
     377            break;
     378        }
     379        snprintf(res20, 20, "<%d>", pri);
     380    }
     381}
     382
     383/* 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. */
     386static void timestamp_and_log(int pri, char *msg, int len)
     387{
    381388    char *timestamp;
    382     static char res[20];
    383 #ifdef CONFIG_FEATURE_REMOTE_LOG
    384     static char line[MAXLINE + 1];
    385 #endif
    386     CODE *c_pri, *c_fac;
    387 
    388     if (pri != 0) {
    389         for (c_fac = facilitynames;
    390              c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri) << 3); c_fac++);
    391         for (c_pri = prioritynames;
    392              c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++);
    393         if (c_fac->c_name == NULL || c_pri->c_name == NULL) {
    394             snprintf(res, sizeof(res), "<%d>", pri);
    395         } else {
    396             snprintf(res, sizeof(res), "%s.%s", c_fac->c_name, c_pri->c_name);
    397         }
    398     }
    399 
    400     if (strlen(msg) < 16 || msg[3] != ' ' || msg[6] != ' ' ||
    401         msg[9] != ':' || msg[12] != ':' || msg[15] != ' ') {
     389
     390    if (len < 16 || msg[3] != ' ' || msg[6] != ' '
     391     || msg[9] != ':' || msg[12] != ':' || msg[15] != ' '
     392    ) {
     393        time_t now;
    402394        time(&now);
    403395        timestamp = ctime(&now) + 4;
    404         timestamp[15] = '\0';
    405396    } else {
    406397        timestamp = msg;
    407         timestamp[15] = '\0';
    408398        msg += 16;
    409399    }
    410 
    411     /* todo: supress duplicates */
    412 
    413 #ifdef CONFIG_FEATURE_REMOTE_LOG
    414     if (doRemoteLog == TRUE) {
    415         /* trying connect the socket */
    416         if (-1 == remotefd) {
    417             init_RemoteLog();
    418         }
    419 
    420         /* if we have a valid socket, send the message */
    421         if (-1 != remotefd) {
    422             now = 1;
    423             snprintf(line, sizeof(line), "<%d>%s", pri, msg);
    424 
    425         retry:
    426             /* send message to remote logger */
    427             if(( -1 == sendto(remotefd, line, strlen(line), 0,
    428                             (struct sockaddr *) &remoteaddr,
    429                             sizeof(remoteaddr))) && (errno == EINTR)) {
    430                 /* sleep now seconds and retry (with now * 2) */
    431                 sleep(now);
    432                 now *= 2;
    433                 goto retry;
    434             }
    435         }
    436     }
    437 
    438     if (local_logging == TRUE)
    439 #endif
    440     {
    441         /* now spew out the message to wherever it is supposed to go */
    442         if (small)
    443             message("%s %s\n", timestamp, msg);
    444         else
    445             message("%s %s %s %s\n", timestamp, LocalHostName, res, msg);
     400    timestamp[15] = '\0';
     401
     402    /* 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
     417static void split_escape_and_log(char *tmpbuf, int len)
     418{
     419    char *p = tmpbuf;
     420
     421    tmpbuf += len;
     422    while (p < tmpbuf) {
     423        char c;
     424        char *q = G.parsebuf;
     425        int pri = (LOG_USER | LOG_NOTICE);
     426
     427        if (*p == '<') {
     428            /* Parse the magic priority number */
     429            pri = bb_strtou(p + 1, &p, 10);
     430            if (*p == '>') p++;
     431            if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
     432                pri = (LOG_USER | LOG_NOTICE);
     433            }
     434        }
     435
     436        while ((c = *p++)) {
     437            if (c == '\n')
     438                c = ' ';
     439            if (!(c & ~0x1f) && c != '\t') {
     440                *q++ = '^';
     441                c += '@'; /* ^@, ^A, ^B... */
     442            }
     443            *q++ = c;
     444        }
     445        *q = '\0';
     446        /* Now log it */
     447        timestamp_and_log(pri, G.parsebuf, q - G.parsebuf);
    446448    }
    447449}
     
    449451static void quit_signal(int sig)
    450452{
    451     logMessage(LOG_SYSLOG | LOG_INFO, "System log daemon exiting.");
    452     unlink(lfile);
    453 #ifdef CONFIG_FEATURE_IPC_SYSLOG
    454     ipcsyslog_cleanup();
    455 #endif
    456 
    457     exit(TRUE);
    458 }
    459 
    460 static void domark(int sig)
    461 {
    462     if (MarkInterval > 0) {
    463         logMessage(LOG_SYSLOG | LOG_INFO, "-- MARK --");
    464         alarm(MarkInterval);
    465     }
    466 }
    467 
    468 /* This must be a #define, since when CONFIG_DEBUG and BUFFERS_GO_IN_BSS are
    469  * enabled, we otherwise get a "storage size isn't constant error. */
    470 static int serveConnection(char *tmpbuf, int n_read)
    471 {
    472     char *p = tmpbuf;
    473 
    474     while (p < tmpbuf + n_read) {
    475 
    476         int pri = (LOG_USER | LOG_NOTICE);
    477         int num_lt = 0;
    478         char line[MAXLINE + 1];
    479         unsigned char c;
    480         char *q = line;
    481 
    482         while ((c = *p) && q < &line[sizeof(line) - 1]) {
    483             if (c == '<' && num_lt == 0) {
    484                 /* Parse the magic priority number. */
    485                 num_lt++;
    486                 pri = 0;
    487                 while (isdigit(*(++p))) {
    488                     pri = 10 * pri + (*p - '0');
    489                 }
    490                 if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
    491                     pri = (LOG_USER | LOG_NOTICE);
    492                 }
    493             } else if (c == '\n') {
    494                 *q++ = ' ';
    495             } else if (iscntrl(c) && (c < 0177)) {
    496                 *q++ = '^';
    497                 *q++ = c ^ 0100;
    498             } else {
    499                 *q++ = c;
    500             }
    501             p++;
    502         }
    503         *q = '\0';
    504         p++;
    505         /* Now log it */
    506         logMessage(pri, line);
    507     }
    508     return n_read;
    509 }
    510 
    511 static void doSyslogd(void) ATTRIBUTE_NORETURN;
    512 static void doSyslogd(void)
     453    timestamp_and_log(LOG_SYSLOG | LOG_INFO, (char*)"syslogd exiting", 0);
     454    puts("syslogd exiting");
     455    if (ENABLE_FEATURE_IPC_SYSLOG)
     456        ipcsyslog_cleanup();
     457    exit(1);
     458}
     459
     460#ifdef SYSLOGD_MARK
     461static 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
     470static void do_syslogd(void) ATTRIBUTE_NORETURN;
     471static void do_syslogd(void)
    513472{
    514473    struct sockaddr_un sunx;
    515     socklen_t addrLength;
    516 
    517474    int sock_fd;
    518475    fd_set fds;
    519 
    520     /* Set up signal handlers. */
     476    char *dev_log_name;
     477
     478    /* Set up signal handlers */
    521479    signal(SIGINT, quit_signal);
    522480    signal(SIGTERM, quit_signal);
     
    527485    signal(SIGCLD, SIG_IGN);
    528486#endif
    529     signal(SIGALRM, domark);
    530     alarm(MarkInterval);
    531 
    532     /* Create the syslog file so realpath() can work. */
    533     if (realpath(_PATH_LOG, lfile) != NULL) {
    534         unlink(lfile);
    535     }
     487#ifdef SYSLOGD_MARK
     488    signal(SIGALRM, do_mark);
     489    alarm(G.markInterval);
     490#endif
     491    remove_pidfile("/var/run/syslogd.pid");
    536492
    537493    memset(&sunx, 0, sizeof(sunx));
    538494    sunx.sun_family = AF_UNIX;
    539     strncpy(sunx.sun_path, lfile, sizeof(sunx.sun_path));
    540     sock_fd = bb_xsocket(AF_UNIX, SOCK_DGRAM, 0);
    541     addrLength = sizeof(sunx.sun_family) + strlen(sunx.sun_path);
    542     if (bind(sock_fd, (struct sockaddr *) &sunx, addrLength) < 0) {
    543         bb_perror_msg_and_die("Could not connect to socket " _PATH_LOG);
    544     }
    545 
    546     if (chmod(lfile, 0666) < 0) {
    547         bb_perror_msg_and_die("Could not set permission on " _PATH_LOG);
    548     }
    549 #ifdef CONFIG_FEATURE_IPC_SYSLOG
    550     if (circular_logging == TRUE) {
     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)) {
    551522        ipcsyslog_init();
    552523    }
    553 #endif
    554 
    555 #ifdef CONFIG_FEATURE_REMOTE_LOG
    556     if (doRemoteLog == TRUE) {
    557         init_RemoteLog();
    558     }
    559 #endif
    560 
    561     logMessage(LOG_SYSLOG | LOG_INFO, "syslogd started: " "BusyBox v" BB_VER );
     524
     525    timestamp_and_log(LOG_SYSLOG | LOG_INFO,
     526            (char*)"syslogd started: BusyBox v" BB_VER, 0);
    562527
    563528    for (;;) {
    564 
    565529        FD_ZERO(&fds);
    566530        FD_SET(sock_fd, &fds);
     
    568532        if (select(sock_fd + 1, &fds, NULL, NULL, NULL) < 0) {
    569533            if (errno == EINTR) {
    570                 /* alarm may have happened. */
     534                /* alarm may have happened */
    571535                continue;
    572536            }
    573             bb_perror_msg_and_die("select error");
     537            bb_perror_msg_and_die("select");
    574538        }
    575539
    576540        if (FD_ISSET(sock_fd, &fds)) {
    577541            int i;
    578 #if MAXLINE > BUFSIZ
    579 # define TMP_BUF_SZ BUFSIZ
    580 #else
    581 # define TMP_BUF_SZ MAXLINE
    582 #endif
    583 #define tmpbuf bb_common_bufsiz1
    584 
    585             if ((i = recv(sock_fd, tmpbuf, TMP_BUF_SZ, 0)) > 0) {
    586                 tmpbuf[i] = '\0';
    587                 serveConnection(tmpbuf, i);
    588             } else {
     542            i = recv(sock_fd, G.recvbuf, MAX_READ - 1, 0);
     543            if (i <= 0)
    589544                bb_perror_msg_and_die("UNIX socket error");
    590             }
    591         }               /* FD_ISSET() */
    592     }                   /* for main loop */
    593 }
    594 
     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
     566int syslogd_main(int argc, char **argv);
    595567int syslogd_main(int argc, char **argv)
    596568{
    597     int opt;
    598 
    599     int doFork = TRUE;
    600 
     569    char OPTION_DECL;
    601570    char *p;
    602571
     572    PTR_TO_GLOBALS = memcpy(xzalloc(sizeof(G)), &init_data, sizeof(init_data));
     573
    603574    /* do normal option parsing */
    604     while ((opt = getopt(argc, argv, "m:nO:s:Sb:R:LC::")) > 0) {
    605         switch (opt) {
    606         case 'm':
    607             MarkInterval = atoi(optarg) * 60;
    608             break;
    609         case 'n':
    610             doFork = FALSE;
    611             break;
    612         case 'O':
    613             logFilePath = optarg;
    614             break;
    615 #ifdef CONFIG_FEATURE_ROTATE_LOGFILE
    616         case 's':
    617             logFileSize = atoi(optarg) * 1024;
    618             break;
    619         case 'b':
    620             logFileRotate = atoi(optarg);
    621             if( logFileRotate > 99 ) logFileRotate = 99;
    622             break;
    623 #endif
    624 #ifdef CONFIG_FEATURE_REMOTE_LOG
    625         case 'R':
    626             RemoteHost = bb_xstrdup(optarg);
    627             if ((p = strchr(RemoteHost, ':'))) {
    628                 RemotePort = atoi(p + 1);
    629                 *p = '\0';
    630             }
    631             doRemoteLog = TRUE;
    632             break;
    633         case 'L':
    634             local_logging = TRUE;
    635             break;
    636 #endif
    637 #ifdef CONFIG_FEATURE_IPC_SYSLOG
    638         case 'C':
    639             if (optarg) {
    640                 int buf_size = atoi(optarg);
    641                 if (buf_size >= 4) {
    642                     shm_size = buf_size * 1024;
    643                 }
    644             }
    645             circular_logging = TRUE;
    646             break;
    647 #endif
    648         case 'S':
    649             small = true;
    650             break;
    651         default:
    652             bb_show_usage();
    653         }
    654     }
    655 
    656 #ifdef CONFIG_FEATURE_REMOTE_LOG
     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
     579        G.markInterval = xatou_range(opt_m, 0, INT_MAX/60) * 60;
     580#endif
     581    //if (option_mask32 & OPT_nofork) // -n
     582    //if (option_mask32 & OPT_outfile) // -O
     583    if (option_mask32 & OPT_loglevel) // -l
     584        G.logLevel = xatou_range(opt_l, 1, 8);
     585    //if (option_mask32 & OPT_small) // -S
     586#if ENABLE_FEATURE_ROTATE_LOGFILE
     587    if (option_mask32 & OPT_filesize) // -s
     588        G.logFileSize = xatou_range(opt_s, 0, INT_MAX/1024) * 1024;
     589    if (option_mask32 & OPT_rotatecnt) // -b
     590        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
     597#endif
     598#if ENABLE_FEATURE_IPC_SYSLOG
     599    if (opt_C) // -Cn
     600        G.shm_size = xatoul_range(opt_C, 4, INT_MAX/1024) * 1024;
     601#endif
     602
    657603    /* If they have not specified remote logging, then log locally */
    658     if (doRemoteLog == FALSE)
    659         local_logging = TRUE;
    660 #endif
    661 
     604    if (ENABLE_FEATURE_REMOTE_LOG && !(option_mask32 & OPT_remotelog))
     605        option_mask32 |= OPT_locallog;
    662606
    663607    /* Store away localhost's name before the fork */
    664     gethostname(LocalHostName, sizeof(LocalHostName));
    665     if ((p = strchr(LocalHostName, '.'))) {
     608    gethostname(G.localHostName, sizeof(G.localHostName));
     609    p = strchr(G.localHostName, '.');
     610    if (p) {
    666611        *p = '\0';
    667612    }
    668613
     614    if (!(option_mask32 & OPT_nofork)) {
     615        bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
     616    }
    669617    umask(0);
    670 
    671     if (doFork == TRUE) {
    672 #ifdef BB_NOMMU
    673         vfork_daemon_rexec(0, 1, argc, argv, "-n");
    674 #else
    675         bb_xdaemon(0, 1);
    676 #endif
    677     }
    678     doSyslogd();
    679 
    680     return EXIT_SUCCESS;
    681 }
     618    write_pidfile("/var/run/syslogd.pid");
     619    do_syslogd();
     620    /* return EXIT_SUCCESS; */
     621}
Note: See TracChangeset for help on using the changeset viewer.