2
* \brief This is the main file of the rsyslogd daemon.
4
* Please visit the rsyslog project at
6
* http://www.rsyslog.com
8
* to learn more about it and discuss any questions you may have.
10
* Please note that as of now, a lot of the code in this file stems
11
* from the sysklogd project. To learn more over this project, please
14
* http://www.infodrom.org/projects/sysklogd/
16
* I would like to express my thanks to the developers of the sysklogd
17
* package - without it, I would have had a much harder start...
19
* Please note that I made quite some changes to the orignal package.
20
* I expect to do even more changes - up
21
* to a full rewrite - to meet my design goals, which among others
22
* contain a (at least) dual-thread design with a memory buffer for
23
* storing received bursts of data. This is also the reason why I
24
* kind of "forked" a completely new branch of the package. My intension
25
* is to do many changes and only this initial release will look
26
* similar to sysklogd (well, one never knows...).
28
* As I have made a lot of modifications, please assume that all bugs
29
* in this package are mine and not those of the sysklogd team.
31
* As of this writing, there already exist heavy
32
* modifications to the orginal sysklogd package. I suggest to no
33
* longer rely too much on code knowledge you eventually have with
34
* sysklogd - rgerhards 2005-07-05
35
* The code is now almost completely different. Be careful!
36
* rgerhards, 2006-11-30
38
* I have decided to put my code under the GPL. The sysklog package
39
* is distributed under the BSD license. As such, this package here
40
* currently comes with two licenses. Both are given below. As it is
41
* probably hard for you to see what was part of the sysklogd package
42
* and what is part of my code, I suggest that you visit the
43
* sysklogd site on the URL above if you would like to base your
44
* development on a version that is not under the GPL.
46
* This Project was intiated and is maintained by
47
* Rainer Gerhards <rgerhards@hq.adiscon.com>. See
48
* AUTHORS to learn who helped make it become a reality.
50
* If you have questions about rsyslogd in general, please email
51
* info@adiscon.com. To learn more about rsyslogd, please visit
52
* http://www.rsyslog.com.
54
* \author Rainer Gerhards <rgerhards@adiscon.com>
56
* Some initial modifications on the sysklogd package to support
57
* liblogging. These have actually not yet been merged to the
58
* source you see currently (but they hopefully will)
61
* Restarted the modifications of sysklogd. This time, we
62
* focus on a simpler approach first. The initial goal is to
63
* provide MySQL database support (so that syslogd can log
66
* rsyslog - An Enhanced syslogd Replacement.
67
* Copyright 2003-2007 Rainer Gerhards and Adiscon GmbH.
69
* This program is free software; you can redistribute it and/or
70
* modify it under the terms of the GNU General Public License
71
* as published by the Free Software Foundation; either version 2
72
* of the License, or (at your option) any later version.
74
* This program is distributed in the hope that it will be useful,
75
* but WITHOUT ANY WARRANTY; without even the implied warranty of
76
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
77
* GNU General Public License for more details.
79
* You should have received a copy of the GNU General Public License
80
* along with this program; if not, write to the Free Software
81
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
83
* A copy of the GPL can be found in the file "COPYING" in this distribution.
92
/* change the following setting to e.g. 32768 if you would like to
93
* support large message sizes for IHE (32k is the current maximum
94
* needed for IHE). I was initially tempted to increase it to 32k,
95
* but there is a large memory footprint with the current
96
* implementation in rsyslog. This will change as the processing
97
* changes, but I have re-set it to 1k, because the vast majority
98
* of messages is below that and the memory savings is huge, at
99
* least compared to the overall memory footprint.
101
* If you intend to receive Windows Event Log data (e.g. via
102
* EventReporter - www.eventreporter.com), you might want to
103
* increase this number to an even higher value, as event
104
* log messages can be very lengthy.
105
* rgerhards, 2005-07-05
107
* during my recent testing, it showed that 4k seems to be
108
* the typical maximum for UDP based syslog. This is a IP stack
109
* restriction. Not always ... but very often. If you go beyond
110
* that value, be sure to test that rsyslogd actually does what
111
* you think it should do ;) Also, it is a good idea to check the
112
* doc set for anything on IHE - it most probably has information on
114
* rgerhards, 2005-08-05
116
* I have increased the default message size to 2048 to be in sync
117
* with recent IETF syslog standardization efforts.
118
* rgerhards, 2006-11-30
120
* I have removed syslogdPanic(). That function was supposed to be used
121
* for logging in low-memory conditons. Ever since it was introduced, it
122
* was a wrapper for dbgprintf(). A more intelligent choice was hard to
123
* find. After all, if we are short on memory, doing anything fance will
124
* again cause memory problems. I have now modified the code so that
125
* those elements for which we do not get memory are simply discarded.
126
* That might be a single property like the TAG, but it might also be
127
* a complete message. The overall goal of this code change is to keep
128
* rsyslogd up and running, while we sacrifice some messages to reach
129
* that goal. It also keeps the code cleaner. A real out of memory
130
* condition is highly unlikely. If it happens, there will probably be
131
* much more trouble on the system in question. Anyhow - rsyslogd will
132
* most probably be able to survive it and carry on with processing
133
* once the situation has been resolved.
135
#define DEFUPRI (LOG_USER|LOG_NOTICE)
136
#define DEFSPRI (LOG_KERN|LOG_CRIT)
137
#define TIMERINTVL 30 /* interval for checking flush, mark */
139
#define CONT_LINE 1 /* Allow continuation lines */
155
#include <sys/syslog.h>
156
#include <sys/param.h>
160
#include <sys/errno.h>
162
#include <sys/ioctl.h>
163
#include <sys/wait.h>
164
#include <sys/socket.h>
165
#include <sys/file.h>
167
#include <sys/time.h>
169
# include <sys/timespec.h>
171
#include <sys/resource.h>
174
#include <netinet/in.h>
181
#include <arpa/nameser.h>
182
#include <arpa/inet.h>
197
/* handle some defines missing on more than one platform */
199
#define SUN_LEN(su) \
200
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
204
#include "stringbuf.h"
205
#include "syslogd-types.h"
206
#include "template.h"
207
#include "outchannel.h"
209
#include "net.h" /* struct NetAddr */
215
#include "tcpsyslog.h"
216
#include "iminternal.h"
217
#include "cfsysline.h"
219
#include "omusrmsg.h"
222
#include "omdiscard.h"
224
/* We define our own set of syslog defintions so that we
225
* do not need to rely on (possibly different) implementations.
226
* 2007-07-19 rgerhards
228
/* missing definitions for solaris
232
# define LOG_AUTHPRIV LOG_AUTH
234
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
235
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
236
#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
237
#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */
238
#define LOG_FTP (11<<3) /* ftp daemon */
239
#define INTERNAL_MARK LOG_MAKEPRI((LOG_NFACILITIES<<3), 0)
241
syslogCODE rs_prioritynames[] =
243
{ "alert", LOG_ALERT },
244
{ "crit", LOG_CRIT },
245
{ "debug", LOG_DEBUG },
246
{ "emerg", LOG_EMERG },
248
{ "error", LOG_ERR }, /* DEPRECATED */
249
{ "info", LOG_INFO },
250
{ "none", INTERNAL_NOPRI }, /* INTERNAL */
251
{ "notice", LOG_NOTICE },
252
{ "panic", LOG_EMERG }, /* DEPRECATED */
253
{ "warn", LOG_WARNING }, /* DEPRECATED */
254
{ "warning", LOG_WARNING },
258
syslogCODE rs_facilitynames[] =
260
{ "auth", LOG_AUTH },
261
{ "authpriv", LOG_AUTHPRIV },
262
{ "cron", LOG_CRON },
263
{ "daemon", LOG_DAEMON },
265
{ "kern", LOG_KERN },
267
{ "mail", LOG_MAIL },
268
{ "mark", INTERNAL_MARK }, /* INTERNAL */
269
{ "news", LOG_NEWS },
270
{ "security", LOG_AUTH }, /* DEPRECATED */
271
{ "syslog", LOG_SYSLOG },
272
{ "user", LOG_USER },
273
{ "uucp", LOG_UUCP },
274
{ "local0", LOG_LOCAL0 },
275
{ "local1", LOG_LOCAL1 },
276
{ "local2", LOG_LOCAL2 },
277
{ "local3", LOG_LOCAL3 },
278
{ "local4", LOG_LOCAL4 },
279
{ "local5", LOG_LOCAL5 },
280
{ "local6", LOG_LOCAL6 },
281
{ "local7", LOG_LOCAL7 },
288
#define UTMP_FILE UTMP_FILENAME
291
#define UTMP_FILE _PATH_UTMP
293
#define UTMP_FILE "/etc/utmp"
298
#ifndef _PATH_LOGCONF
299
#define _PATH_LOGCONF "/etc/rsyslog.conf"
303
#define _PATH_MODDIR "/lib/rsyslog/"
306
#if defined(SYSLOGD_PIDNAME)
310
#define _PATH_VARRUN "/var/run/"
313
#define _PATH_VARRUN "/var/run/"
315
#define _PATH_LOGPID _PATH_VARRUN SYSLOGD_PIDNAME
317
#define _PATH_LOGPID "/etc/" SYSLOGD_PIDNAME
322
#define _PATH_LOGPID _PATH_VARRUN "rsyslogd.pid"
324
#define _PATH_LOGPID "/etc/rsyslogd.pid"
330
#define _PATH_DEV "/dev/"
333
#ifndef _PATH_CONSOLE
334
#define _PATH_CONSOLE "/dev/console"
338
#define _PATH_TTY "/dev/tty"
343
#define _PATH_LOG "/var/run/log"
345
#define _PATH_LOG "/dev/log"
350
/* IPv6 compatibility layer for older platforms
351
* We need to handle a few things different if we are running
352
* on an older platform which does not support all the glory
353
* of IPv6. We try to limit toll on features and reliability,
354
* but obviously it is better to run rsyslog on a platform that
355
* supports everything...
356
* rgerhards, 2007-06-22
358
#ifndef AI_NUMERICSERV
359
# define AI_NUMERICSERV 0
363
static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */
364
static char *PidFile = _PATH_LOGPID; /* read-only after startup */
365
static uchar *pModDir = NULL; /* read-only after startup */
366
char ctty[] = _PATH_CONSOLE; /* this is read-only */
368
static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */
369
/* mypid is read-only after the initial fork() */
370
static int debugging_on = 0; /* read-only, except on sig USR1 */
371
static int restart = 0; /* do restart (config read) - multithread safe */
373
static int bRequestDoMark = 0; /* do mark processing? (multithread safe) */
376
int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */
377
int startIndexUxLocalSockets = 0; /* process funix from that index on (used to
378
* suppress local logging. rgerhards 2005-08-01
379
* read-only after startup
381
int funixParseHost[MAXFUNIX] = { 0, }; /* should parser parse host name? read-only after startup */
382
char *funixn[MAXFUNIX] = { _PATH_LOG }; /* read-only after startup */
383
int funix[MAXFUNIX] = { -1, }; /* read-only after startup */
385
#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */
386
#define TABLE_NOPRI 0 /* Value to indicate no priority in f_pmask */
387
#define TABLE_ALLPRI 0xFF /* Value to indicate all priorities in f_pmask */
388
#define LOG_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) /* mark "facility" */
390
/* definitions used for doNameLine to differentiate between different command types
391
* (with otherwise identical code). This is a left-over from the previous config
392
* system. It stays, because it is still useful. So do not wonder why it looks
393
* somewhat strange (at least its name). -- rgerhards, 2007-08-01
395
enum eDirective { DIR_TEMPLATE = 0, DIR_OUTCHANNEL = 1, DIR_ALLOWEDSENDER = 2};
397
/* The following global variables are used for building
398
* tag and host selector lines during startup and config reload.
399
* This is stored as a global variable pool because of its ease. It is
400
* also fairly compatible with multi-threading as the stratup code must
401
* be run in a single thread anyways. So there can be no race conditions. These
402
* variables are no longer used once the configuration has been loaded (except,
403
* of course, during a reload). rgerhards 2005-10-18
405
static EHostnameCmpMode eDfltHostnameCmpMode;
406
static rsCStrObj *pDfltHostnameCmp;
407
static rsCStrObj *pDfltProgNameCmp;
409
/* supporting structures for multithreading */
411
/* this is the first approach to a queue, this time with static
418
pthread_mutex_t *mut;
419
pthread_cond_t *notFull, *notEmpty;
422
int iMainMsgQueueSize;
423
int bRunningMultithreaded = 0; /* Is this program running in multithreaded mode? */
424
msgQueue *pMsgQueue = NULL;
425
static pthread_t thrdWorker;
426
static int bGlblDone = 0;
428
/* END supporting structures for multithreading */
430
static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be
431
* parsed inside message - rgerhards, 2006-03-13 */
432
static int bFinished = 0; /* used by termination signal handler, read-only except there
433
* is either 0 or the number of the signal that requested the
438
* Intervals at which we flush out "message repeated" messages,
439
* in seconds after previous message is logged. After each flush,
440
* we move to the next interval until we reach the largest.
442
int repeatinterval[] = { 30, 60 }; /* # of secs before flush */
443
#define MAXREPEAT ((int)((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1))
444
#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])
445
#define BACKOFF(f) { if (++(f)->f_repeatcount > MAXREPEAT) \
446
(f)->f_repeatcount = MAXREPEAT; \
454
struct sockaddr_in su_sin;
455
struct sockaddr_in6 su_sin6;
459
#define LIST_DELIMITER ':' /* delimiter between two hosts */
461
struct filed *Files = NULL; /* read-only after init() (but beware of sigusr1!) */
468
static struct code PriNames[] = {
469
{"alert", LOG_ALERT},
471
{"debug", LOG_DEBUG},
472
{"emerg", LOG_EMERG},
474
{"error", LOG_ERR}, /* DEPRECATED */
476
{"none", INTERNAL_NOPRI}, /* INTERNAL */
477
{"notice", LOG_NOTICE},
478
{"panic", LOG_EMERG}, /* DEPRECATED */
479
{"warn", LOG_WARNING}, /* DEPRECATED */
480
{"warning", LOG_WARNING},
485
static struct code FacNames[] = {
487
{"authpriv", LOG_AUTHPRIV},
489
{"daemon", LOG_DAEMON},
493
{"mark", LOG_MARK}, /* INTERNAL */
495
{"security", LOG_AUTH}, /* DEPRECATED */
496
{"syslog", LOG_SYSLOG},
502
{"local0", LOG_LOCAL0},
503
{"local1", LOG_LOCAL1},
504
{"local2", LOG_LOCAL2},
505
{"local3", LOG_LOCAL3},
506
{"local4", LOG_LOCAL4},
507
{"local5", LOG_LOCAL5},
508
{"local6", LOG_LOCAL6},
509
{"local7", LOG_LOCAL7},
513
static pid_t ppid; /* This is a quick and dirty hack used for spliting main/startup thread */
515
/* global variables for config file state */
516
static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */
517
int Debug; /* debug flag - read-only after startup */
518
static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */
519
static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */
520
static int bDebugPrintModuleList = 1;/* output module list in debug mode? */
521
int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
522
static uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */
523
static int bEscapeCCOnRcv; /* escape control characters on reception: 0 - no, 1 - yes */
524
static int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */
525
static int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */
526
static int logEveryMsg = 0;/* no repeat message processing - read-only after startup
527
* 0 - suppress duplicate messages
528
* 1 - do NOT suppress duplicate messages
530
/* end global config file state variables */
532
static unsigned int Forwarding = 0;
533
static int nfunix = 1; /* number of Unix sockets open / read-only after startup */
534
char LocalHostName[MAXHOSTNAMELEN+1];/* our hostname - read-only after startup */
535
char *LocalDomain; /* our local domain name - read-only after startup */
536
int *finet = NULL; /* Internet datagram sockets, first element is nbr of elements
537
* read-only after init(), but beware of restart! */
538
static char *LogPort = "514"; /* port number for INET connections */
539
static int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */
540
int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */
541
int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */
542
static int MarkSeq = 0; /* mark sequence number - modified in domark() only */
543
static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */
544
static int AcceptRemote = 0;/* receive messages that come via UDP - read-only after startup */
545
int DisableDNS = 0; /* don't look up IP addresses of remote messages */
546
char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */
547
char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */
548
int NoHops = 1; /* Can we bounce syslog messages through an
549
intermediate host. Read-only after startup */
550
static int Initialized = 0; /* set when we have initialized ourselves
551
* rgerhards 2004-11-09: and by initialized, we mean that
552
* the configuration file could be properly read AND the
553
* syslog/udp port could be obtained (the later is debatable).
554
* It is mainly a setting used for emergency logging: if
555
* something really goes wild, we can not do as indicated in
556
* the log file, but we still log messages to the system
557
* console. This is probably the best that can be done in
559
* read-only after startup, but modified during restart
565
/* This structure represents the files that will have log
567
* RGerhards 2004-11-08: Each instance of the filed structure
568
* describes what I call an "output channel". This is important
569
* to mention as we now allow database connections to be
570
* present in the filed structure. If helps immensely, if we
571
* think of it as the abstraction of an output channel.
572
* rgerhards, 2005-10-26: The structure below provides ample
573
* opportunity for non-thread-safety. Each of the variable
574
* accesses must be carefully evaluated, many of them probably
575
* be guarded by mutexes. But beware of deadlocks...
576
* rgerhards, 2007-08-01: as you can see, the structure has shrunk pretty much. I will
577
* remove some of the comments some time. It's still the structure that controls much
578
* of the processing that goes on in syslogd, but it now has lots of helpers.
581
struct filed *f_next; /* next in linked list */
582
/* filter properties */
584
FILTER_PRI = 0, /* traditional PRI based filer */
585
FILTER_PROP = 1 /* extended filter, property based */
587
EHostnameCmpMode eHostnameCmpMode;
588
rsCStrObj *pCSHostnameComp; /* hostname to check */
589
rsCStrObj *pCSProgNameComp; /* tag to check or NULL, if not to be checked */
591
u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */
593
rsCStrObj *pCSPropName;
595
FIOP_NOP = 0, /* do not use - No Operation */
596
FIOP_CONTAINS = 1, /* contains string? */
597
FIOP_ISEQUAL = 2, /* is (exactly) equal? */
598
FIOP_STARTSWITH = 3, /* starts with a string? */
599
FIOP_REGEX = 4 /* matches a regular expression? */
601
rsCStrObj *pCSCompValue; /* value to "compare" against */
602
char isNegated; /* actually a boolean ;) */
606
linkedList_t llActList; /* list of configured actions */
608
typedef struct filed selector_t; /* new type name */
611
/* support for simple textual representation of FIOP names
612
* rgerhards, 2005-09-27
614
static char* getFIOPName(unsigned iFIOP)
624
case FIOP_STARTSWITH:
638
/* Reset config variables to default values.
639
* rgerhards, 2007-07-17
641
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
644
bActExecWhenPrevSusp = 0;
645
bDebugPrintTemplateList = 1;
646
bDebugPrintCfSysLineHandlerList = 1;
647
bDebugPrintModuleList = 1;
648
bEscapeCCOnRcv = 1; /* default is to escape control characters */
649
bReduceRepeatMsgs = (logEveryMsg == 1) ? 0 : 1;
651
if(pModDir != NULL) {
656
iMainMsgQueueSize = 10000;
663
/* support for defining allowed TCP and UDP senders. We use the same
664
* structure to implement this (a linked list), but we define two different
665
* list roots, one for UDP and one for TCP.
666
* rgerhards, 2005-09-26
669
/* All of the five below are read-only after startup */
670
static struct AllowedSenders *pAllowedSenders_UDP = NULL; /* the roots of the allowed sender */
671
struct AllowedSenders *pAllowedSenders_TCP = NULL; /* lists. If NULL, all senders are ok! */
672
static struct AllowedSenders *pLastAllowedSenders_UDP = NULL; /* and now the pointers to the last */
673
static struct AllowedSenders *pLastAllowedSenders_TCP = NULL; /* element in the respective list */
674
#endif /* #ifdef SYSLOG_INET */
676
int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
679
/* hardcoded standard templates (used for defaults) */
680
static uchar template_TraditionalFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\"";
681
static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\"";
682
static uchar template_StdFwdFmt[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%\"";
683
static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\"";
684
static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL";
688
/* up to the next comment, prototypes that should be removed by reordering */
690
static msgQueue *queueInit (void);
691
static void *singleWorker(); /* REMOVEME later 2005-10-24 */
693
/* Function prototypes. */
694
static char **crunch_list(char *list);
695
static void printline(char *hname, char *msg, int iSource);
696
static void logmsg(int pri, msg_t*, int flags);
697
static rsRetVal fprintlog(action_t *pAction);
698
static void reapchild();
699
static void debug_switch();
700
static rsRetVal cfline(uchar *line, selector_t **pfCurr);
701
static int decode(uchar *name, struct code *codetab);
702
static void sighup_handler();
703
static void die(int sig);
704
static void freeSelectors(void);
705
static rsRetVal processConfFile(uchar *pConfFile);
706
static rsRetVal selectorAddList(selector_t *f);
707
static void processImInternal(void);
709
/* Code for handling allowed/disallowed senders
712
static inline void MaskIP6 (struct in6_addr *addr, uint8_t bits) {
715
assert (addr != NULL);
716
assert (bits <= 128);
720
addr->s6_addr32[i++] &= htonl(0xffffffff << (32 - (bits % 32)));
721
for (; i < (sizeof addr->s6_addr32)/4; i++)
722
addr->s6_addr32[i] = 0;
725
static inline void MaskIP4 (struct in_addr *addr, uint8_t bits) {
727
assert (addr != NULL);
730
addr->s_addr &= htonl(0xffffffff << (32 - bits));
733
#define SIN(sa) ((struct sockaddr_in *)(sa))
734
#define SIN6(sa) ((struct sockaddr_in6 *)(sa))
736
/* This function adds an allowed sender entry to the ACL linked list.
737
* In any case, a single entry is added. If an error occurs, the
738
* function does its error reporting itself. All validity checks
739
* must already have been done by the caller.
740
* This is a helper to AddAllowedSender().
741
* rgerhards, 2007-07-17
743
static rsRetVal AddAllowedSenderEntry(struct AllowedSenders **ppRoot, struct AllowedSenders **ppLast,
744
struct NetAddr *iAllow, uint8_t iSignificantBits)
746
struct AllowedSenders *pEntry = NULL;
748
assert(ppRoot != NULL);
749
assert(ppLast != NULL);
750
assert(iAllow != NULL);
752
if((pEntry = (struct AllowedSenders*) calloc(1, sizeof(struct AllowedSenders))) == NULL) {
753
glblHadMemShortage = 1;
754
return RS_RET_OUT_OF_MEMORY; /* no options left :( */
757
memcpy(&(pEntry->allowedSender), iAllow, sizeof (struct NetAddr));
758
pEntry->pNext = NULL;
759
pEntry->SignificantBits = iSignificantBits;
762
if(*ppRoot == NULL) {
765
(*ppLast)->pNext = pEntry;
772
/* function to clear the allowed sender structure in cases where
773
* it must be freed (occurs most often when HUPed.
774
* TODO: reconsider recursive implementation
776
static void clearAllowedSenders (struct AllowedSenders *pAllow) {
777
if (pAllow != NULL) {
778
if (pAllow->pNext != NULL)
779
clearAllowedSenders (pAllow->pNext);
781
if (F_ISSET(pAllow->allowedSender.flags, ADDR_NAME))
782
free (pAllow->allowedSender.addr.HostWildcard);
784
free (pAllow->allowedSender.addr.NetAddr);
791
/* function to add an allowed sender to the allowed sender list. The
792
* root of the list is caller-provided, so it can be used for all
793
* supported lists. The caller must provide a pointer to the root,
794
* as it eventually needs to be updated. Also, a pointer to the
795
* pointer to the last element must be provided (to speed up adding
797
* rgerhards, 2005-09-26
798
* If a hostname is given there are possible multiple entries
799
* added (all addresses from that host).
801
static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedSenders **ppLast,
802
struct NetAddr *iAllow, uint8_t iSignificantBits)
806
assert(ppRoot != NULL);
807
assert(ppLast != NULL);
808
assert(iAllow != NULL);
810
if (!F_ISSET(iAllow->flags, ADDR_NAME)) {
811
if(iSignificantBits == 0)
812
/* we handle this seperatly just to provide a better
815
logerror("You can not specify 0 bits of the netmask, this would "
816
"match ALL systems. If you really intend to do that, "
817
"remove all $AllowedSender directives.");
819
switch (iAllow->addr.NetAddr->sa_family) {
821
if((iSignificantBits < 1) || (iSignificantBits > 32)) {
822
logerrorInt("Invalid bit number in IPv4 address - adjusted to 32",
823
(int)iSignificantBits);
824
iSignificantBits = 32;
827
MaskIP4 (&(SIN(iAllow->addr.NetAddr)->sin_addr), iSignificantBits);
830
if((iSignificantBits < 1) || (iSignificantBits > 128)) {
831
logerrorInt("Invalid bit number in IPv6 address - adjusted to 128",
833
iSignificantBits = 128;
836
MaskIP6 (&(SIN6(iAllow->addr.NetAddr)->sin6_addr), iSignificantBits);
839
/* rgerhards, 2007-07-16: We have an internal program error in this
840
* case. However, there is not much we can do against it right now. Of
841
* course, we could abort, but that would probably cause more harm
842
* than good. So we continue to run. We simply do not add this line - the
843
* worst thing that happens is that one host will not be allowed to
846
logerrorInt("Internal error caused AllowedSender to be ignored, AF = %d",
847
iAllow->addr.NetAddr->sa_family);
850
/* OK, entry constructed, now lets add it to the ACL list */
851
iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits);
853
/* we need to process a hostname ACL */
855
logerror ("Ignoring hostname based ACLs because DNS is disabled.");
859
if (!strchr (iAllow->addr.HostWildcard, '*') &&
860
!strchr (iAllow->addr.HostWildcard, '?')) {
861
/* single host - in this case, we pull its IP addresses from DNS
862
* and add IP-based ACLs.
864
struct addrinfo hints, *res, *restmp;
865
struct NetAddr allowIP;
867
memset (&hints, 0, sizeof (struct addrinfo));
868
hints.ai_family = AF_UNSPEC;
869
hints.ai_flags = AI_ADDRCONFIG;
870
hints.ai_socktype = SOCK_DGRAM;
872
if (getaddrinfo (iAllow->addr.HostWildcard, NULL, &hints, &res) != 0) {
873
logerrorSz("DNS error: Can't resolve \"%s\", not added as allowed sender", iAllow->addr.HostWildcard);
874
/* We could use the text name in this case - maybe this could become
875
* a user-defined option at some stage.
880
for (restmp = res ; res != NULL ; res = res->ai_next) {
881
switch (res->ai_family) {
882
case AF_INET: /* add IPv4 */
883
iSignificantBits = 32;
885
if((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) {
886
glblHadMemShortage = 1;
887
return RS_RET_OUT_OF_MEMORY;
889
memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen);
891
if((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP, iSignificantBits))
895
case AF_INET6: /* IPv6 - but need to check if it is a v6-mapped IPv4 */
896
if(IN6_IS_ADDR_V4MAPPED (&SIN6(res->ai_addr)->sin6_addr)) {
897
/* extract & add IPv4 */
899
iSignificantBits = 32;
901
if((allowIP.addr.NetAddr = malloc(sizeof(struct sockaddr_in)))
903
glblHadMemShortage = 1;
904
return RS_RET_OUT_OF_MEMORY;
906
SIN(allowIP.addr.NetAddr)->sin_family = AF_INET;
907
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
908
SIN(allowIP.addr.NetAddr)->sin_len = sizeof (struct sockaddr_in);
910
SIN(allowIP.addr.NetAddr)->sin_port = 0;
911
memcpy(&(SIN(allowIP.addr.NetAddr)->sin_addr.s_addr),
912
&(SIN6(res->ai_addr)->sin6_addr.s6_addr32[3]),
913
sizeof (struct sockaddr_in));
915
if((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP,
920
/* finally add IPv6 */
922
iSignificantBits = 128;
924
if((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) {
925
glblHadMemShortage = 1;
926
return RS_RET_OUT_OF_MEMORY;
928
memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen);
930
if((iRet = AddAllowedSenderEntry(ppRoot, ppLast, &allowIP,
938
freeaddrinfo (restmp);
940
/* wildcards in hostname - we need to add a text-based ACL.
941
* For this, we already have everything ready and just need
942
* to pass it along...
944
iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits);
950
#endif /* #ifdef SYSLOG_INET */
954
/* Print an allowed sender list. The caller must tell us which one.
955
* iListToPrint = 1 means UDP, 2 means TCP
956
* rgerhards, 2005-09-27
958
static void PrintAllowedSenders(int iListToPrint)
960
struct AllowedSenders *pSender;
963
assert((iListToPrint == 1) || (iListToPrint == 2));
965
printf("\nAllowed %s Senders:\n",
966
(iListToPrint == 1) ? "UDP" : "TCP");
967
pSender = (iListToPrint == 1) ?
968
pAllowedSenders_UDP : pAllowedSenders_TCP;
969
if(pSender == NULL) {
970
printf("\tNo restrictions set.\n");
972
while(pSender != NULL) {
973
if (F_ISSET(pSender->allowedSender.flags, ADDR_NAME))
974
printf ("\t%s\n", pSender->allowedSender.addr.HostWildcard);
976
if(getnameinfo (pSender->allowedSender.addr.NetAddr,
977
SALEN(pSender->allowedSender.addr.NetAddr),
978
(char*)szIP, 64, NULL, 0, NI_NUMERICHOST) == 0) {
979
printf ("\t%s/%u\n", szIP, pSender->SignificantBits);
981
/* getnameinfo() failed - but as this is only a
982
* debug function, we simply spit out an error and do
983
* not care much about it.
985
dbgprintf("\tERROR in getnameinfo() - something may be wrong "
986
"- ignored for now\n");
989
pSender = pSender->pNext;
995
/* compares a host to an allowed sender list entry. Handles all subleties
996
* including IPv4/v6 as well as domain name wildcards.
997
* This is a helper to isAllowedSender. As it is only called once, it is
999
* Returns 0 if they do not match, something else otherwise.
1000
* contributed 1007-07-16 by mildew@gmail.com
1002
static inline int MaskCmp(struct NetAddr *pAllow, uint8_t bits, struct sockaddr *pFrom, const char *pszFromHost)
1004
assert(pAllow != NULL);
1005
assert(pFrom != NULL);
1007
if(F_ISSET(pAllow->flags, ADDR_NAME)) {
1008
dbgprintf("MaskCmp: host=\"%s\"; pattern=\"%s\"\n", pszFromHost, pAllow->addr.HostWildcard);
1010
return(fnmatch(pAllow->addr.HostWildcard, pszFromHost, FNM_NOESCAPE|FNM_CASEFOLD) == 0);
1011
} else {/* We need to compare an IP address */
1012
switch (pFrom->sa_family) {
1014
if (AF_INET == pAllow->addr.NetAddr->sa_family)
1015
return(( SIN(pFrom)->sin_addr.s_addr & htonl(0xffffffff << (32 - bits)) )
1016
== SIN(pAllow->addr.NetAddr)->sin_addr.s_addr);
1021
switch (pAllow->addr.NetAddr->sa_family) {
1023
struct in6_addr ip, net;
1026
memcpy (&ip, &(SIN6(pFrom))->sin6_addr, sizeof (struct in6_addr));
1027
memcpy (&net, &(SIN6(pAllow->addr.NetAddr))->sin6_addr, sizeof (struct in6_addr));
1031
ip.s6_addr32[i++] &= htonl(0xffffffff << (32 - (bits % 32)));
1032
for (; i < (sizeof ip.s6_addr32)/4; i++)
1033
ip.s6_addr32[i] = 0;
1035
return (memcmp (ip.s6_addr, net.s6_addr, sizeof ip.s6_addr) == 0 &&
1036
(SIN6(pAllow->addr.NetAddr)->sin6_scope_id != 0 ?
1037
SIN6(pFrom)->sin6_scope_id == SIN6(pAllow->addr.NetAddr)->sin6_scope_id : 1));
1040
struct in6_addr *ip6 = &(SIN6(pFrom))->sin6_addr;
1041
struct in_addr *net = &(SIN(pAllow->addr.NetAddr))->sin_addr;
1043
if ((ip6->s6_addr32[3] & (u_int32_t) htonl((0xffffffff << (32 - bits)))) == net->s_addr &&
1044
#if BYTE_ORDER == LITTLE_ENDIAN
1045
(ip6->s6_addr32[2] == (u_int32_t)0xffff0000) &&
1047
(ip6->s6_addr32[2] == (u_int32_t)0x0000ffff) &&
1049
(ip6->s6_addr32[1] == 0) && (ip6->s6_addr32[0] == 0))
1055
/* Unsupported AF */
1059
/* Unsupported AF */
1066
/* check if a sender is allowed. The root of the the allowed sender.
1067
* list must be proveded by the caller. As such, this function can be
1068
* used to check both UDP and TCP allowed sender lists.
1069
* returns 1, if the sender is allowed, 0 otherwise.
1070
* rgerhards, 2005-09-26
1072
int isAllowedSender(struct AllowedSenders *pAllowRoot, struct sockaddr *pFrom, const char *pszFromHost)
1074
struct AllowedSenders *pAllow;
1076
assert(pFrom != NULL);
1078
if(pAllowRoot == NULL)
1079
return 1; /* checking disabled, everything is valid! */
1081
/* now we loop through the list of allowed senders. As soon as
1082
* we find a match, we return back (indicating allowed). We loop
1083
* until we are out of allowed senders. If so, we fall through the
1084
* loop and the function's terminal return statement will indicate
1085
* that the sender is disallowed.
1087
for(pAllow = pAllowRoot ; pAllow != NULL ; pAllow = pAllow->pNext) {
1088
if (MaskCmp (&(pAllow->allowedSender), pAllow->SignificantBits, pFrom, pszFromHost))
1091
dbgprintf("%s is not an allowed sender\n", pszFromHost);
1094
#endif /* #ifdef SYSLOG_INET */
1097
/* code to free all sockets within a socket table.
1098
* A socket table is a descriptor table where the zero
1099
* element has the count of elements. This is used for
1100
* listening sockets. The socket table itself is also
1102
* A POINTER to this structure must be provided, thus
1103
* double indirection!
1104
* rgerhards, 2007-06-28
1106
void freeAllSockets(int **socks)
1108
assert(socks != NULL);
1109
assert(*socks != NULL);
1111
dbgprintf("Closing socket %d.\n", (*socks)[**socks]);
1112
close((*socks)[**socks]);
1122
/*******************************************************************
1123
* BEGIN CODE-LIBLOGGING *
1124
*******************************************************************
1125
* Code in this section is borrowed from liblogging. This is an
1126
* interim solution. Once liblogging is fully integrated, this is
1127
* to be removed (see http://www.monitorware.com/liblogging for
1128
* more details. 2004-11-16 rgerhards
1130
* Please note that the orginal liblogging code is modified so that
1131
* it fits into the context of the current version of syslogd.c.
1133
* DO NOT PUT ANY OTHER CODE IN THIS BEGIN ... END BLOCK!!!!
1137
* Parse a 32 bit integer number from a string.
1139
* \param ppsz Pointer to the Pointer to the string being parsed. It
1140
* must be positioned at the first digit. Will be updated
1141
* so that on return it points to the first character AFTER
1142
* the integer parsed.
1143
* \retval The number parsed.
1146
static int srSLMGParseInt32(char** ppsz)
1151
while(isdigit((int) **ppsz))
1153
i = i * 10 + **ppsz - '0';
1162
* Parse a TIMESTAMP-3339.
1163
* updates the parse pointer position.
1165
static int srSLMGParseTIMESTAMP3339(struct syslogTime *pTime, char** ppszTS)
1167
char *pszTS = *ppszTS;
1169
assert(pTime != NULL);
1170
assert(ppszTS != NULL);
1171
assert(pszTS != NULL);
1173
pTime->year = srSLMGParseInt32(&pszTS);
1175
/* We take the liberty to accept slightly malformed timestamps e.g. in
1176
* the format of 2003-9-1T1:0:0. This doesn't hurt on receiving. Of course,
1177
* with the current state of affairs, we would never run into this code
1178
* here because at postion 11, there is no "T" in such cases ;)
1182
pTime->month = srSLMGParseInt32(&pszTS);
1183
if(pTime->month < 1 || pTime->month > 12)
1188
pTime->day = srSLMGParseInt32(&pszTS);
1189
if(pTime->day < 1 || pTime->day > 31)
1195
pTime->hour = srSLMGParseInt32(&pszTS);
1196
if(pTime->hour < 0 || pTime->hour > 23)
1201
pTime->minute = srSLMGParseInt32(&pszTS);
1202
if(pTime->minute < 0 || pTime->minute > 59)
1207
pTime->second = srSLMGParseInt32(&pszTS);
1208
if(pTime->second < 0 || pTime->second > 60)
1211
/* Now let's see if we have secfrac */
1214
char *pszStart = ++pszTS;
1215
pTime->secfrac = srSLMGParseInt32(&pszTS);
1216
pTime->secfracPrecision = (int) (pszTS - pszStart);
1220
pTime->secfracPrecision = 0;
1224
/* check the timezone */
1227
pszTS++; /* eat Z */
1228
pTime->OffsetMode = 'Z';
1229
pTime->OffsetHour = 0;
1230
pTime->OffsetMinute = 0;
1232
else if((*pszTS == '+') || (*pszTS == '-'))
1234
pTime->OffsetMode = *pszTS;
1237
pTime->OffsetHour = srSLMGParseInt32(&pszTS);
1238
if(pTime->OffsetHour < 0 || pTime->OffsetHour > 23)
1243
pTime->OffsetMinute = srSLMGParseInt32(&pszTS);
1244
if(pTime->OffsetMinute < 0 || pTime->OffsetMinute > 59)
1248
/* there MUST be TZ information */
1251
/* OK, we actually have a 3339 timestamp, so let's indicated this */
1257
/* update parse pointer */
1265
* Parse a TIMESTAMP-3164.
1266
* Returns TRUE on parse OK, FALSE on parse error.
1268
static int srSLMGParseTIMESTAMP3164(struct syslogTime *pTime, char* pszTS)
1270
assert(pTime != NULL);
1271
assert(pszTS != NULL);
1273
getCurrTime(pTime); /* obtain the current year and UTC offsets! */
1275
/* If we look at the month (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec),
1276
* we may see the following character sequences occur:
1278
* J(an/u(n/l)), Feb, Ma(r/y), A(pr/ug), Sep, Oct, Nov, Dec
1280
* We will use this for parsing, as it probably is the
1281
* fastest way to parse it.
1283
* 2005-07-18, well sometimes it pays to be a bit more verbose, even in C...
1284
* Fixed a bug that lead to invalid detection of the data. The issue was that
1285
* we had an if(++pszTS == 'x') inside of some of the consturcts below. However,
1286
* there were also some elseifs (doing the same ++), which than obviously did not
1287
* check the orginal character but the next one. Now removed the ++ and put it
1288
* into the statements below. Was a really nasty bug... I didn't detect it before
1289
* june, when it first manifested. This also lead to invalid parsing of the rest
1290
* of the message, as the time stamp was not detected to be correct. - rgerhards
1302
} else if(*pszTS == 'u') {
1307
} else if(*pszTS == 'l') {
1332
} else if(*pszTS == 'y') {
1348
} else if(*pszTS == 'u') {
1411
/* we accept a slightly malformed timestamp when receiving. This is
1412
* we accept one-digit days
1417
pTime->day = srSLMGParseInt32(&pszTS);
1418
if(pTime->day < 1 || pTime->day > 31)
1423
pTime->hour = srSLMGParseInt32(&pszTS);
1424
if(pTime->hour < 0 || pTime->hour > 23)
1429
pTime->minute = srSLMGParseInt32(&pszTS);
1430
if(pTime->minute < 0 || pTime->minute > 59)
1435
pTime->second = srSLMGParseInt32(&pszTS);
1436
if(pTime->second < 0 || pTime->second > 60)
1440
/* OK, we actually have a 3164 timestamp, so let's indicate this
1441
* and fill the rest of the properties. */
1442
pTime->timeType = 1;
1443
pTime->secfracPrecision = 0;
1448
/*******************************************************************
1449
* END CODE-LIBLOGGING *
1450
*******************************************************************/
1453
* Format a syslogTimestamp into format required by MySQL.
1454
* We are using the 14 digits format. For example 20041111122600
1455
* is interpreted as '2004-11-11 12:26:00'.
1456
* The caller must provide the timestamp as well as a character
1457
* buffer that will receive the resulting string. The function
1458
* returns the size of the timestamp written in bytes (without
1459
* the string terminator). If 0 is returend, an error occured.
1461
int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLenDst)
1463
/* currently we do not consider localtime/utc. This may later be
1464
* added. If so, I recommend using a property replacer option
1465
* and/or a global configuration option. However, we should wait
1466
* on user requests for this feature before doing anything.
1467
* rgerhards, 2007-06-26
1470
assert(pDst != NULL);
1472
if (iLenDst < 15) /* we need at least 14 bytes
1473
14 digits for timestamp + '\n' */
1476
return(snprintf(pDst, iLenDst, "%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d",
1477
ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second));
1482
* Format a syslogTimestamp to a RFC3339 timestamp string (as
1483
* specified in syslog-protocol).
1484
* The caller must provide the timestamp as well as a character
1485
* buffer that will receive the resulting string. The function
1486
* returns the size of the timestamp written in bytes (without
1487
* the string terminator). If 0 is returend, an error occured.
1489
int formatTimestamp3339(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
1492
char szTZ[7]; /* buffer for TZ information */
1495
assert(pBuf != NULL);
1498
return(0); /* we NEED at least 20 bytes */
1500
/* do TZ information first, this is easier to take care of "Z" zone in rfc3339 */
1501
if(ts->OffsetMode == 'Z') {
1505
snprintf(szTZ, sizeof(szTZ) / sizeof(char), "%c%2.2d:%2.2d",
1506
ts->OffsetMode, ts->OffsetHour, ts->OffsetMinute);
1509
if(ts->secfracPrecision > 0)
1510
{ /* we now need to include fractional seconds. While doing so, we must look at
1511
* the precision specified. For example, if we have millisec precision (3 digits), a
1512
* secFrac value of 12 is not equivalent to ".12" but ".012". Obviously, this
1513
* is a huge difference ;). To avoid this, we first create a format string with
1514
* the specific precision and *then* use that format string to do the actual
1515
* formating (mmmmhhh... kind of self-modifying code... ;)).
1518
/* be careful: there is ONE actual %d in the format string below ;) */
1519
snprintf(szFmtStr, sizeof(szFmtStr),
1520
"%%04d-%%02d-%%02dT%%02d:%%02d:%%02d.%%0%dd%%s",
1521
ts->secfracPrecision);
1522
iRet = snprintf(pBuf, iLenBuf, szFmtStr, ts->year, ts->month, ts->day,
1523
ts->hour, ts->minute, ts->second, ts->secfrac, szTZ);
1526
iRet = snprintf(pBuf, iLenBuf,
1527
"%4.4d-%2.2d-%2.2dT%2.2d:%2.2d:%2.2d%s",
1528
ts->year, ts->month, ts->day,
1529
ts->hour, ts->minute, ts->second, szTZ);
1534
* Format a syslogTimestamp to a RFC3164 timestamp sring.
1535
* The caller must provide the timestamp as well as a character
1536
* buffer that will receive the resulting string. The function
1537
* returns the size of the timestamp written in bytes (without
1538
* the string termnator). If 0 is returend, an error occured.
1540
int formatTimestamp3164(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
1542
static char* monthNames[13] = {"ERR", "Jan", "Feb", "Mar",
1543
"Apr", "May", "Jun", "Jul",
1544
"Aug", "Sep", "Oct", "Nov", "Dec"};
1546
assert(pBuf != NULL);
1549
return(0); /* we NEED 16 bytes */
1550
return(snprintf(pBuf, iLenBuf, "%s %2d %2.2d:%2.2d:%2.2d",
1551
monthNames[ts->month], ts->day, ts->hour,
1552
ts->minute, ts->second
1557
* Format a syslogTimestamp to a text format.
1558
* The caller must provide the timestamp as well as a character
1559
* buffer that will receive the resulting string. The function
1560
* returns the size of the timestamp written in bytes (without
1561
* the string termnator). If 0 is returend, an error occured.
1563
#if 0 /* This method is currently not called, be we like to preserve it */
1564
static int formatTimestamp(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
1567
assert(pBuf != NULL);
1569
if(ts->timeType == 1) {
1570
return(formatTimestamp3164(ts, pBuf, iLenBuf));
1573
if(ts->timeType == 2) {
1574
return(formatTimestamp3339(ts, pBuf, iLenBuf));
1583
* Get the current date/time in the best resolution the operating
1584
* system has to offer (well, actually at most down to the milli-
1587
* The date and time is returned in separate fields as this is
1588
* most portable and removes the need for additional structures
1589
* (but I have to admit it is somewhat "bulky";)).
1591
* Obviously, all caller-provided pointers must not be NULL...
1593
void getCurrTime(struct syslogTime *t)
1601
gettimeofday(&tp, NULL);
1602
tm = localtime_r((time_t*) &(tp.tv_sec), &tmBuf);
1604
t->year = tm->tm_year + 1900;
1605
t->month = tm->tm_mon + 1;
1606
t->day = tm->tm_mday;
1607
t->hour = tm->tm_hour;
1608
t->minute = tm->tm_min;
1609
t->second = tm->tm_sec;
1610
t->secfrac = tp.tv_usec;
1611
t->secfracPrecision = 6;
1614
/* Solaris uses a different method of exporting the time zone.
1615
* It is UTC - localtime, which is the opposite sign of mins east of GMT.
1617
lBias = -(daylight ? altzone : timezone);
1619
lBias = tm->tm_gmtoff;
1623
t->OffsetMode = '-';
1627
t->OffsetMode = '+';
1628
t->OffsetHour = lBias / 3600;
1629
t->OffsetMinute = lBias % 3600;
1631
/* rgerhards 2004-11-09: end of helper routines. On to the
1636
static int usage(void)
1638
fprintf(stderr, "usage: rsyslogd [-46Adhvw] [-l hostlist] [-m markinterval] [-n] [-p path]\n" \
1639
" [-s domainlist] [-r[port]] [-tport[,max-sessions]] [-f conffile] [-i pidfile] [-x]\n");
1640
exit(1); /* "good" exit - done to terminate usage() */
1643
#ifdef SYSLOG_UNIXAF
1644
static int create_unix_socket(const char *path)
1646
struct sockaddr_un sunx;
1648
char line[MAXLINE +1];
1650
if (path[0] == '\0')
1653
(void) unlink(path);
1655
memset(&sunx, 0, sizeof(sunx));
1656
sunx.sun_family = AF_UNIX;
1657
(void) strncpy(sunx.sun_path, path, sizeof(sunx.sun_path));
1658
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
1659
if (fd < 0 || bind(fd, (struct sockaddr *) &sunx,
1660
SUN_LEN(&sunx)) < 0 ||
1661
chmod(path, 0666) < 0) {
1662
snprintf(line, sizeof(line), "cannot create %s", path);
1664
dbgprintf("cannot create %s (%d).\n", path, errno);
1673
/* closes the UDP listen sockets (if they exist) and frees
1674
* all dynamically assigned memory.
1676
static void closeUDPListenSockets()
1681
for (i = 0; i < *finet; i++)
1689
/* creates the UDP listen sockets
1691
static int *create_udp_socket()
1693
struct addrinfo hints, *res, *r;
1694
int error, maxs, *s, *socks, on = 1;
1697
memset(&hints, 0, sizeof(hints));
1698
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
1699
hints.ai_family = family;
1700
hints.ai_socktype = SOCK_DGRAM;
1701
error = getaddrinfo(NULL, LogPort, &hints, &res);
1703
logerror((char*) gai_strerror(error));
1704
logerror("UDP message reception disabled due to error logged in last message.\n");
1708
/* Count max number of sockets we may open */
1709
for (maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++)
1711
socks = malloc((maxs+1) * sizeof(int));
1712
if (socks == NULL) {
1713
logerror("couldn't allocate memory for UDP sockets, suspending UDP message reception");
1718
*socks = 0; /* num of sockets counter at start of array */
1720
for (r = res; r != NULL ; r = r->ai_next) {
1721
*s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
1723
if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT))
1724
logerror("create_udp_socket(), socket");
1725
/* it is debatable if PF_INET with EAFNOSUPPORT should
1726
* also be ignored...
1732
if (r->ai_family == AF_INET6) {
1734
if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
1735
(char *)&ion, sizeof (ion)) < 0) {
1736
logerror("setsockopt");
1744
/* if we have an error, we "just" suspend that socket. Eventually
1745
* other sockets will work. At the end of this function, we check
1746
* if we managed to open at least one socket. If not, we'll write
1747
* a "inet suspended" message and declare failure. Else we use
1748
* what we could obtain.
1749
* rgerhards, 2007-06-22
1751
if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR,
1752
(char *) &on, sizeof(on)) < 0 ) {
1753
logerror("setsockopt(REUSEADDR)");
1759
/* We need to enable BSD compatibility. Otherwise an attacker
1760
* could flood our log files by sending us tons of ICMP errors.
1763
if (should_use_so_bsdcompat()) {
1764
if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT,
1765
(char *) &on, sizeof(on)) < 0) {
1766
logerror("setsockopt(BSDCOMPAT)");
1773
/* We must not block on the network socket, in case a packet
1774
* gets lost between select and recv, otherwise the process
1775
* will stall until the timeout, and other processes trying to
1776
* log will also stall.
1777
* Patch vom Colin Phipps <cph@cph.demon.co.uk> to the original
1778
* sysklogd source. Applied to rsyslogd on 2005-10-19.
1780
if ((sockflags = fcntl(*s, F_GETFL)) != -1) {
1781
sockflags |= O_NONBLOCK;
1782
/* SETFL could fail too, so get it caught by the subsequent
1785
sockflags = fcntl(*s, F_SETFL, sockflags);
1787
if (sockflags == -1) {
1788
logerror("fcntl(O_NONBLOCK)");
1794
/* rgerhards, 2007-06-22: if we run on a kernel that does not support
1795
* the IPV6_V6ONLY socket option, we need to use a work-around. On such
1796
* systems the IPv6 socket does also accept IPv4 sockets. So an IPv4
1797
* socket can not listen on the same port as an IPv6 socket. The only
1798
* workaround is to ignore the "socket in use" error. This is what we
1801
if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0)
1802
# ifndef IPV6_V6ONLY
1803
&& (errno != EADDRINUSE)
1819
if(Debug && *socks != maxs)
1820
dbgprintf("We could initialize %d UDP listen sockets out of %d we received "
1821
"- this may or may not be an error indication.\n", *socks, maxs);
1824
logerror("No UDP listen socket could successfully be initialized, "
1825
"message reception via UDP disabled.\n");
1826
/* we do NOT need to free any sockets, because there were none... */
1836
/* function to destruct a selector_t object
1837
* rgerhards, 2007-08-01
1839
static rsRetVal selectorDestruct(void *pVal)
1841
selector_t *pThis = (selector_t *) pVal;
1843
assert(pThis != NULL);
1845
if(pThis->pCSHostnameComp != NULL)
1846
rsCStrDestruct(pThis->pCSHostnameComp);
1847
if(pThis->pCSProgNameComp != NULL)
1848
rsCStrDestruct(pThis->pCSProgNameComp);
1850
if(pThis->f_filter_type == FILTER_PROP) {
1851
if(pThis->f_filterData.prop.pCSPropName != NULL)
1852
rsCStrDestruct(pThis->f_filterData.prop.pCSPropName);
1853
if(pThis->f_filterData.prop.pCSCompValue != NULL)
1854
rsCStrDestruct(pThis->f_filterData.prop.pCSCompValue);
1857
llDestroy(&pThis->llActList);
1864
/* function to construct a selector_t object
1865
* rgerhards, 2007-08-01
1867
static rsRetVal selectorConstruct(selector_t **ppThis)
1872
assert(ppThis != NULL);
1874
if((pThis = (selector_t*) calloc(1, sizeof(selector_t))) == NULL) {
1875
glblHadMemShortage = 1;
1876
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
1878
CHKiRet(llInit(&pThis->llActList, actionDestruct, NULL, NULL));
1881
if(iRet != RS_RET_OK) {
1883
selectorDestruct(pThis);
1891
/* rgerhards, 2005-10-24: crunch_list is called only during option processing. So
1892
* it is never called once rsyslogd is running (not even when HUPed). This code
1893
* contains some exits, but they are considered safe because they only happen
1894
* during startup. Anyhow, when we review the code here, we might want to
1895
* reconsider the exit()s.
1897
static char **crunch_list(char *list)
1901
char **result = NULL;
1905
/* strip off trailing delimiters */
1906
while (p[strlen(p)-1] == LIST_DELIMITER) {
1908
p[strlen(p)-1] = '\0';
1910
/* cut off leading delimiters */
1911
while (p[0] == LIST_DELIMITER) {
1916
/* count delimiters to calculate elements */
1917
for (count=i=0; p[i]; i++)
1918
if (p[i] == LIST_DELIMITER) count++;
1920
if ((result = (char **)malloc(sizeof(char *) * (count+2))) == NULL) {
1921
printf ("Sorry, can't get enough memory, exiting.\n");
1922
exit(0); /* safe exit, because only called during startup */
1926
* We now can assume that the first and last
1927
* characters are different from any delimiters,
1928
* so we don't have to care about this.
1931
while ((q=strchr(p, LIST_DELIMITER))) {
1932
result[count] = (char *) malloc((q - p + 1) * sizeof(char));
1933
if (result[count] == NULL) {
1934
printf ("Sorry, can't get enough memory, exiting.\n");
1935
exit(0); /* safe exit, because only called during startup */
1937
strncpy(result[count], p, q - p);
1938
result[count][q - p] = '\0';
1942
if ((result[count] = \
1943
(char *)malloc(sizeof(char) * strlen(p) + 1)) == NULL) {
1944
printf ("Sorry, can't get enough memory, exiting.\n");
1945
exit(0); /* safe exit, because only called during startup */
1947
strcpy(result[count],p);
1948
result[++count] = NULL;
1952
while (result[count])
1953
dbgprintf("#%d: %s\n", count, StripDomains[count++]);
1972
i = open(_PATH_TTY, O_RDWR);
1974
(void) ioctl(i, (int) TIOCNOTTY, (char *)0);
1982
/* rgerhards, 2006-11-30: I have greatly changed this function. Formerly,
1983
* it tried to reassemble multi-part messages, which is a legacy stock
1984
* sysklogd concept. In essence, that was that messages not ending with
1985
* \0 were glued together. As far as I can see, this is a sysklogd
1986
* specific feature and, from looking at the code, seems to be used
1987
* pretty seldom (if at all). I remove this now, not the least because it is totally
1988
* incompatible with upcoming IETF syslog standards. If you experience
1989
* strange behaviour with messages beeing split across multiple lines,
1990
* this function here might be the place to look at.
1992
* Some previous history worth noting:
1993
* I added the "iSource" parameter. This is needed to distinguish between
1994
* messages that have a hostname in them (received from the internet) and
1995
* those that do not have (most prominently /dev/log). rgerhards 2004-11-16
1996
* And now I removed the "iSource" parameter and changed it to be "bParseHost",
1997
* because all that it actually controls is whether the host is parsed or not.
1998
* For rfc3195 support, we needed to modify the algo for host parsing, so we can
1999
* no longer rely just on the source (rfc3195d forwarded messages arrive via
2000
* unix domain sockets but contain the hostname). rgerhards, 2005-10-06
2002
void printchopped(char *hname, char *msg, int len, int fd, int bParseHost)
2008
char tmpline[MAXLINE + 1];
2010
char deflateBuf[MAXLINE + 1];
2014
assert(hname != NULL);
2015
assert(msg != NULL);
2018
dbgprintf("Message length: %d, File descriptor: %d.\n", len, fd);
2020
/* we first check if we have a NUL character at the very end of the
2021
* message. This seems to be a frequent problem with a number of senders.
2022
* So I have now decided to drop these NULs. However, if they are intentional,
2023
* that may cause us some problems, e.g. with syslog-sign. On the other hand,
2024
* current code always has problems with intentional NULs (as it needs to escape
2025
* them to prevent problems with the C string libraries), so that does not
2026
* really matter. Just to be on the save side, we'll log destruction of such
2027
* NULs in the debug log.
2028
* rgerhards, 2007-09-14
2030
if(*(msg + len - 1) == '\0') {
2031
dbgprintf("dropped NUL at very end of message\n");
2035
/* then we check if we need to drop trailing LFs, which often make
2036
* their way into syslog messages unintentionally. In order to remain
2037
* compatible to recent IETF developments, we allow the user to
2038
* turn on/off this handling. rgerhards, 2007-07-23
2040
if(bDropTrailingLF && *(msg + len - 1) == '\n') {
2041
dbgprintf("dropped LF at very end of message (DropTrailingLF is set)\n");
2045
iMsg = 0; /* initialize receiving buffer index */
2046
pMsg = tmpline; /* set receiving buffer pointer */
2047
pData = msg; /* set source buffer pointer */
2048
pEnd = msg + len; /* this is one off, which is intensional */
2051
/* we first need to check if we have a compressed record. If so,
2052
* we must decompress it.
2054
if(len > 0 && *msg == 'z') { /* compressed data present? (do NOT change order if conditions!) */
2055
/* we have compressed data, so let's deflate it. We support a maximum
2056
* message size of MAXLINE. If it is larger, an error message is logged
2057
* and the message is dropped. We do NOT try to decompress larger messages
2058
* as such might be used for denial of service. It might happen to later
2059
* builds that such functionality be added as an optional, operator-configurable
2063
iLenDefBuf = MAXLINE;
2064
ret = uncompress((uchar *) deflateBuf, &iLenDefBuf, (uchar *) msg+1, len-1);
2065
dbgprintf("Compressed message uncompressed with status %d, length: new %d, old %d.\n",
2066
ret, iLenDefBuf, len-1);
2067
/* Now check if the uncompression worked. If not, there is not much we can do. In
2068
* that case, we log an error message but ignore the message itself. Storing the
2069
* compressed text is dangerous, as it contains control characters. So we do
2070
* not do this. If someone would like to have a copy, this code here could be
2071
* modified to do a hex-dump of the buffer in question. We do not include
2072
* this functionality right now.
2073
* rgerhards, 2006-12-07
2076
logerrorInt("Uncompression of a message failed with return code %d "
2077
"- enable debug logging if you need further information. "
2078
"Message ignored.", ret);
2079
return; /* unconditional exit, nothing left to do... */
2082
pEnd = deflateBuf + iLenDefBuf;
2084
# else /* ifdef USE_NETZIP */
2085
/* in this case, we still need to check if the message is compressed. If so, we must
2086
* tell the user we can not accept it.
2088
if(len > 0 && *msg == 'z') {
2089
logerror("Received a compressed message, but rsyslogd does not have compression "
2090
"support enabled. The message will be ignored.");
2093
# endif /* ifdef USE_NETZIP */
2095
while(pData < pEnd) {
2096
if(iMsg >= MAXLINE) {
2097
/* emergency, we now need to flush, no matter if
2098
* we are at end of message or not...
2100
if(iMsg == MAXLINE) {
2101
*(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */
2102
printline(hname, tmpline, bParseHost);
2104
/* This case in theory never can happen. If it happens, we have
2105
* a logic error. I am checking for it, because if I would not,
2106
* we would address memory invalidly with the code above. I
2107
* do not care much about this case, just a debug log entry
2108
* (I couldn't do any more smart things anyway...).
2109
* rgerhards, 2007-9-20
2111
dbgprintf("internal error: iMsg > MAXLINE in printchopped()\n");
2113
return; /* in this case, we are done... nothing left we can do */
2115
if(*pData == '\0') { /* guard against \0 characters... */
2116
/* changed to the sequence (somewhat) proposed in
2117
* draft-ietf-syslog-protocol-19. rgerhards, 2006-11-30
2119
if(iMsg + 3 < MAXLINE) { /* do we have space? */
2120
*(pMsg + iMsg++) = cCCEscapeChar;
2121
*(pMsg + iMsg++) = '0';
2122
*(pMsg + iMsg++) = '0';
2123
*(pMsg + iMsg++) = '0';
2124
} /* if we do not have space, we simply ignore the '\0'... */
2125
/* log an error? Very questionable... rgerhards, 2006-11-30 */
2126
/* decided: we do not log an error, it won't help... rger, 2007-06-21 */
2128
} else if(bEscapeCCOnRcv && iscntrl((int) *pData)) {
2129
/* we are configured to escape control characters. Please note
2130
* that this most probably break non-western character sets like
2131
* Japanese, Korean or Chinese. rgerhards, 2007-07-17
2132
* Note: sysklogd logs octal values only for DEL and CCs above 127.
2133
* For others, it logs ^n where n is the control char converted to an
2134
* alphabet character. We like consistency and thus escape it to octal
2135
* in all cases. If someone complains, we may change the mode. At least
2136
* we known now what's going on.
2137
* rgerhards, 2007-07-17
2139
if(iMsg + 3 < MAXLINE) { /* do we have space? */
2140
*(pMsg + iMsg++) = cCCEscapeChar;
2141
*(pMsg + iMsg++) = '0' + ((*pData & 0300) >> 6);
2142
*(pMsg + iMsg++) = '0' + ((*pData & 0070) >> 3);
2143
*(pMsg + iMsg++) = '0' + ((*pData & 0007));
2144
} /* again, if we do not have space, we ignore the char - see comment at '\0' */
2147
*(pMsg + iMsg++) = *pData++;
2151
*(pMsg + iMsg) = '\0'; /* space *is* reserved for this! */
2153
/* typically, we should end up here! */
2154
printline(hname, tmpline, bParseHost);
2159
/* Take a raw input line, decode the message, and print the message
2160
* on the appropriate log files.
2161
* rgerhards 2004-11-08: Please note
2162
* that this function does only a partial decoding. At best, it splits
2163
* the PRI part. No further decode happens. The rest is done in
2165
* Added the iSource parameter so that we know if we have to parse
2166
* HOSTNAME or not. rgerhards 2004-11-16.
2167
* changed parameter iSource to bParseHost. For details, see comment in
2168
* printchopped(). rgerhards 2005-10-06
2170
void printline(char *hname, char *msg, int bParseHost)
2176
/* Now it is time to create the message object (rgerhards)
2178
if((pMsg = MsgConstruct()) == NULL){
2179
/* rgerhards, 2007-06-21: if we can not get memory, we discard this
2180
* message but continue to run (in the hope that things improve)
2182
glblHadMemShortage = 1;
2183
dbgprintf("Memory shortage in printline(): Could not construct Msg object.\n");
2186
MsgSetRawMsg(pMsg, msg);
2188
pMsg->bParseHOSTNAME = bParseHost;
2189
/* test for special codes */
2194
while (isdigit((int) *++p))
2196
pri = 10 * pri + (*p - '0');
2201
if (pri &~ (LOG_FACMASK|LOG_PRIMASK))
2203
pMsg->iFacility = LOG_FAC(pri);
2204
pMsg->iSeverity = LOG_PRI(pri);
2206
/* Now we look at the HOSTNAME. That is a bit complicated...
2207
* If we have a locally received message, it does NOT
2208
* contain any hostname information in the message itself.
2209
* As such, the HOSTNAME is the same as the system that
2210
* the message was received from (that, for obvious reasons,
2211
* being the local host). rgerhards 2004-11-16
2214
MsgSetHOSTNAME(pMsg, hname);
2215
MsgSetRcvFrom(pMsg, hname);
2217
/* rgerhards 2004-11-19: well, well... we've now seen that we
2218
* have the "hostname problem" also with the traditional Unix
2219
* message. As we like to emulate it, we need to add the hostname
2222
if(MsgSetUxTradMsg(pMsg, p) != 0) return;
2224
logmsg(pri, pMsg, SYNC_FILE);
2226
/* rgerhards 2004-11-11:
2227
* we are done with the message object. If it still is
2228
* stored somewhere, we can call discard anyhow. This
2229
* is handled via the reference count - see description
2230
* of msg_t for details.
2238
/* rgerhards 2004-11-09: the following is a function that can be used
2239
* to log a message orginating from the syslogd itself. In sysklogd code,
2240
* this is done by simply calling logmsg(). However, logmsg() is changed in
2241
* rsyslog so that it takes a msg "object". So it can no longer be called
2242
* directly. This method here solves the need. It provides an interface that
2243
* allows to construct a locally-generated message. Please note that this
2244
* function here probably is only an interim solution and that we need to
2245
* think on the best way to do this.
2247
static void logmsgInternal(int pri, char *msg, int flags)
2251
if((pMsg = MsgConstruct()) == NULL){
2252
/* rgerhards 2004-11-09: calling panic might not be the
2253
* brightest idea - however, it is the best I currently have
2254
* (think a bit more about this).
2255
* rgehards, 2007-06-21: I have now thought a bit more about
2256
* it. If we are so low on memory, there is few we can do. calling
2257
* panic so far only write a debug line - this is seomthing we keep.
2258
* Other than that, however, we ignore the error and hope that
2259
* memory shortage will be resolved while we continue to run. In any
2260
* case, there is no valid point in aborting the syslogd for this
2261
* reason - that would be counter-productive. So we ignore the
2262
* to be logged message.
2264
glblHadMemShortage = 1;
2265
dbgprintf("Memory shortage in logmsgInternal: could not construct Msg object.\n");
2269
MsgSetUxTradMsg(pMsg, msg);
2270
MsgSetRawMsg(pMsg, msg);
2271
MsgSetHOSTNAME(pMsg, LocalHostName);
2272
MsgSetTAG(pMsg, "rsyslogd:");
2273
pMsg->iFacility = LOG_FAC(pri);
2274
pMsg->iSeverity = LOG_PRI(pri);
2275
pMsg->bParseHOSTNAME = 0;
2276
getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */
2277
flags |= INTERNAL_MSG;
2280
if(bRunningMultithreaded == 0) { /* not yet in queued mode */
2281
iminternalAddMsg(pri, pMsg, flags);
2283
/* we have the queue, so we can simply provide the
2284
* message to the queue engine.
2286
logmsg(pri, pMsg, flags);
2290
iminternalAddMsg(pri, pMsg, flags);
2294
/* This functions looks at the given message and checks if it matches the
2295
* provided filter condition. If so, it returns true, else it returns
2296
* false. This is a helper to logmsg() and meant to drive the decision
2297
* process if a message is to be processed or not. As I expect this
2298
* decision code to grow more complex over time AND logmsg() is already
2299
* a very lengthy function, I thought a separate function is more appropriate.
2300
* 2005-09-19 rgerhards
2302
int shouldProcessThisMessage(selector_t *f, msg_t *pMsg)
2304
unsigned short pbMustBeFreed;
2309
assert(pMsg != NULL);
2311
/* we first have a look at the global, BSD-style block filters (for tag
2312
* and host). Only if they match, we evaluate the actual filter.
2313
* rgerhards, 2005-10-18
2315
if(f->eHostnameCmpMode == HN_NO_COMP) {
2316
/* EMPTY BY INTENSION - we check this value first, because
2317
* it is the one most often used, so this saves us time!
2319
} else if(f->eHostnameCmpMode == HN_COMP_MATCH) {
2320
if(rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) {
2321
/* not equal, so we are already done... */
2322
dbgprintf("hostname filter '+%s' does not match '%s'\n",
2323
rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg));
2326
} else { /* must be -hostname */
2327
if(!rsCStrSzStrCmp(f->pCSHostnameComp, (uchar*) getHOSTNAME(pMsg), getHOSTNAMELen(pMsg))) {
2328
/* not equal, so we are already done... */
2329
dbgprintf("hostname filter '-%s' does not match '%s'\n",
2330
rsCStrGetSzStrNoNULL(f->pCSHostnameComp), getHOSTNAME(pMsg));
2335
if(f->pCSProgNameComp != NULL) {
2336
int bInv = 0, bEqv = 0, offset = 0;
2337
if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp)) == '-') {
2338
if(*(rsCStrGetSzStrNoNULL(f->pCSProgNameComp) + 1) == '-')
2345
if(!rsCStrOffsetSzStrCmp(f->pCSProgNameComp, offset, (uchar*) getProgramName(pMsg), getProgramNameLen(pMsg)))
2348
if((!bEqv && !bInv) || (bEqv && bInv)) {
2349
/* not equal or inverted selection, so we are already done... */
2350
dbgprintf("programname filter '%s' does not match '%s'\n",
2351
rsCStrGetSzStrNoNULL(f->pCSProgNameComp), getProgramName(pMsg));
2356
/* done with the BSD-style block filters */
2358
if(f->f_filter_type == FILTER_PRI) {
2359
/* skip messages that are incorrect priority */
2360
if ( (f->f_filterData.f_pmask[pMsg->iFacility] == TABLE_NOPRI) || \
2361
((f->f_filterData.f_pmask[pMsg->iFacility] & (1<<pMsg->iSeverity)) == 0) )
2366
assert(f->f_filter_type == FILTER_PROP); /* assert() just in case... */
2367
pszPropVal = MsgGetProp(pMsg, NULL,
2368
f->f_filterData.prop.pCSPropName, &pbMustBeFreed);
2370
/* Now do the compares (short list currently ;)) */
2371
switch(f->f_filterData.prop.operation ) {
2373
if(rsCStrLocateInSzStr(f->f_filterData.prop.pCSCompValue, (uchar*) pszPropVal) != -1)
2377
if(rsCStrSzStrCmp(f->f_filterData.prop.pCSCompValue,
2378
(uchar*) pszPropVal, strlen(pszPropVal)) == 0)
2379
iRet = 1; /* process message! */
2381
case FIOP_STARTSWITH:
2382
if(rsCStrSzStrStartsWithCStr(f->f_filterData.prop.pCSCompValue,
2383
(uchar*) pszPropVal, strlen(pszPropVal)) == 0)
2384
iRet = 1; /* process message! */
2387
if(rsCStrSzStrMatchRegex(f->f_filterData.prop.pCSCompValue,
2388
(unsigned char*) pszPropVal) == 0)
2392
/* here, it handles NOP (for performance reasons) */
2393
assert(f->f_filterData.prop.operation == FIOP_NOP);
2394
iRet = 1; /* as good as any other default ;) */
2398
/* now check if the value must be negated */
2399
if(f->f_filterData.prop.isNegated)
2400
iRet = (iRet == 1) ? 0 : 1;
2403
printf("Filter: check for property '%s' (value '%s') ",
2404
rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName),
2406
if(f->f_filterData.prop.isNegated)
2408
printf("%s '%s': %s\n",
2409
getFIOPName(f->f_filterData.prop.operation),
2410
rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue),
2411
iRet ? "TRUE" : "FALSE");
2423
/* doEmergencyLoggin()
2424
* ... does exactly do that. It logs messages when the subsystem has not yet
2425
* been initialized. This almost always happens during initial startup or
2426
* during HUPing. -- rgerhards, 2007-07-25
2427
* rgerhards, 2007-08-03: as of now, this can normally no longer happen. All
2428
* startup messages are now buffered until the system is ready to run. I leave
2429
* this minimal implementation here in in the very remote case that it might
2430
* be needed in the future or due to a program bug. Do *not* excpect this
2431
* code to be called.
2433
static void doEmergencyLogging(msg_t *pMsg)
2435
assert(pMsg != NULL);
2436
fprintf(stderr, "rsyslog: %s\n", pMsg->pszMSG);
2440
/* call the configured action. Does all necessary housekeeping.
2441
* rgerhards, 2007-08-01
2443
static rsRetVal callAction(msg_t *pMsg, action_t *pAction)
2447
assert(pMsg != NULL);
2448
assert(pAction != NULL);
2450
/* first, we need to check if this is a disabled
2451
* entry. If so, we must not further process it.
2452
* rgerhards 2005-09-26
2453
* In the future, disabled modules may be re-probed from time
2454
* to time. They are in a perfectly legal state, except that the
2455
* doAction method indicated that it wanted to be disabled - but
2456
* we do not consider this is a solution for eternity... So we
2457
* should check from time to time if affairs have improved.
2458
* rgerhards, 2007-07-24
2460
if(pAction->bEnabled == 0) {
2461
ABORT_FINALIZE(RS_RET_OK);
2464
if(actionIsSuspended(pAction)) {
2465
CHKiRet(actionTryResume(pAction));
2468
/* don't output marks to recently written files */
2469
if ((pMsg->msgFlags & MARK) && (now - pAction->f_time) < MarkInterval / 2) {
2470
ABORT_FINALIZE(RS_RET_OK);
2473
/* suppress duplicate messages
2475
if ((pAction->f_ReduceRepeated == 1) && pAction->f_pMsg != NULL &&
2476
(pMsg->msgFlags & MARK) == 0 && getMSGLen(pMsg) == getMSGLen(pAction->f_pMsg) &&
2477
!strcmp(getMSG(pMsg), getMSG(pAction->f_pMsg)) &&
2478
!strcmp(getHOSTNAME(pMsg), getHOSTNAME(pAction->f_pMsg)) &&
2479
!strcmp(getPROCID(pMsg), getPROCID(pAction->f_pMsg)) &&
2480
!strcmp(getAPPNAME(pMsg), getAPPNAME(pAction->f_pMsg))) {
2481
pAction->f_prevcount++;
2482
dbgprintf("msg repeated %d times, %ld sec of %d.\n",
2483
pAction->f_prevcount, now - pAction->f_time,
2484
repeatinterval[pAction->f_repeatcount]);
2485
MsgDestruct(pAction->f_pMsg);
2486
pAction->f_pMsg = MsgAddRef(pMsg);
2487
/* If domark would have logged this by now, flush it now (so we don't hold
2488
* isolated messages), but back off so we'll flush less often in the future.
2490
if (now > REPEATTIME(pAction)) {
2491
iRet = fprintlog(pAction);
2495
/* new message, save it */
2496
/* first check if we have a previous message stored
2497
* if so, emit and then discard it first
2499
if(pAction->f_pMsg != NULL) {
2500
if(pAction->f_prevcount > 0)
2502
/* we do not care about iRet above - I think it's right but if we have
2503
* some troubles, you know where to look at ;) -- rgerhards, 2007-08-01
2505
MsgDestruct(pAction->f_pMsg);
2507
pAction->f_pMsg = MsgAddRef(pMsg);
2508
/* call the output driver */
2509
iRet = fprintlog(pAction);
2517
/* helper to processMsg(), used to call the configured actions. It is
2518
* executed from within llExecFunc() of the action list.
2519
* rgerhards, 2007-08-02
2521
typedef struct processMsgDoActions_s {
2522
int bPrevWasSuspended; /* was the previous action suspended? */
2524
} processMsgDoActions_t;
2525
DEFFUNC_llExecFunc(processMsgDoActions)
2528
rsRetVal iRetMod; /* return value of module - we do not always pass that back */
2529
action_t *pAction = (action_t*) pData;
2530
processMsgDoActions_t *pDoActData = (processMsgDoActions_t*) pParam;
2532
assert(pAction != NULL);
2534
if((pAction->bExecWhenPrevSusp == 1) && (pDoActData->bPrevWasSuspended == 0)) {
2535
dbgprintf("not calling action because the previous one is not suspended\n");
2536
ABORT_FINALIZE(RS_RET_OK);
2539
iRetMod = callAction(pDoActData->pMsg, pAction);
2540
if(iRetMod == RS_RET_DISCARDMSG) {
2541
ABORT_FINALIZE(RS_RET_DISCARDMSG);
2542
} else if(iRetMod == RS_RET_SUSPENDED) {
2543
/* indicate suspension for next module to be called */
2544
pDoActData->bPrevWasSuspended = 1;
2546
pDoActData->bPrevWasSuspended = 0;
2554
/* Process (consume) a received message. Calls the actions configured.
2555
* Can some time later run in its own thread. To aid this, the calling
2556
* parameters should be reduced to just pMsg.
2557
* See comment dated 2005-10-13 in logmsg() on multithreading.
2558
* rgerhards, 2005-10-13
2560
static void processMsg(msg_t *pMsg)
2564
processMsgDoActions_t DoActData;
2566
assert(pMsg != NULL);
2568
/* log the message to the particular outputs */
2570
doEmergencyLogging(pMsg);
2575
for (f = Files; f != NULL && bContinue ; f = f->f_next) {
2576
/* This is actually the "filter logic". Looks like we need
2577
* to improve it a little for complex selector line conditions. We
2578
* won't do that for now, but at least we now know where
2580
* 2005-09-09 rgerhards
2581
* ok, we are now ready to move to something more advanced. Because
2582
* of this, I am moving the actual decision code to outside this function.
2583
* 2005-09-19 rgerhards
2585
if(!shouldProcessThisMessage(f, pMsg)) {
2589
/* ok -- from here, we have action-specific code, nothing really selector-specific -- rger 2007-08-01 */
2590
DoActData.pMsg = pMsg;
2591
DoActData.bPrevWasSuspended = 0;
2592
if(llExecFunc(&f->llActList, processMsgDoActions, (void*)&DoActData) == RS_RET_DISCARDMSG)
2599
/* This block contains code that is only present when USE_PTHREADS is
2600
* enabled. I plan to move it to some other file, but for the time
2601
* being, I include it here because that saves me from the need to
2602
* do so many external definitons.
2603
* rgerhards, 2005-10-24
2606
/* shuts down the worker process. The worker will first finish
2607
* with the message queue. Control returns, when done.
2608
* This function is intended to be called during syslogd shutdown
2609
* AND restart (init()!).
2610
* rgerhards, 2005-10-25
2612
static void stopWorker(void)
2614
if(bRunningMultithreaded) {
2615
/* we could run single-threaded if there was an error
2616
* during startup. Then, we obviously do not need to
2617
* do anything to stop the worker ;)
2619
dbgprintf("Initiating worker thread shutdown sequence...\n");
2620
/* We are now done with all messages, so we need to wake up the
2621
* worker thread and then wait for it to finish.
2624
/* It's actually not "not empty" below but awaking the worker. The worker
2625
* then finds out that it shall terminate and does so.
2627
pthread_cond_signal(pMsgQueue->notEmpty);
2628
pthread_join(thrdWorker, NULL);
2629
bRunningMultithreaded = 0;
2630
dbgprintf("Worker thread terminated.\n");
2635
/* starts the worker thread. It must be made sure that the queue is
2636
* already existing and the worker is NOT already running.
2637
* rgerhards 2005-10-25
2639
static void startWorker(void)
2642
if(pMsgQueue != NULL) {
2643
bGlblDone = 0; /* we are NOT done (else worker would immediately terminate) */
2644
i = pthread_create(&thrdWorker, NULL, singleWorker, NULL);
2645
dbgprintf("Worker thread started with state %d.\n", i);
2646
bRunningMultithreaded = 1;
2648
dbgprintf("message queue not existing, remaining single-threaded.\n");
2653
static msgQueue *queueInit (void)
2657
q = (msgQueue *)malloc(sizeof(msgQueue));
2658
if (q == NULL) return (NULL);
2659
if((q->pbuf = malloc(sizeof(void *) * iMainMsgQueueSize)) == NULL) {
2668
q->mut = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t));
2669
pthread_mutex_init (q->mut, NULL);
2670
q->notFull = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
2671
pthread_cond_init (q->notFull, NULL);
2672
q->notEmpty = (pthread_cond_t *) malloc (sizeof (pthread_cond_t));
2673
pthread_cond_init (q->notEmpty, NULL);
2678
static void queueDelete (msgQueue *q)
2680
pthread_mutex_destroy (q->mut);
2682
pthread_cond_destroy (q->notFull);
2684
pthread_cond_destroy (q->notEmpty);
2691
/* In queueAdd() and queueDel() we have a potential race condition. If a message
2692
* is dequeued and at the same time a message is enqueued and the queue is either
2693
* full or empty, the full (or empty) indicator may be invalidly updated. HOWEVER,
2694
* this does not cause any real problems. No queue pointers can be wrong. And even
2695
* if one of the flags is set invalidly, that does not pose a real problem. If
2696
* "full" is invalidly set, at mose one message might be lost, if we are already in
2697
* a timeout situation (this is quite acceptable). And if "empty" is accidently set,
2698
* the receiver will not continue the inner loop, but break out of the outer. So no
2699
* harm is done at all. For this reason, I do not yet use a mutex to guard the two
2700
* flags - there would be a notable performance hit with, IMHO, no gain in stability
2701
* or functionality. But anyhow, now it's documented...
2702
* rgerhards, 2007-09-20
2703
* NOTE: this comment does not really apply - the callers handle the mutex, so it
2706
static void queueAdd (msgQueue *q, void* in)
2708
q->pbuf[q->tail] = in;
2710
if (q->tail == iMainMsgQueueSize)
2712
if (q->tail == q->head)
2719
static void queueDel (msgQueue *q, msg_t **out)
2721
*out = (msg_t*) q->pbuf[q->head];
2724
if (q->head == iMainMsgQueueSize)
2726
if (q->head == q->tail)
2734
/* The worker thread (so far, we have dual-threading, so only one
2735
* worker thread. Having more than one worker requires considerable
2736
* additional code review in regard to thread-safety.
2738
static void *singleWorker()
2740
msgQueue *fifo = pMsgQueue;
2744
assert(fifo != NULL);
2746
sigfillset(&sigSet);
2747
pthread_sigmask(SIG_BLOCK, &sigSet, NULL);
2749
while(!bGlblDone || !fifo->empty) {
2750
pthread_mutex_lock(fifo->mut);
2751
while (fifo->empty && !bGlblDone) {
2752
dbgprintf("singleWorker: queue EMPTY, waiting for next message.\n");
2753
pthread_cond_wait (fifo->notEmpty, fifo->mut);
2756
/* dequeue element (still protected from mutex) */
2757
queueDel(fifo, &pMsg);
2758
assert(pMsg != NULL);
2759
pthread_mutex_unlock(fifo->mut);
2760
pthread_cond_signal (fifo->notFull);
2761
/* do actual processing (the lengthy part, runs in parallel) */
2762
dbgprintf("Lone worker is running...\n");
2765
/* If you need a delay for testing, here do a */
2767
} else { /* the mutex must be unlocked in any case (important for termination) */
2768
pthread_mutex_unlock(fifo->mut);
2771
if(debugging_on && bGlblDone && !fifo->empty)
2772
dbgprintf("Worker does not yet terminate because it still has messages to process.\n");
2775
dbgprintf("Worker thread terminates\n");
2779
/* END threads-related code */
2780
#endif /* #ifdef USE_PTHREADS */
2783
/* This method enqueues a message into the the message buffer. It also
2784
* the worker thread, so that the message will be processed. If we are
2785
* compiled without PTHREADS support, we simply use this method as
2786
* an alias for processMsg().
2787
* See comment dated 2005-10-13 in logmsg() on multithreading.
2788
* rgerhards, 2005-10-24
2790
#ifndef USE_PTHREADS
2791
#define enqueueMsg(x) processMsg((x))
2793
static void enqueueMsg(msg_t *pMsg)
2796
msgQueue *fifo = pMsgQueue;
2799
assert(pMsg != NULL);
2801
if(bRunningMultithreaded == 0) {
2802
/* multi-threading is not yet initialized, happens e.g.
2803
* during startup and restart. rgerhards, 2005-10-25
2805
dbgprintf("enqueueMsg: not yet running on multiple threads\n");
2808
/* "normal" mode, threading initialized */
2809
pthread_mutex_lock(fifo->mut);
2811
while (fifo->full) {
2812
dbgprintf("enqueueMsg: queue FULL.\n");
2814
clock_gettime (CLOCK_REALTIME, &t);
2817
if(pthread_cond_timedwait (fifo->notFull,
2818
fifo->mut, &t) != 0) {
2819
dbgprintf("enqueueMsg: cond timeout, dropping message!\n");
2823
queueAdd(fifo, MsgAddRef(pMsg));
2825
/* now activate the worker thread */
2826
pthread_mutex_unlock(fifo->mut);
2827
iRet = pthread_cond_signal(fifo->notEmpty);
2828
dbgprintf("EnqueueMsg signaled condition (%d)\n", iRet);
2831
#endif /* #ifndef USE_PTHREADS */
2834
/* Helper to parseRFCSyslogMsg. This function parses a field up to
2835
* (and including) the SP character after it. The field contents is
2836
* returned in a caller-provided buffer. The parsepointer is advanced
2837
* to after the terminating SP. The caller must ensure that the
2838
* provided buffer is large enough to hold the to be extracted value.
2839
* Returns 0 if everything is fine or 1 if either the field is not
2840
* SP-terminated or any other error occurs.
2843
static int parseRFCField(char **pp2parse, char *pResult)
2848
assert(pp2parse != NULL);
2849
assert(*pp2parse != NULL);
2850
assert(pResult != NULL);
2852
p2parse = *pp2parse;
2854
/* this is the actual parsing loop */
2855
while(*p2parse && *p2parse != ' ') {
2856
*pResult++ = *p2parse++;
2860
++p2parse; /* eat SP, but only if not at end of string */
2862
iRet = 1; /* there MUST be an SP! */
2865
/* set the new parse pointer */
2866
*pp2parse = p2parse;
2871
/* Helper to parseRFCSyslogMsg. This function parses the structured
2872
* data field of a message. It does NOT parse inside structured data,
2873
* just gets the field as whole. Parsing the single entities is left
2874
* to other functions. The parsepointer is advanced
2875
* to after the terminating SP. The caller must ensure that the
2876
* provided buffer is large enough to hold the to be extracted value.
2877
* Returns 0 if everything is fine or 1 if either the field is not
2878
* SP-terminated or any other error occurs.
2881
static int parseRFCStructuredData(char **pp2parse, char *pResult)
2887
assert(pp2parse != NULL);
2888
assert(*pp2parse != NULL);
2889
assert(pResult != NULL);
2891
p2parse = *pp2parse;
2893
/* this is the actual parsing loop
2894
* Remeber: structured data starts with [ and includes any characters
2895
* until the first ] followed by a SP. There may be spaces inside
2896
* structured data. There may also be \] inside the structured data, which
2897
* do NOT terminate an element.
2900
return 1; /* this is NOT structured data! */
2903
if(*p2parse == '\0') {
2904
iRet = 1; /* this is not valid! */
2906
} else if(*p2parse == '\\' && *(p2parse+1) == ']') {
2907
/* this is escaped, need to copy both */
2908
*pResult++ = *p2parse++;
2909
*pResult++ = *p2parse++;
2910
} else if(*p2parse == ']' && *(p2parse+1) == ' ') {
2911
/* found end, just need to copy the ] and eat the SP */
2912
*pResult++ = *p2parse;
2916
*pResult++ = *p2parse++;
2921
++p2parse; /* eat SP, but only if not at end of string */
2923
iRet = 1; /* there MUST be an SP! */
2926
/* set the new parse pointer */
2927
*pp2parse = p2parse;
2931
/* parse a RFC-formatted syslog message. This function returns
2932
* 0 if processing of the message shall continue and 1 if something
2933
* went wrong and this messe should be ignored. This function has been
2934
* implemented in the effort to support syslog-protocol. Please note that
2935
* the name (parse *RFC*) stems from the hope that syslog-protocol will
2936
* some time become an RFC. Do not confuse this with informational
2937
* RFC 3164 (which is legacy syslog).
2939
* currently supported format:
2941
* <PRI>VERSION SP TIMESTAMP SP HOSTNAME SP APP-NAME SP PROCID SP MSGID SP [SD-ID]s SP MSG
2943
* <PRI> is already stripped when this function is entered. VERSION already
2944
* has been confirmed to be "1", but has NOT been stripped from the message.
2948
static int parseRFCSyslogMsg(msg_t *pMsg, int flags)
2954
assert(pMsg != NULL);
2955
assert(pMsg->pszUxTradMsg != NULL);
2956
p2parse = (char*) pMsg->pszUxTradMsg;
2958
/* do a sanity check on the version and eat it */
2959
assert(p2parse[0] == '1' && p2parse[1] == ' ');
2962
/* Now get us some memory we can use as a work buffer while parsing.
2963
* We simply allocated a buffer sufficiently large to hold all of the
2964
* message, so we can not run into any troubles. I think this is
2965
* more wise then to use individual buffers.
2967
if((pBuf = malloc(sizeof(char)* strlen(p2parse) + 1)) == NULL)
2971
* Validation is not actually done below nor are any errors handled. I have
2972
* NOT included this for the current proof of concept. However, it is strongly
2973
* advisable to add it when this code actually goes into production.
2974
* rgerhards, 2005-11-24
2978
if(srSLMGParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == FALSE) {
2979
dbgprintf("no TIMESTAMP detected!\n");
2984
if (flags & ADDDATE) {
2985
getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */
2990
parseRFCField(&p2parse, pBuf);
2991
MsgSetHOSTNAME(pMsg, pBuf);
2993
/* we can not parse, so we get the system we
2994
* received the data from.
2996
MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
3001
parseRFCField(&p2parse, pBuf);
3002
MsgSetAPPNAME(pMsg, pBuf);
3007
parseRFCField(&p2parse, pBuf);
3008
MsgSetPROCID(pMsg, pBuf);
3013
parseRFCField(&p2parse, pBuf);
3014
MsgSetMSGID(pMsg, pBuf);
3017
/* STRUCTURED-DATA */
3019
parseRFCStructuredData(&p2parse, pBuf);
3020
MsgSetStructuredData(pMsg, pBuf);
3024
MsgSetMSG(pMsg, p2parse);
3026
return 0; /* all ok */
3028
/* parse a legay-formatted syslog message. This function returns
3029
* 0 if processing of the message shall continue and 1 if something
3030
* went wrong and this messe should be ignored. This function has been
3031
* implemented in the effort to support syslog-protocol.
3033
* As of 2006-01-10, I am removing the logic to continue parsing only
3034
* when a valid TIMESTAMP is detected. Validity of other fields already
3035
* is ignored. This is due to the fact that the parser has grown smarter
3036
* and is now more able to understand different dialects of the syslog
3037
* message format. I do not expect any bad side effects of this change,
3038
* but I thought I log it in this comment.
3039
* rgerhards, 2006-01-10
3041
static int parseLegacySyslogMsg(msg_t *pMsg, int flags)
3048
int bTAGCharDetected;
3050
assert(pMsg != NULL);
3051
assert(pMsg->pszUxTradMsg != NULL);
3052
p2parse = (char*) pMsg->pszUxTradMsg;
3054
/* Check to see if msg contains a timestamp
3056
if(srSLMGParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), p2parse) == TRUE)
3062
/* here we need to check if the timestamp is valid. If it is not,
3063
* we can not continue to parse but must treat the rest as the
3064
* MSG part of the message (as of RFC 3164).
3065
* rgerhards 2004-12-03
3068
if (flags & ADDDATE) {
3069
getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */
3072
/* rgerhards, 2006-03-13: next, we parse the hostname and tag. But we
3073
* do this only when the user has not forbidden this. I now introduce some
3074
* code that allows a user to configure rsyslogd to treat the rest of the
3075
* message as MSG part completely. In this case, the hostname will be the
3076
* machine that we received the message from and the tag will be empty. This
3077
* is meant to be an interim solution, but for now it is in the code.
3080
if(bParseHOSTNAMEandTAG && !(flags & INTERNAL_MSG)) {
3081
/* parse HOSTNAME - but only if this is network-received!
3082
* rger, 2005-11-14: we still have a problem with BSD messages. These messages
3083
* do NOT include a host name. In most cases, this leads to the TAG to be treated
3084
* as hostname and the first word of the message as the TAG. Clearly, this is not
3085
* of advantage ;) I think I have now found a way to handle this situation: there
3086
* are certain characters which are frequently used in TAG (e.g. ':'), which are
3087
* *invalid* in host names. So while parsing the hostname, I check for these characters.
3088
* If I find them, I set a simple flag but continue. After parsing, I check the flag.
3089
* If it was set, then we most probably do not have a hostname but a TAG. Thus, I change
3090
* the fields. I think this logic shall work with any type of syslog message.
3092
bTAGCharDetected = 0;
3093
if(pMsg->bParseHOSTNAME) {
3094
/* TODO: quick and dirty memory allocation */
3095
/* the memory allocated is far too much in most cases. But on the plus side,
3096
* it is quite fast... - rgerhards, 2007-09-20
3098
if((pBuf = malloc(sizeof(char)* (strlen(p2parse) +1))) == NULL)
3101
/* this is the actual parsing loop */
3102
while(*p2parse && *p2parse != ' ' && *p2parse != ':') {
3103
if(*p2parse == '[' || *p2parse == ']' || *p2parse == '/')
3104
bTAGCharDetected = 1;
3105
*pWork++ = *p2parse++;
3107
/* we need to handle ':' seperately, because it terminates the
3108
* TAG - so we also need to terminate the parser here!
3109
* rgerhards, 2007-09-10 *p2parse points to a valid address here in
3110
* any case. We can reach this point only if we are at end of string,
3111
* or we have a ':' or ' '. What the if below does is check if we are
3112
* not at end of string and, if so, advance the parse pointer. If we
3113
* are already at end of string, *p2parse is equal to '\0', neither if
3114
* will be true and the parse pointer remain as is. This is perfectly
3117
if(*p2parse == ':') {
3118
bTAGCharDetected = 1;
3120
} else if(*p2parse == ' ')
3123
MsgAssignHOSTNAME(pMsg, pBuf);
3125
/* check if we seem to have a TAG */
3126
if(bTAGCharDetected) {
3127
/* indeed, this smells like a TAG, so lets use it for this. We take
3128
* the HOSTNAME from the sender system instead.
3130
dbgprintf("HOSTNAME contains invalid characters, assuming it to be a TAG.\n");
3131
moveHOSTNAMEtoTAG(pMsg);
3132
MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
3135
/* now parse TAG - that should be present in message from
3137
* This code is somewhat not compliant with RFC 3164. As of 3164,
3138
* the TAG field is ended by any non-alphanumeric character. In
3139
* practice, however, the TAG often contains dashes and other things,
3140
* which would end the TAG. So it is not desirable. As such, we only
3141
* accept colon and SP to be terminators. Even there is a slight difference:
3142
* a colon is PART of the TAG, while a SP is NOT part of the tag
3143
* (it is CONTENT). Finally, we allow only up to 32 characters for
3144
* TAG, as it is specified in RFC 3164.
3146
/* The following code in general is quick & dirty - I need to get
3147
* it going for a test, rgerhards 2004-11-16 */
3148
/* lol.. we tried to solve it, just to remind ourselfs that 32 octets
3149
* is the max size ;) we need to shuffle the code again... Just for
3150
* the records: the code is currently clean, but we could optimize it! */
3151
if(!bTAGCharDetected) {
3153
if((pStrB = rsCStrConstruct()) == NULL)
3155
rsCStrSetAllocIncrement(pStrB, 33);
3158
while(*p2parse && *p2parse != ':' && *p2parse != ' ' && iCnt < 32) {
3159
rsCStrAppendChar(pStrB, *p2parse++);
3162
if(*p2parse == ':') {
3164
rsCStrAppendChar(pStrB, ':');
3166
rsCStrFinish(pStrB);
3168
rsCStrConvSzStrAndDestruct(pStrB, &pszTAG, 1);
3170
{ /* rger, 2005-11-10: no TAG found - this implies that what
3171
* we have considered to be the HOSTNAME is most probably the
3172
* TAG. We consider it so probable, that we now adjust it
3173
* that way. So we pick up the previously set hostname, assign
3174
* it to tag and use the sender system (from IP stack) as
3175
* the hostname. This situation is the standard case with
3176
* stock BSD syslogd.
3178
dbgprintf("No TAG in message, assuming that HOSTNAME is missing.\n");
3179
moveHOSTNAMEtoTAG(pMsg);
3180
MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
3181
} else { /* we have a TAG, so we can happily set it ;) */
3182
MsgAssignTAG(pMsg, pszTAG);
3185
/* we have no TAG, so we ... */
3189
/* we enter this code area when the user has instructed rsyslog NOT
3190
* to parse HOSTNAME and TAG - rgerhards, 2006-03-13
3192
if(!(flags & INTERNAL_MSG))
3194
dbgprintf("HOSTNAME and TAG not parsed by user configuraton.\n");
3195
MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg));
3199
/* The rest is the actual MSG */
3200
MsgSetMSG(pMsg, p2parse);
3202
return 0; /* all ok */
3207
* Log a message to the appropriate log files, users, etc. based on
3209
* rgerhards 2004-11-08: actually, this also decodes all but the PRI part.
3210
* rgerhards 2004-11-09: ... but only, if syslogd could properly be initialized
3211
* if not, we use emergency logging to the console and in
3212
* this case, no further decoding happens.
3213
* changed to no longer receive a plain message but a msg object instead.
3214
* rgerhards-2004-11-16: OK, we are now up to another change... This method
3215
* actually needs to PARSE the message. How exactly this needs to happen depends on
3216
* a number of things. Most importantly, it depends on the source. For example,
3217
* locally received messages (SOURCE_UNIXAF) do NOT have a hostname in them. So
3218
* we need to treat them differntly form network-received messages which have.
3219
* Well, actually not all network-received message really have a hostname. We
3220
* can just hope they do, but we can not be sure. So this method tries to find
3221
* whatever can be found in the message and uses that... Obviously, there is some
3222
* potential for misinterpretation, which we simply can not solve under the
3223
* circumstances given.
3225
void logmsg(int pri, msg_t *pMsg, int flags)
3230
assert(pMsg != NULL);
3231
assert(pMsg->pszUxTradMsg != NULL);
3232
msg = (char*) pMsg->pszUxTradMsg;
3233
dbgprintf("logmsg: %s, flags %x, from '%s', msg %s\n",
3234
textpri(PRItext, sizeof(PRItext) / sizeof(char), pri),
3235
flags, getRcvFrom(pMsg), msg);
3237
/* rger 2005-11-24 (happy thanksgiving!): we now need to check if we have
3238
* a traditional syslog message or one formatted according to syslog-protocol.
3239
* We need to apply different parsers depending on that. We use the
3240
* -protocol VERSION field for the detection.
3242
if(msg[0] == '1' && msg[1] == ' ') {
3243
dbgprintf("Message has syslog-protocol format.\n");
3244
setProtocolVersion(pMsg, 1);
3245
if(parseRFCSyslogMsg(pMsg, flags) == 1)
3247
} else { /* we have legacy syslog */
3248
dbgprintf("Message has legacy syslog format.\n");
3249
setProtocolVersion(pMsg, 0);
3250
if(parseLegacySyslogMsg(pMsg, flags) == 1)
3254
/* ---------------------- END PARSING ---------------- */
3256
/* rgerhards, 2005-10-13: if we consider going multi-threaded, this
3257
* is probably the best point to split between a producer and a consumer
3258
* thread. In general, with the first multi-threaded approach, we should
3259
* NOT try to do more than have a single producer and consumer, at least
3260
* if both are from the current code base. The issue is that this code
3261
* was definitely not written with reentrancy in mind and uses a lot of
3262
* global variables. So it is very dangerous to simply go ahead and multi
3263
* thread it. However, I think there is a clear distinction between
3264
* producer (where data is received) and consumer (where the actions are).
3265
* It should be fairly safe to create a single thread for each and run them
3266
* concurrently, thightly coupled via an in-memory queue. Even with this
3267
* limited multithraeding, benefits are immediate: the lengthy actions
3268
* (database writes!) are de-coupled from the receivers, what should result
3269
* in less likely message loss (loss due to receiver overrun). It also allows
3270
* us to utilize 2-cpu systems, which will soon be common given the current
3271
* advances in multicore CPU hardware. So this is well worth trying.
3272
* Another plus of this two-thread-approach would be that it can easily be configured,
3273
* so if there are compatibility issues with the threading libs, we could simply
3274
* disable it (as a makefile feature).
3275
* There is one important thing to keep in mind when doing this basic
3276
* multithreading. The syslog/tcp message forwarder manipulates a structutre
3277
* that is used by the main thread, which actually sends the data. This
3278
* structure must be guarded by a mutex, else we will have race conditions and
3279
* some very bad things could happen.
3281
* Additional consumer threads might be added relatively easy for new receivers,
3282
* e.g. if we decide to move RFC 3195 via liblogging natively into rsyslogd.
3284
* To aid this functionality, I am moving the rest of the code (the actual
3285
* consumer) to its own method, now called "processMsg()".
3287
* rgerhards, 2005-10-25: as of now, the dual-threading code is now in place.
3288
* It is an optional feature and even when enabled, rsyslogd will run single-threaded
3289
* if it gets any errors during thread creation.
3292
pMsg->msgFlags = flags;
3297
/* rgerhards 2004-11-09: fprintlog() is the actual driver for
3298
* the output channel. It receives the channel description (f) as
3299
* well as the message and outputs them according to the channel
3300
* semantics. The message is typically already contained in the
3301
* channel save buffer (f->f_prevline). This is not only the case
3302
* when a message was already repeated but also when a new message
3304
* rgerhards 2007-08-01: interface changed to use action_t
3306
rsRetVal fprintlog(action_t *pAction)
3308
msg_t *pMsgSave; /* to save current message pointer, necessary to restore
3309
it in case it needs to be updated (e.g. repeated msgs) */
3310
pMsgSave = NULL; /* indicate message poiner not saved */
3314
/* first check if this is a regular message or the repeation of
3315
* a previous message. If so, we need to change the message text
3316
* to "last message repeated n times" and then go ahead and write
3317
* it. Please note that we can not modify the message object, because
3318
* that would update it in other selectors as well. As such, we first
3319
* need to create a local copy of the message, which we than can update.
3320
* rgerhards, 2007-07-10
3322
if(pAction->f_prevcount > 1) {
3325
snprintf((char*)szRepMsg, sizeof(szRepMsg), "last message repeated %d times",
3326
pAction->f_prevcount);
3328
if((pMsg = MsgDup(pAction->f_pMsg)) == NULL) {
3329
/* it failed - nothing we can do against it... */
3330
dbgprintf("Message duplication failed, dropping repeat message.\n");
3332
/* This return is OK. The finalizer frees strings, which are not
3333
* yet allocated. So we can not use the finalizer.
3337
/* We now need to update the other message properties.
3338
* ... RAWMSG is a problem ... Please note that digital
3339
* signatures inside the message are also invalidated.
3341
getCurrTime(&(pMsg->tRcvdAt));
3342
getCurrTime(&(pMsg->tTIMESTAMP));
3343
MsgSetMSG(pMsg, (char*)szRepMsg);
3344
MsgSetRawMsg(pMsg, (char*)szRepMsg);
3346
pMsgSave = pAction->f_pMsg; /* save message pointer for later restoration */
3347
pAction->f_pMsg = pMsg; /* use the new msg (pointer will be restored below) */
3350
dbgprintf("Called fprintlog, logging to %s", modGetStateName(pAction->pMod));
3352
pAction->f_time = now; /* we need this for message repeation processing TODO: why must "now" be global? */
3354
/* When we reach this point, we have a valid, non-disabled action.
3355
* So let's execute it. -- rgerhards, 2007-07-24
3357
/* here we must loop to process all requested strings */
3359
for(i = 0 ; i < pAction->iNumTpls ; ++i) {
3360
CHKiRet(tplToString(pAction->ppTpl[i], pAction->f_pMsg, &pAction->ppMsgs[i]));
3362
/* call configured action */
3363
iRet = pAction->pMod->mod.om.doAction(pAction->ppMsgs, pAction->f_pMsg->msgFlags, pAction->pModData);
3365
if(iRet == RS_RET_DISABLE_ACTION) {
3366
dbgprintf("Action requested to be disabled, done that.\n");
3367
pAction->bEnabled = 0; /* that's it... */
3370
if(iRet == RS_RET_SUSPENDED) {
3371
dbgprintf("Action requested to be suspended, done that.\n");
3372
actionSuspend(pAction);
3375
if(iRet == RS_RET_OK)
3376
pAction->f_prevcount = 0; /* message process, so we start a new cycle */
3380
for(i = 0 ; i < pAction->iNumTpls ; ++i) {
3381
if(pAction->ppMsgs[i] != NULL) {
3382
free(pAction->ppMsgs[i]);
3383
pAction->ppMsgs[i] = NULL;
3387
if(pMsgSave != NULL) {
3388
/* we had saved the original message pointer. That was
3389
* done because we needed to create a temporary one
3390
* (most often for "message repeated n time" handling. If so,
3391
* we need to restore the original one now, so that procesing
3392
* can continue as normal. We also need to discard the temporary
3393
* one, as we do not like memory leaks ;) Please note that the original
3394
* message object will be discarded by our callers, so this is nothing
3395
* of our buisiness. rgerhards, 2007-07-10
3397
MsgDestruct(pAction->f_pMsg);
3398
pAction->f_pMsg = pMsgSave; /* restore it */
3405
static void reapchild()
3407
int saved_errno = errno;
3408
struct sigaction sigAct;
3410
memset(&sigAct, 0, sizeof (sigAct));
3411
sigemptyset(&sigAct.sa_mask);
3412
sigAct.sa_handler = reapchild;
3413
sigaction(SIGCHLD, &sigAct, NULL); /* reset signal handler -ASP */
3415
while(waitpid(-1, NULL, WNOHANG) > 0);
3416
errno = saved_errno;
3420
/* helper to domark to flush the individual action links via llExecFunc
3421
* rgerhards, 2007-08-02
3423
DEFFUNC_llExecFunc(domarkActions)
3425
action_t *pAction = (action_t*) pData;
3427
assert(pAction != NULL);
3429
if (pAction->f_prevcount && now >= REPEATTIME(pAction)) {
3430
dbgprintf("flush %s: repeated %d times, %d sec.\n",
3431
modGetStateName(pAction->pMod), pAction->f_prevcount,
3432
repeatinterval[pAction->f_repeatcount]);
3437
return RS_RET_OK; /* we ignore errors, we can not do anything either way */
3441
/* This method writes mark messages and - some time later - flushes reapeat
3443
* This method was initially called by an alarm handler. As such, it could potentially
3444
* have race-conditons. For details, see
3445
* http://lkml.org/lkml/2005/3/26/37
3446
* http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=301511
3447
* I have now changed it so that the alarm handler only sets a global variable, telling
3448
* the main thread that it must do mark processing. So domark() is now called from the
3449
* main thread itself, which is the only thing to make sure rsyslogd will not do
3450
* strange things. The way it originally was seemed to work because mark occurs very
3451
* seldom. However, the code called was anything else but reentrant, so it was like
3453
* rgerhards, 2005-10-20
3455
static void domark(void)
3457
register selector_t *f;
3459
if (MarkInterval > 0) {
3461
MarkSeq += TIMERINTVL;
3462
if (MarkSeq >= MarkInterval) {
3463
logmsgInternal(LOG_INFO, "-- MARK --", ADDDATE|MARK);
3467
/* see if we need to flush any "message repeated n times"... */
3468
for (f = Files; f != NULL ; f = f->f_next) {
3469
llExecFunc(&f->llActList, domarkActions, NULL);
3475
/* This is the alarm handler setting the global variable for
3476
* domark request. See domark() comments for further details.
3477
* rgerhards, 2005-10-20
3479
static void domarkAlarmHdlr()
3481
struct sigaction sigAct;
3483
bRequestDoMark = 1; /* request alarm */
3485
memset(&sigAct, 0, sizeof (sigAct));
3486
sigemptyset(&sigAct.sa_mask);
3487
sigAct.sa_handler = domarkAlarmHdlr;
3488
sigaction(SIGALRM, &sigAct, NULL);
3490
(void) alarm(TIMERINTVL);
3494
static void debug_switch()
3496
struct sigaction sigAct;
3498
dbgprintf("Switching debugging_on to %s\n", (debugging_on == 0) ? "true" : "false");
3499
debugging_on = (debugging_on == 0) ? 1 : 0;
3501
memset(&sigAct, 0, sizeof (sigAct));
3502
sigemptyset(&sigAct.sa_mask);
3503
sigAct.sa_handler = debug_switch;
3504
sigaction(SIGUSR1, &sigAct, NULL);
3509
* Add a string to error message and send it to logerror()
3510
* The error message is passed to snprintf() and must be
3511
* correctly formatted for it (containing a single %s param).
3512
* rgerhards 2005-09-19
3514
void logerrorSz(char *type, char *errMsg)
3518
snprintf(buf, sizeof(buf), type, errMsg);
3519
buf[sizeof(buf)/sizeof(char) - 1] = '\0'; /* just to be on the safe side... */
3525
* Add an integer to error message and send it to logerror()
3526
* The error message is passed to snprintf() and must be
3527
* correctly formatted for it (containing a single %d param).
3528
* rgerhards 2005-09-19
3530
void logerrorInt(char *type, int errCode)
3534
snprintf(buf, sizeof(buf), type, errCode);
3535
buf[sizeof(buf)/sizeof(char) - 1] = '\0'; /* just to be on the safe side... */
3540
/* Print syslogd errors some place.
3542
void logerror(char *type)
3547
dbgprintf("Called logerr, msg: %s\n", type);
3550
snprintf(buf, sizeof(buf), "%s", type);
3552
snprintf(buf, sizeof(buf), "%s: %s", type, strerror_r(errno, errStr, sizeof(errStr)));
3553
buf[sizeof(buf)/sizeof(char) - 1] = '\0'; /* just to be on the safe side... */
3555
logmsgInternal(LOG_SYSLOG|LOG_ERR, buf, ADDDATE);
3559
/* doDie() is a signal handler. If called, it sets the bFinished variable
3560
* to indicate the program should terminate. However, it does not terminate
3561
* it itself, because that causes issues with multi-threading. The actual
3562
* termination is then done on the main thread. This solution might introduce
3563
* a minimal delay, but it is much cleaner than the approach of doing everything
3564
* inside the signal handler.
3565
* rgerhards, 2005-10-26
3567
static void doDie(int sig)
3569
dbgprintf("DoDie called.\n");
3574
/* die() is called when the program shall end. This typically only occurs
3575
* during sigterm or during the initialization. If you search for places where
3576
* it is called, search for "die", not "die(", because the later will not find
3577
* setting of signal handlers! As die() is intended to shutdown rsyslogd, it is
3578
* safe to call exit() here. Just make sure that die() itself is not called
3579
* at inapropriate places. As a general rule of thumb, it is a bad idea to add
3580
* any calls to die() in new code!
3581
* rgerhards, 2005-10-24
3583
static void die(int sig)
3589
dbgprintf(" exiting on signal %d\n", sig);
3590
(void) snprintf(buf, sizeof(buf) / sizeof(char),
3591
" [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
3592
"\" x-pid=\"%d\"]" " exiting on signal %d.",
3595
logmsgInternal(LOG_SYSLOG|LOG_INFO, buf, ADDDATE);
3598
/* Free ressources and close connections */
3602
/* Worker threads are stopped by freeSelectors() */
3603
queueDelete(pMsgQueue); /* delete fifo here! */
3607
/* now clean up the listener part */
3609
/* Close the UNIX sockets. */
3610
for (i = 0; i < nfunix; i++)
3613
/* Close the UDP inet socket. */
3614
closeUDPListenSockets();
3615
/* Close the TCP inet socket. */
3616
if(sockTCPLstn != NULL && *sockTCPLstn) {
3617
deinit_tcp_listener();
3621
/* Clean-up files. */
3622
for (i = 0; i < nfunix; i++)
3623
if (funixn[i] && funix[i] != -1)
3624
(void)unlink(funixn[i]);
3627
* now clean up the in-memory structures. OK, the OS
3628
* would also take care of that, but if we do it
3629
* ourselfs, this makes finding memory leaks a lot
3634
remove_pid(PidFile);
3635
if(glblHadMemShortage)
3636
dbgprintf("Had memory shortage at least once during the run.\n");
3638
/* de-init some modules */
3639
modExitIminternal();
3641
unregCfSysLineHdlrs();
3643
/* TODO: this would also be the right place to de-init the builtin output modules. We
3644
* do not currently do that, because the module interface does not allow for
3645
* it. This will come some time later (it's essential with loadable modules).
3646
* For the time being, this is a memory leak on exit, but as the process is
3647
* terminated, we do not really bother about it.
3648
* rgerhards, 2007-08-03
3649
* I have added some code now, but all that mod init/de-init should be moved to
3650
* init, so that modules are unloaded and reloaded on HUP to. Eventually it should go
3651
* into freeSelectors() - but that needs to be seen. -- rgerhards, 2007-08-09
3653
modUnloadAndDestructAll();
3655
/* clean up auxiliary data */
3659
dbgprintf("Clean shutdown completed, bye.\n");
3660
exit(0); /* "good" exit, this is the terminator function for rsyslog [die()] */
3664
* Signal handler to terminate the parent process.
3665
* rgerhards, 2005-10-24: this is only called during forking of the
3666
* detached syslogd. I consider this method to be safe.
3668
static void doexit()
3670
exit(0); /* "good" exit, only during child-creation */
3674
/* parse an allowed sender config line and add the allowed senders
3675
* (if the line is correct).
3676
* rgerhards, 2005-09-27
3678
static rsRetVal addAllowedSenderLine(char* pName, uchar** ppRestOfConfLine)
3681
struct AllowedSenders **ppRoot;
3682
struct AllowedSenders **ppLast;
3685
struct NetAddr *uIP = NULL;
3689
assert(pName != NULL);
3690
assert(ppRestOfConfLine != NULL);
3691
assert(*ppRestOfConfLine != NULL);
3695
logerror("config file contains allowed sender list, but rsyslogd "
3696
"compiled without Internet support - line ignored");
3699
if(!strcasecmp(pName, "udp")) {
3700
ppRoot = &pAllowedSenders_UDP;
3701
ppLast = &pLastAllowedSenders_UDP;
3702
} else if(!strcasecmp(pName, "tcp")) {
3703
ppRoot = &pAllowedSenders_TCP;
3704
ppLast = &pLastAllowedSenders_TCP;
3706
logerrorSz("Invalid protocol '%s' in allowed sender "
3707
"list, line ignored", pName);
3711
/* OK, we now know the protocol and have valid list pointers.
3712
* So let's process the entries. We are using the parse class
3715
/* create parser object starting with line string without leading colon */
3716
if((iRet = rsParsConstructFromSz(&pPars, (uchar*) *ppRestOfConfLine) != RS_RET_OK)) {
3717
logerrorInt("Error %d constructing parser object - ignoring allowed sender list", iRet);
3721
while(!parsIsAtEndOfParseString(pPars)) {
3722
if(parsPeekAtCharAtParsPtr(pPars) == '#')
3723
break; /* a comment-sign stops processing of line */
3724
/* now parse a single IP address */
3725
if((iRet = parsAddrWithBits(pPars, &uIP, &iBits)) != RS_RET_OK) {
3726
logerrorInt("Error %d parsing address in allowed sender"
3727
"list - ignoring.", iRet);
3728
rsParsDestruct(pPars);
3731
if((iRet = AddAllowedSender(ppRoot, ppLast, uIP, iBits))
3733
logerrorInt("Error %d adding allowed sender entry "
3734
"- ignoring.", iRet);
3735
rsParsDestruct(pPars);
3738
free (uIP); /* copy stored in AllowedSenders list */
3742
*ppRestOfConfLine += parsGetCurrentPosition(pPars);
3743
return rsParsDestruct(pPars);
3744
#endif /*#ifndef SYSLOG_INET */
3748
/* process a directory and include all of its files into
3749
* the current config file. There is no specific order of inclusion,
3750
* files are included in the order they are read from the directory.
3751
* The caller must have make sure that the provided parameter is
3752
* indeed a directory.
3753
* rgerhards, 2007-08-01
3755
static rsRetVal doIncludeDirectory(uchar *pDirName)
3758
int iEntriesDone = 0;
3762
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
3766
size_t iFileNameLen;
3767
uchar szFullFileName[MAXFNAME];
3769
assert(pDirName != NULL);
3771
if((pDir = opendir((char*) pDirName)) == NULL) {
3772
logerror("error opening include directory");
3773
ABORT_FINALIZE(RS_RET_FOPEN_FAILURE);
3776
/* prepare file name buffer */
3777
iDirNameLen = strlen((char*) pDirName);
3778
memcpy(szFullFileName, pDirName, iDirNameLen);
3780
/* now read the directory */
3782
while(readdir_r(pDir, &u.d, &res) == 0) {
3784
break; /* this also indicates end of directory */
3785
if(res->d_type != DT_REG)
3786
continue; /* we are not interested in special files */
3787
if(res->d_name[0] == '.')
3788
continue; /* these files we are also not interested in */
3790
/* construct filename */
3791
iFileNameLen = strnlen(res->d_name, NAME_MAX);
3792
memcpy(szFullFileName + iDirNameLen, res->d_name, iFileNameLen);
3793
*(szFullFileName + iDirNameLen + iFileNameLen) = '\0';
3794
dbgprintf("including file '%s'\n", szFullFileName);
3795
processConfFile(szFullFileName);
3796
/* we deliberately ignore the iRet of processConfFile() - this is because
3797
* failure to process one file does not mean all files will fail. By ignoring,
3798
* we retry with the next file, which is the best thing we can do. -- rgerhards, 2007-08-01
3802
if(iEntriesDone == 0) {
3803
/* I just make it a debug output, because I can think of a lot of cases where it
3804
* makes sense not to have any files. E.g. a system maintainer may place a $Include
3805
* into the config file just in case, when additional modules be installed. When none
3806
* are installed, the directory will be empty, which is fine. -- rgerhards 2007-08-01
3808
dbgprintf("warning: the include directory contained no files - this may be ok.\n");
3819
/* process a $include config line. That type of line requires
3820
* inclusion of another file.
3821
* rgerhards, 2007-08-01
3823
static rsRetVal doIncludeLine(uchar **pp, __attribute__((unused)) void* pVal)
3826
uchar cfgFile[MAXFNAME];
3829
assert(*pp != NULL);
3831
if(getSubString(pp, (char*) cfgFile, sizeof(cfgFile) / sizeof(uchar), ' ') != 0) {
3832
logerror("could not extract group name");
3833
ABORT_FINALIZE(RS_RET_NOT_FOUND);
3836
if(*(cfgFile+strlen((char*) cfgFile) - 1) == '/') {
3837
dbgprintf("requested to include directory '%s'\n", cfgFile);
3838
iRet = doIncludeDirectory(cfgFile);
3840
dbgprintf("Requested to include config file '%s'\n", cfgFile);
3841
iRet = processConfFile(cfgFile);
3849
/* process a $ModLoad config line.
3850
* As of now, it is a dummy, that will later evolve into the
3851
* loader for plug-ins.
3852
* rgerhards, 2007-07-21
3853
* varmojfekoj added support for dynamically loadable modules on 2007-08-13
3854
* rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is
3855
* called below. This is ok because modules are currently only loaded during
3856
* configuration file processing, which is executed on a single thread. Should we
3857
* change that design at any stage (what is unlikely), we need to find a
3860
static rsRetVal doModLoad(uchar **pp, __attribute__((unused)) void* pVal)
3867
void *pModHdlr, *pModInit;
3870
assert(*pp != NULL);
3872
if(getSubString(pp, (char*) szName, sizeof(szName) / sizeof(uchar), ' ') != 0) {
3873
logerror("could not extract module name");
3874
ABORT_FINALIZE(RS_RET_NOT_FOUND);
3877
/* this below is a quick and dirty hack to provide compatibility with the
3878
* $ModLoad MySQL forward compatibility statement. TODO: clean this up
3879
* For the time being, it is clean enough, it just needs to be done
3880
* differently when we have a full design for loadable plug-ins. For the
3881
* time being, we just mangle the names a bit.
3882
* rgerhards, 2007-08-14
3884
if(!strcmp((char*) szName, "MySQL"))
3885
pModName = (uchar*) "ommysql.so";
3889
dbgprintf("Requested to load module '%s'\n", szName);
3891
if(*pModName == '/') {
3892
*szPath = '\0'; /* we do not need to append the path - its already in the module name */
3894
strncpy((char *) szPath, (pModDir == NULL) ? _PATH_MODDIR : (char*) pModDir, sizeof(szPath));
3896
strncat((char *) szPath, (char *) pModName, sizeof(szPath) - strlen((char*) szPath) - 1);
3897
if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) {
3898
snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlopen: %s\n", szPath, dlerror());
3899
errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
3900
logerror((char *) errMsg);
3901
ABORT_FINALIZE(RS_RET_ERR);
3903
if(!(pModInit = dlsym(pModHdlr, "modInit"))) {
3904
snprintf((char *) errMsg, sizeof(errMsg), "could not load module '%s', dlsym: %s\n", szPath, dlerror());
3905
errMsg[sizeof(errMsg)/sizeof(uchar) - 1] = '\0';
3906
logerror((char *) errMsg);
3908
ABORT_FINALIZE(RS_RET_ERR);
3910
if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK)
3913
skipWhiteSpace(pp); /* skip over any whitespace */
3919
/* parse and interpret a $-config line that starts with
3920
* a name (this is common code). It is parsed to the name
3921
* and then the proper sub-function is called to handle
3922
* the actual directive.
3923
* rgerhards 2004-11-17
3924
* rgerhards 2005-06-21: previously only for templates, now
3927
static rsRetVal doNameLine(uchar **pp, void* pVal)
3931
enum eDirective eDir;
3938
eDir = (enum eDirective) pVal; /* this time, it actually is NOT a pointer! */
3940
if(getSubString(&p, szName, sizeof(szName) / sizeof(char), ',') != 0) {
3941
logerror("Invalid config line: could not extract name - line ignored");
3942
ABORT_FINALIZE(RS_RET_NOT_FOUND);
3945
++p; /* comma was eaten */
3947
/* we got the name - now we pass name & the rest of the string
3948
* to the subfunction. It makes no sense to do further
3949
* parsing here, as this is in close interaction with the
3950
* respective subsystem. rgerhards 2004-11-17
3955
tplAddLine(szName, &p);
3957
case DIR_OUTCHANNEL:
3958
ochAddLine(szName, &p);
3960
case DIR_ALLOWEDSENDER:
3961
addAllowedSenderLine(szName, &p);
3963
default:/* we do this to avoid compiler warning - not all
3964
* enum values call this function, so an incomplete list
3965
* is quite ok (but then we should not run into this code,
3966
* so at least we log a debug warning).
3968
dbgprintf("INTERNAL ERROR: doNameLine() called with invalid eDir %d.\n",
3980
/* set the action resume interval
3982
static rsRetVal setActionResumeInterval(void __attribute__((unused)) *pVal, int iNewVal)
3984
return actionSetGlobalResumeInterval(iNewVal);
3988
/* set the processes umask (upon configuration request)
3990
static rsRetVal setUmask(void __attribute__((unused)) *pVal, int iUmask)
3993
dbgprintf("umask set to 0%3.3o.\n", iUmask);
3999
/* Parse and interpret a system-directive in the config line
4000
* A system directive is one that starts with a "$" sign. It offers
4001
* extended configuration parameters.
4002
* 2004-11-17 rgerhards
4004
rsRetVal cfsysline(uchar *p)
4008
uchar errMsg[128]; /* for dynamic error messages */
4012
if(getSubString(&p, (char*) szCmd, sizeof(szCmd) / sizeof(uchar), ' ') != 0) {
4013
logerror("Invalid $-configline - could not extract command - line ignored\n");
4014
ABORT_FINALIZE(RS_RET_NOT_FOUND);
4017
/* we now try and see if we can find the command in the registered
4018
* list of cfsysline handlers. -- rgerhards, 2007-07-31
4020
CHKiRet(processCfSysLineCommand(szCmd, &p));
4022
/* now check if we have some extra characters left on the line - that
4023
* should not be the case. Whitespace is OK, but everything else should
4024
* trigger a warning (that may be an indication of undesired behaviour).
4025
* An exception, of course, are comments (starting with '#').
4026
* rgerhards, 2007-07-04
4030
if(*p && *p != '#') { /* we have a non-whitespace, so let's complain */
4031
snprintf((char*) errMsg, sizeof(errMsg)/sizeof(uchar),
4032
"error: extra characters in config line ignored: '%s'", p);
4034
logerror((char*) errMsg);
4042
/* helper to freeSelectors(), used with llExecFunc() to flush
4043
* pending output. -- rgerhards, 2007-08-02
4045
DEFFUNC_llExecFunc(freeSelectorsActions)
4047
action_t *pAction = (action_t*) pData;
4049
assert(pAction != NULL);
4051
/* flush any pending output */
4052
if(pAction->f_prevcount) {
4056
return RS_RET_OK; /* never fails ;) */
4060
/* Close all open log files and free selector descriptor array.
4062
static void freeSelectors(void)
4068
dbgprintf("Freeing log structures.\n");
4070
/* just in case, we flush the emergency log. If error messages occur after
4071
* this stage, we loose them, but that's ok. With multi-threading, this can
4072
* never happen. -- rgerhards, 2007-08-03
4074
processImInternal();
4076
/* we need first to flush, then wait for all messages to be processed
4077
* (stopWoker() does that), then we can free the structures.
4079
for(f = Files ; f != NULL ; f = f->f_next) {
4080
llExecFunc(&f->llActList, freeSelectorsActions, NULL);
4083
# ifdef USE_PTHREADS
4091
selectorDestruct(fPrev);
4094
/* Reflect the deletion of the selectors linked list. */
4101
/* helper to dbPrintInitInfo, to print out all actions via
4102
* the llExecFunc() facility.
4103
* rgerhards, 2007-08-02
4105
DEFFUNC_llExecFunc(dbgPrintInitInfoAction)
4108
iRet = actionDbgPrint((action_t*) pData);
4114
/* print debug information as part of init(). This pretty much
4115
* outputs the whole config of rsyslogd. I've moved this code
4116
* out of init() to clean it somewhat up.
4117
* rgerhards, 2007-07-31
4119
static void dbgPrintInitInfo(void)
4121
register selector_t *f;
4125
printf("\nActive selectors:\n");
4126
for (f = Files; f != NULL ; f = f->f_next) {
4127
printf("Selector %d:\n", iSelNbr++);
4128
if(f->pCSProgNameComp != NULL)
4129
printf("tag: '%s'\n", rsCStrGetSzStrNoNULL(f->pCSProgNameComp));
4130
if(f->eHostnameCmpMode != HN_NO_COMP)
4131
printf("hostname: %s '%s'\n",
4132
f->eHostnameCmpMode == HN_COMP_MATCH ?
4134
rsCStrGetSzStrNoNULL(f->pCSHostnameComp));
4135
if(f->f_filter_type == FILTER_PRI) {
4136
for (i = 0; i <= LOG_NFACILITIES; i++)
4137
if (f->f_filterData.f_pmask[i] == TABLE_NOPRI)
4140
printf("%2X ", f->f_filterData.f_pmask[i]);
4142
printf("PROPERTY-BASED Filter:\n");
4143
printf("\tProperty.: '%s'\n",
4144
rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSPropName));
4145
printf("\tOperation: ");
4146
if(f->f_filterData.prop.isNegated)
4148
printf("'%s'\n", getFIOPName(f->f_filterData.prop.operation));
4149
printf("\tValue....: '%s'\n",
4150
rsCStrGetSzStrNoNULL(f->f_filterData.prop.pCSCompValue));
4151
printf("\tAction...: ");
4154
printf("\nActions:\n");
4155
llExecFunc(&f->llActList, dbgPrintInitInfoAction, NULL); /* actions */
4160
if(bDebugPrintTemplateList)
4162
if(bDebugPrintModuleList)
4166
if(bDebugPrintCfSysLineHandlerList)
4167
dbgPrintCfSysLineHandlers();
4170
/* now the allowedSender lists: */
4171
PrintAllowedSenders(1); /* UDP */
4172
PrintAllowedSenders(2); /* TCP */
4174
#endif /* #ifdef SYSLOG_INET */
4176
printf("Messages with malicious PTR DNS Records are %sdropped.\n",
4177
bDropMalPTRMsgs ? "" : "not ");
4179
printf("Control characters are %sreplaced upon reception.\n",
4180
bEscapeCCOnRcv? "" : "not ");
4183
printf("Control character escape sequence prefix is '%c'.\n",
4187
printf("Main queue size %d messages.\n", iMainMsgQueueSize);
4192
/* process a configuration file
4193
* started with code from init() by rgerhards on 2007-07-31
4195
static rsRetVal processConfFile(uchar *pConfFile)
4200
selector_t *fCurr = NULL;
4206
uchar cline[BUFSIZ];
4208
assert(pConfFile != NULL);
4210
if((cf = fopen((char*)pConfFile, "r")) == NULL) {
4211
ABORT_FINALIZE(RS_RET_FOPEN_FAILURE);
4214
/* Now process the file.
4218
while (fgets((char*)cline, sizeof(cbuf) - (cline - cbuf), cf) != NULL) {
4220
while (fgets(cline, sizeof(cline), cf) != NULL) {
4223
/* drop LF - TODO: make it better, replace fgets(), but its clean as it is */
4224
if(cline[strlen((char*)cline)-1] == '\n') {
4225
cline[strlen((char*)cline) -1] = '\0';
4227
/* check for end-of-section, comments, strip off trailing
4228
* spaces and newline character.
4232
if (*p == '\0' || *p == '#')
4236
strcpy((char*)cline, (char*)p);
4238
for (p = (uchar*) strchr((char*)cline, '\0'); isspace((int) *--p););
4241
if ((p - cbuf) > BUFSIZ - 30) {
4242
/* Oops the buffer is full - what now? */
4252
*++p = '\0'; // TODO: check this
4254
/* we now have the complete line, and are positioned at the first non-whitespace
4255
* character. So let's process it
4258
if(cfline(cbuf, &fCurr) != RS_RET_OK) {
4260
if(cfline((uchar*)cline, &fCurr) != RS_RET_OK) {
4262
/* we log a message, but otherwise ignore the error. After all, the next
4263
* line can be correct. -- rgerhards, 2007-08-02
4265
uchar szErrLoc[MAXFNAME + 64];
4266
dbgprintf("config line NOT successfully processed\n");
4267
snprintf((char*)szErrLoc, sizeof(szErrLoc) / sizeof(uchar),
4268
"%s, line %d", pConfFile, iLnNbr);
4269
logerrorSz("the last error occured in %s", (char*)szErrLoc);
4273
/* we probably have one selector left to be added - so let's do that now */
4274
CHKiRet(selectorAddList(fCurr));
4276
/* close the configuration file */
4280
if(iRet != RS_RET_OK) {
4283
selectorDestruct(fCurr);
4284
dbgprintf("error %d processing config file '%s'; os error (if any): %s\n",
4285
iRet, pConfFile, strerror_r(errno, errStr, sizeof(errStr)));
4291
/* INIT -- Initialize syslogd from configuration table
4292
* init() is called at initial startup AND each time syslogd is HUPed
4294
static void init(void)
4303
char bufStartUpMsg[512];
4305
struct sigaction sigAct;
4307
/* initialize some static variables */
4308
pDfltHostnameCmp = NULL;
4309
pDfltProgNameCmp = NULL;
4310
eDfltHostnameCmpMode = HN_NO_COMP;
4315
if (pAllowedSenders_UDP != NULL) {
4316
clearAllowedSenders (pAllowedSenders_UDP);
4317
pAllowedSenders_UDP = NULL;
4320
if (pAllowedSenders_TCP != NULL) {
4321
clearAllowedSenders (pAllowedSenders_TCP);
4322
pAllowedSenders_TCP = NULL;
4326
assert (pAllowedSenders_UDP == NULL &&
4327
pAllowedSenders_TCP == NULL );
4329
/* I was told by an IPv6 expert that calling getservbyname() seems to be
4330
* still valid, at least for the use case we have. So I re-enabled that
4331
* code. rgerhards, 2007-07-02
4333
if(!strcmp(LogPort, "0")) {
4334
/* we shall use the default syslog/udp port, so let's
4336
* NOTE: getservbyname() is not thread-safe, but this is OK as
4337
* it is called only during init, in single-threading mode.
4339
sp = getservbyname("syslog", "udp");
4342
logerror("Could not find syslog/udp port in /etc/services. "
4343
"Now using IANA-assigned default of 514.");
4346
/* we can dynamically allocate memory here and do NOT need
4347
* to care about freeing it because even though init() is
4348
* called on each restart, the LogPort can never again be
4349
* "0". So we will only once run into this part of the code
4350
* here. rgerhards, 2007-07-02
4351
* We save ourselfs the hassle of dynamic memory management
4352
* for the very same reason.
4354
static char defPort[8];
4355
snprintf(defPort, sizeof(defPort), "%d", ntohs(sp->s_port));
4360
dbgprintf("rsyslog %s.\n", VERSION);
4361
dbgprintf("Called init.\n");
4363
/* Close all open log files and free log descriptor array. */
4366
/* Unload all non-static modules */
4367
dbgprintf("Unloading non-static modules.\n");
4368
modUnloadAndDestructDynamic();
4370
dbgprintf("Clearing templates.\n");
4374
if(pMsgQueue != NULL) {
4375
dbgprintf("deleting message queue\n");
4376
queueDelete(pMsgQueue); /* delete fifo here! */
4381
/* re-setting values to defaults (where applicable) */
4382
/* TODO: once we have loadable modules, we must re-visit this code. The reason is
4383
* that config variables are not re-set, because the module is not yet loaded. On
4384
* the other hand, that doesn't matter, because the module got unloaded and is then
4385
* re-loaded, so the variables should be re-set via that way. In any case, we should
4386
* think about the whole situation when we implement loadable plugins.
4387
* rgerhards, 2007-07-31
4389
cfsysline((uchar*)"ResetConfigVariables");
4391
/* open the configuration file */
4392
if((iRet = processConfFile(ConfFile)) != RS_RET_OK) {
4393
/* rgerhards: this code is executed to set defaults when the
4394
* config file could not be opened. We might think about
4395
* abandoning the run in this case - but this, too, is not
4396
* very clever... So we stick with what we have.
4397
* We ignore any errors while doing this - we would be lost anyhow...
4399
selector_t *f = NULL;
4400
char szTTYNameBuf[TTY_NAME_MAX+1]; /* +1 for NULL character */
4401
dbgprintf("primary config file could not be opened - using emergency definitions.\n");
4402
cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f);
4403
cfline((uchar*)"*.PANIC\t*", &f);
4404
if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) {
4405
snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf);
4406
cfline((uchar*)cbuf, &f);
4411
/* we are now done with reading the configuration. This is the right time to
4412
* free some objects that were just needed for loading it. rgerhards 2005-10-19
4414
if(pDfltHostnameCmp != NULL) {
4415
rsCStrDestruct(pDfltHostnameCmp);
4416
pDfltHostnameCmp = NULL;
4419
if(pDfltProgNameCmp != NULL) {
4420
rsCStrDestruct(pDfltProgNameCmp);
4421
pDfltProgNameCmp = NULL;
4424
#ifdef SYSLOG_UNIXAF
4425
for (i = startIndexUxLocalSockets ; i < nfunix ; i++) {
4427
/* Don't close the socket, preserve it instead
4431
if ((funix[i] = create_unix_socket(funixn[i])) != -1)
4432
dbgprintf("Opened UNIX socket `%s' (fd %d).\n", funixn[i], funix[i]);
4437
/* I have moved initializing UDP sockets before the TCP sockets. This ensures
4438
* they are as soon ready for reception as possible. Of course, it is only a
4439
* very small window of exposure, but it doesn't hurt to limit the message
4440
* loss risk to as low as possible - especially if it costs nothing...
4441
* rgerhards, 2007-06-28
4443
if(Forwarding || AcceptRemote) {
4444
if (finet == NULL) {
4445
if((finet = create_udp_socket()) != NULL)
4446
dbgprintf("Opened %d syslog UDP port(s).\n", *finet);
4449
/* this case can happen during HUP processing. */
4450
closeUDPListenSockets();
4454
if(sockTCPLstn == NULL) {
4455
/* even when doing a re-init, we do not shut down and
4456
* re-open the TCP socket. That would break existing TCP
4457
* session, which we do not desire. Should at some time arise
4458
* need to do that, I recommend controlling that via a
4459
* user-selectable option. rgerhards, 2007-06-21
4461
if((sockTCPLstn = create_tcp_socket()) != NULL) {
4462
dbgprintf("Opened %d syslog TCP port(s).\n", *sockTCPLstn);
4468
# ifdef USE_PTHREADS
4469
/* create message queue */
4470
pMsgQueue = queueInit();
4471
if(pMsgQueue == NULL) {
4473
logerror("error: could not create message queue - running single-threaded!\n");
4485
/* we now generate the startup message. It now includes everything to
4486
* identify this instance. -- rgerhards, 2005-08-17
4488
snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char),
4489
" [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
4490
"\" x-pid=\"%d\"][x-configInfo udpReception=\"%s\" " \
4491
"udpPort=\"%s\" tcpReception=\"%s\" tcpPort=\"%s\"]" \
4495
AcceptRemote ? "Yes" : "No", LogPort,
4496
bEnableTCP ? "Yes" : "No", TCPLstnPort
4498
"No", "0", "No", "0"
4499
#endif /* #ifdef SYSLOG_INET */
4501
logmsgInternal(LOG_SYSLOG|LOG_INFO, bufStartUpMsg, ADDDATE);
4503
memset(&sigAct, 0, sizeof (sigAct));
4504
sigemptyset(&sigAct.sa_mask);
4505
sigAct.sa_handler = sighup_handler;
4506
sigaction(SIGHUP, &sigAct, NULL);
4508
dbgprintf(" restarted.\n");
4512
/* Helper to cfline() and its helpers. Parses a template name
4513
* from an "action" line. Must be called with the Line pointer
4514
* pointing to the first character after the semicolon.
4515
* rgerhards 2004-11-19
4516
* changed function to work with OMSR. -- rgerhards, 2007-07-27
4517
* the default template is to be used when no template is specified.
4519
rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName)
4527
assert(*pp != NULL);
4528
assert(pOMSR != NULL);
4531
/* a template must follow - search it and complain, if not found
4536
else if(*p != '\0' && *p != '#') {
4537
logerror("invalid character in selector line - ';template' expected");
4542
skipWhiteSpace(&p); /* go to begin of template name */
4545
/* no template specified, use the default */
4546
/* TODO: check NULL ptr */
4547
tplName = (uchar*) strdup((char*)dfltTplName);
4549
/* template specified, pick it up */
4550
if((pStrB = rsCStrConstruct()) == NULL) {
4551
glblHadMemShortage = 1;
4552
iRet = RS_RET_OUT_OF_MEMORY;
4556
/* now copy the string */
4557
while(*p && *p != '#' && !isspace((int) *p)) {
4558
CHKiRet(rsCStrAppendChar(pStrB, *p));
4561
CHKiRet(rsCStrFinish(pStrB));
4562
CHKiRet(rsCStrConvSzStrAndDestruct(pStrB, &tplName, 0));
4565
iRet = OMSRsetEntry(pOMSR, iEntry, tplName, iTplOpts);
4566
if(iRet != RS_RET_OK) goto finalize_it;
4574
/* Helper to cfline(). Parses a file name up until the first
4575
* comma and then looks for the template specifier. Tries
4576
* to find that template.
4577
* rgerhards 2004-11-18
4578
* parameter pFileName must point to a buffer large enough
4579
* to hold the largest possible filename.
4580
* rgerhards, 2007-07-25
4581
* updated to include OMSR pointer -- rgerhards, 2007-07-27
4583
rsRetVal cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts)
4585
register uchar *pName;
4589
assert(pOMSR != NULL);
4592
i = 1; /* we start at 1 so that we reseve space for the '\0'! */
4593
while(*p && *p != ';' && i < MAXFNAME) {
4599
iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, (uchar*) " TradFmt");
4606
* Helper to cfline(). This function takes the filter part of a traditional, PRI
4607
* based line and decodes the PRIs given in the selector line. It processed the
4608
* line up to the beginning of the action part. A pointer to that beginnig is
4609
* passed back to the caller.
4610
* rgerhards 2005-09-15
4612
static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f)
4624
assert(pline != NULL);
4625
assert(*pline != NULL);
4628
dbgprintf(" - traditional PRI filter\n");
4629
errno = 0; /* keep strerror_r() stuff out of logerror messages */
4631
f->f_filter_type = FILTER_PRI;
4632
/* Note: file structure is pre-initialized to zero because it was
4633
* created with calloc()!
4635
for (i = 0; i <= LOG_NFACILITIES; i++) {
4636
f->f_filterData.f_pmask[i] = TABLE_NOPRI;
4639
/* scan through the list of selectors */
4640
for (p = *pline; *p && *p != '\t' && *p != ' ';) {
4642
/* find the end of this facility name list */
4643
for (q = p; *q && *q != '\t' && *q++ != '.'; )
4646
/* collect priority name */
4647
for (bp = buf; *q && !strchr("\t ,;", *q); )
4652
while (strchr(",;", *q))
4655
/* decode priority name */
4656
if ( *buf == '!' ) {
4658
for (bp=buf; *(bp+1); bp++)
4668
pri = decode(&buf[1], PriNames);
4672
pri = decode(buf, PriNames);
4676
snprintf((char*) xbuf, sizeof(xbuf), "unknown priority name \"%s\"", buf);
4677
logerror((char*) xbuf);
4681
/* scan facilities */
4682
while (*p && !strchr("\t .;", *p)) {
4683
for (bp = buf; *p && !strchr("\t ,;.", *p); )
4687
for (i = 0; i <= LOG_NFACILITIES; i++) {
4688
if ( pri == INTERNAL_NOPRI ) {
4690
f->f_filterData.f_pmask[i] = TABLE_ALLPRI;
4692
f->f_filterData.f_pmask[i] = TABLE_NOPRI;
4694
else if ( singlpri ) {
4696
f->f_filterData.f_pmask[i] &= ~(1<<pri);
4698
f->f_filterData.f_pmask[i] |= (1<<pri);
4702
if ( pri == TABLE_ALLPRI ) {
4704
f->f_filterData.f_pmask[i] = TABLE_NOPRI;
4706
f->f_filterData.f_pmask[i] = TABLE_ALLPRI;
4711
for (i2= 0; i2 <= pri; ++i2)
4712
f->f_filterData.f_pmask[i] &= ~(1<<i2);
4714
for (i2= 0; i2 <= pri; ++i2)
4715
f->f_filterData.f_pmask[i] |= (1<<i2);
4720
i = decode(buf, FacNames);
4723
snprintf((char*) xbuf, sizeof(xbuf), "unknown facility name \"%s\"", buf);
4724
logerror((char*) xbuf);
4728
if ( pri == INTERNAL_NOPRI ) {
4730
f->f_filterData.f_pmask[i >> 3] = TABLE_ALLPRI;
4732
f->f_filterData.f_pmask[i >> 3] = TABLE_NOPRI;
4733
} else if ( singlpri ) {
4735
f->f_filterData.f_pmask[i >> 3] &= ~(1<<pri);
4737
f->f_filterData.f_pmask[i >> 3] |= (1<<pri);
4739
if ( pri == TABLE_ALLPRI ) {
4741
f->f_filterData.f_pmask[i >> 3] = TABLE_NOPRI;
4743
f->f_filterData.f_pmask[i >> 3] = TABLE_ALLPRI;
4746
for (i2= 0; i2 <= pri; ++i2)
4747
f->f_filterData.f_pmask[i >> 3] &= ~(1<<i2);
4749
for (i2= 0; i2 <= pri; ++i2)
4750
f->f_filterData.f_pmask[i >> 3] |= (1<<i2);
4754
while (*p == ',' || *p == ' ')
4761
/* skip to action part */
4762
while (*p == '\t' || *p == ' ')
4771
* Helper to cfline(). This function takes the filter part of a property
4772
* based filter and decodes it. It processes the line up to the beginning
4773
* of the action part. A pointer to that beginnig is passed back to the caller.
4774
* rgerhards 2005-09-15
4776
static rsRetVal cflineProcessPropFilter(uchar **pline, register selector_t *f)
4779
rsCStrObj *pCSCompOp;
4781
int iOffset; /* for compare operations */
4783
assert(pline != NULL);
4784
assert(*pline != NULL);
4787
dbgprintf(" - property-based filter\n");
4788
errno = 0; /* keep strerror_r() stuff out of logerror messages */
4790
f->f_filter_type = FILTER_PROP;
4792
/* create parser object starting with line string without leading colon */
4793
if((iRet = rsParsConstructFromSz(&pPars, (*pline)+1)) != RS_RET_OK) {
4794
logerrorInt("Error %d constructing parser object - ignoring selector", iRet);
4799
iRet = parsDelimCStr(pPars, &f->f_filterData.prop.pCSPropName, ',', 1, 1);
4800
if(iRet != RS_RET_OK) {
4801
logerrorInt("error %d parsing filter property - ignoring selector", iRet);
4802
rsParsDestruct(pPars);
4806
/* read operation */
4807
iRet = parsDelimCStr(pPars, &pCSCompOp, ',', 1, 1);
4808
if(iRet != RS_RET_OK) {
4809
logerrorInt("error %d compare operation property - ignoring selector", iRet);
4810
rsParsDestruct(pPars);
4814
/* we now first check if the condition is to be negated. To do so, we first
4815
* must make sure we have at least one char in the param and then check the
4817
* rgerhards, 2005-09-26
4819
if(rsCStrLen(pCSCompOp) > 0) {
4820
if(*rsCStrGetBufBeg(pCSCompOp) == '!') {
4821
f->f_filterData.prop.isNegated = 1;
4822
iOffset = 1; /* ignore '!' */
4824
f->f_filterData.prop.isNegated = 0;
4828
f->f_filterData.prop.isNegated = 0;
4832
if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "contains", 8)) {
4833
f->f_filterData.prop.operation = FIOP_CONTAINS;
4834
} else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "isequal", 7)) {
4835
f->f_filterData.prop.operation = FIOP_ISEQUAL;
4836
} else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (uchar*) "startswith", 10)) {
4837
f->f_filterData.prop.operation = FIOP_STARTSWITH;
4838
} else if(!rsCStrOffsetSzStrCmp(pCSCompOp, iOffset, (unsigned char*) "regex", 5)) {
4839
f->f_filterData.prop.operation = FIOP_REGEX;
4841
logerrorSz("error: invalid compare operation '%s' - ignoring selector",
4842
(char*) rsCStrGetSzStrNoNULL(pCSCompOp));
4844
rsCStrDestruct (pCSCompOp); /* no longer needed */
4846
/* read compare value */
4847
iRet = parsQuotedCStr(pPars, &f->f_filterData.prop.pCSCompValue);
4848
if(iRet != RS_RET_OK) {
4849
logerrorInt("error %d compare value property - ignoring selector", iRet);
4850
rsParsDestruct(pPars);
4854
/* skip to action part */
4855
if((iRet = parsSkipWhitespace(pPars)) != RS_RET_OK) {
4856
logerrorInt("error %d skipping to action part - ignoring selector", iRet);
4857
rsParsDestruct(pPars);
4862
*pline = *pline + rsParsGetParsePointer(pPars) + 1;
4863
/* we are adding one for the skipped initial ":" */
4865
return rsParsDestruct(pPars);
4870
* Helper to cfline(). This function interprets a BSD host selector line
4871
* from the config file ("+/-hostname"). It stores it for further reference.
4872
* rgerhards 2005-10-19
4874
static rsRetVal cflineProcessHostSelector(uchar **pline)
4878
assert(pline != NULL);
4879
assert(*pline != NULL);
4880
assert(**pline == '-' || **pline == '+');
4882
dbgprintf(" - host selector line\n");
4884
/* check include/exclude setting */
4885
if(**pline == '+') {
4886
eDfltHostnameCmpMode = HN_COMP_MATCH;
4887
} else { /* we do not check for '-', it must be, else we wouldn't be here */
4888
eDfltHostnameCmpMode = HN_COMP_NOMATCH;
4890
(*pline)++; /* eat + or - */
4892
/* the below is somewhat of a quick hack, but it is efficient (this is
4893
* why it is in here. "+*" resets the tag selector with BSD syslog. We mimic
4894
* this, too. As it is easy to check that condition, we do not fire up a
4895
* parser process, just make sure we do not address beyond our space.
4896
* Order of conditions in the if-statement is vital! rgerhards 2005-10-18
4898
if(**pline != '\0' && **pline == '*' && *(*pline+1) == '\0') {
4899
dbgprintf("resetting BSD-like hostname filter\n");
4900
eDfltHostnameCmpMode = HN_NO_COMP;
4901
if(pDfltHostnameCmp != NULL) {
4902
if((iRet = rsCStrSetSzStr(pDfltHostnameCmp, NULL)) != RS_RET_OK)
4906
dbgprintf("setting BSD-like hostname filter to '%s'\n", *pline);
4907
if(pDfltHostnameCmp == NULL) {
4908
/* create string for parser */
4909
if((iRet = rsCStrConstructFromszStr(&pDfltHostnameCmp, *pline)) != RS_RET_OK)
4911
} else { /* string objects exists, just update... */
4912
if((iRet = rsCStrSetSzStr(pDfltHostnameCmp, *pline)) != RS_RET_OK)
4921
* Helper to cfline(). This function interprets a BSD tag selector line
4922
* from the config file ("!tagname"). It stores it for further reference.
4923
* rgerhards 2005-10-18
4925
static rsRetVal cflineProcessTagSelector(uchar **pline)
4929
assert(pline != NULL);
4930
assert(*pline != NULL);
4931
assert(**pline == '!');
4933
dbgprintf(" - programname selector line\n");
4935
(*pline)++; /* eat '!' */
4937
/* the below is somewhat of a quick hack, but it is efficient (this is
4938
* why it is in here. "!*" resets the tag selector with BSD syslog. We mimic
4939
* this, too. As it is easy to check that condition, we do not fire up a
4940
* parser process, just make sure we do not address beyond our space.
4941
* Order of conditions in the if-statement is vital! rgerhards 2005-10-18
4943
if(**pline != '\0' && **pline == '*' && *(*pline+1) == '\0') {
4944
dbgprintf("resetting programname filter\n");
4945
if(pDfltProgNameCmp != NULL) {
4946
if((iRet = rsCStrSetSzStr(pDfltProgNameCmp, NULL)) != RS_RET_OK)
4950
dbgprintf("setting programname filter to '%s'\n", *pline);
4951
if(pDfltProgNameCmp == NULL) {
4952
/* create string for parser */
4953
if((iRet = rsCStrConstructFromszStr(&pDfltProgNameCmp, *pline)) != RS_RET_OK)
4955
} else { /* string objects exists, just update... */
4956
if((iRet = rsCStrSetSzStr(pDfltProgNameCmp, *pline)) != RS_RET_OK)
4964
/* add an Action to the current selector
4965
* The pOMSR is freed, as it is not needed after this function.
4966
* Note: this function pulls global data that specifies action config state.
4967
* rgerhards, 2007-07-27
4969
rsRetVal addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringRequest_t *pOMSR, int bSuspended)
4978
assert(ppAction != NULL);
4979
assert(pMod != NULL);
4980
assert(pOMSR != NULL);
4981
dbgprintf("Module %s processed this config line.\n", modGetName(pMod));
4983
CHKiRet(actionConstruct(&pAction)); /* create action object first */
4984
pAction->pMod = pMod;
4985
pAction->pModData = pModData;
4986
pAction->bExecWhenPrevSusp = bActExecWhenPrevSusp;
4988
/* check if we can obtain the template pointers - TODO: move to separat function? */
4989
pAction->iNumTpls = OMSRgetEntryCount(pOMSR);
4990
assert(pAction->iNumTpls >= 0); /* only debug check because this "can not happen" */
4991
/* please note: iNumTpls may validly be zero. This is the case if the module
4992
* does not request any templates. This sounds unlikely, but an actual example is
4993
* the discard action, which does not require a string. -- rgerhards, 2007-07-30
4995
if(pAction->iNumTpls > 0) {
4996
/* we first need to create the template pointer array */
4997
if((pAction->ppTpl = calloc(pAction->iNumTpls, sizeof(struct template *))) == NULL) {
4998
glblHadMemShortage = 1;
4999
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
5001
/* and now the array for doAction() message pointers */
5002
if((pAction->ppMsgs = calloc(pAction->iNumTpls, sizeof(uchar *))) == NULL) {
5003
glblHadMemShortage = 1;
5004
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
5008
for(i = 0 ; i < pAction->iNumTpls ; ++i) {
5009
CHKiRet(OMSRgetEntry(pOMSR, i, &pTplName, &iTplOpts));
5010
/* Ok, we got everything, so it now is time to look up the
5011
* template (Hint: templates MUST be defined before they are
5014
if((pAction->ppTpl[i] = tplFind((char*)pTplName, strlen((char*)pTplName))) == NULL) {
5015
snprintf(errMsg, sizeof(errMsg) / sizeof(char),
5016
" Could not find template '%s' - action disabled\n",
5020
ABORT_FINALIZE(RS_RET_NOT_FOUND);
5022
/* check required template options */
5023
if( (iTplOpts & OMSR_RQD_TPL_OPT_SQL)
5024
&& (pAction->ppTpl[i]->optFormatForSQL == 0)) {
5026
logerror("Action disabled. To use this action, you have to specify "
5027
"the SQL or stdSQL option in your template!\n");
5028
ABORT_FINALIZE(RS_RET_RQD_TPLOPT_MISSING);
5031
dbgprintf("template: '%s' assigned\n", pTplName);
5034
pAction->pMod = pMod;
5035
pAction->pModData = pModData;
5036
/* now check if the module is compatible with select features */
5037
if(pMod->isCompatibleWithFeature(sFEATURERepeatedMsgReduction) == RS_RET_OK)
5038
pAction->f_ReduceRepeated = bReduceRepeatMsgs;
5040
dbgprintf("module is incompatible with RepeatedMsgReduction - turned off\n");
5041
pAction->f_ReduceRepeated = 0;
5043
pAction->bEnabled = 1; /* action is enabled */
5046
actionSuspend(pAction);
5048
*ppAction = pAction; /* finally store the action pointer */
5051
if(iRet == RS_RET_OK)
5052
iRet = OMSRdestruct(pOMSR);
5054
/* do not overwrite error state! */
5055
OMSRdestruct(pOMSR);
5057
actionDestruct(pAction);
5064
/* read the filter part of a configuration line and store the filter
5065
* in the supplied selector_t
5066
* rgerhards, 2007-08-01
5068
static rsRetVal cflineDoFilter(uchar **pp, selector_t *f)
5075
/* check which filter we need to pull... */
5078
iRet = cflineProcessPropFilter(pp, f);
5081
iRet = cflineProcessTradPRIFilter(pp, f);
5085
/* we now check if there are some global (BSD-style) filter conditions
5086
* and, if so, we copy them over. rgerhards, 2005-10-18
5088
if(pDfltProgNameCmp != NULL)
5089
if((iRet = rsCStrConstructFromCStr(&(f->pCSProgNameComp), pDfltProgNameCmp)) != RS_RET_OK)
5092
if(eDfltHostnameCmpMode != HN_NO_COMP) {
5093
f->eHostnameCmpMode = eDfltHostnameCmpMode;
5094
if((iRet = rsCStrConstructFromCStr(&(f->pCSHostnameComp), pDfltHostnameCmp)) != RS_RET_OK)
5102
/* process the action part of a selector line
5103
* rgerhards, 2007-08-01
5105
static rsRetVal cflineDoAction(uchar **p, action_t **ppAction)
5109
omodStringRequest_t *pOMSR;
5114
assert(ppAction != NULL);
5116
/* loop through all modules and see if one picks up the line */
5117
pMod = omodGetNxt(NULL);
5118
while(pMod != NULL) {
5119
iRet = pMod->mod.om.parseSelectorAct(p, &pModData, &pOMSR);
5120
dbgprintf("tried selector action for %s: %d\n", modGetName(pMod), iRet);
5121
if(iRet == RS_RET_OK || iRet == RS_RET_SUSPENDED) {
5122
if((iRet = addAction(&pAction, pMod, pModData, pOMSR, (iRet == RS_RET_SUSPENDED)? 1 : 0)) == RS_RET_OK) {
5123
/* now check if the module is compatible with select features */
5124
if(pMod->isCompatibleWithFeature(sFEATURERepeatedMsgReduction) == RS_RET_OK)
5125
pAction->f_ReduceRepeated = bReduceRepeatMsgs;
5127
dbgprintf("module is incompatible with RepeatedMsgReduction - turned off\n");
5128
pAction->f_ReduceRepeated = 0;
5130
pAction->bEnabled = 1; /* action is enabled */
5134
else if(iRet != RS_RET_CONFLINE_UNPROCESSED) {
5135
/* In this case, the module would have handled the config
5136
* line, but some error occured while doing so. This error should
5137
* already by reported by the module. We do not try any other
5138
* modules on this line, because we found the right one.
5139
* rgerhards, 2007-07-24
5141
dbgprintf("error %d parsing config line\n", (int) iRet);
5144
pMod = omodGetNxt(pMod);
5147
*ppAction = pAction;
5152
/* helper to selectorAddListCheckActions()
5153
* This is the fucntion to be executed by llExecFunc
5155
DEFFUNC_llExecFunc(selectorAddListCheckActionsChecker)
5158
action_t *pAction = (action_t *) pData;
5160
assert(pAction != NULL);
5162
if(pAction->pMod->needUDPSocket(pAction->pModData) == RS_RET_TRUE) {
5169
/* loop through a list of actions and perform necessary checks and
5170
* housekeeping. This function must only be called when the owning
5171
* selector_t looks valid and is not likely to be discarded. However,
5172
* if we do not return RS_RET_OK, the caller MUST discard the
5173
* owning selector_t. -- rgerhards, 2007-08-02
5175
static rsRetVal selectorAddListCheckActions(selector_t *f)
5181
CHKiRet(llExecFunc(&f->llActList, selectorAddListCheckActionsChecker, NULL));
5188
/* add a completely-processed selector (after config line parsing) to
5189
* the linked list of selectors. We now need to check
5190
* if it has any actions associated and, if so, link it to the linked
5191
* list. If it has nothing associated with it, we can simply discard
5193
* We have one special case during initialization: then, the current
5194
* selector is NULL, which means we do not need to care about it at
5195
* all. -- rgerhards, 2007-08-01
5197
static rsRetVal selectorAddList(selector_t *f)
5202
static selector_t *nextp = NULL; /* TODO: make this go away (see comment below) */
5205
CHKiRet(llGetNumElts(&f->llActList, &iActionCnt));
5206
if(iActionCnt == 0) {
5207
logerror("warning: selector line without actions will be discarded");
5208
selectorDestruct(f);
5210
if((iRet = selectorAddListCheckActions(f)) != RS_RET_OK) {
5211
logerror("selector line will be discarded due to error in action(s)");
5212
selectorDestruct(f);
5215
/* successfully created an entry */
5216
dbgprintf("selector line successfully processed\n");
5217
/* TODO: we should use the linked list class for the selector list, else we need to add globals
5218
* ... well nextp could be added temporarily...
5219
* Thanks to varmojfekoj for having the idea to just use "Files" to make this
5220
* code work. I had actually forgotten to fix the code here before moving to 1.18.0.
5221
* And, of course, I also did not migrate the selector_t structure to the linked list class.
5222
* However, that should still be one of the very next things to happen.
5223
* rgerhards, 2007-08-06
5239
/* Process a configuration file line in traditional "filter selector" format
5241
static rsRetVal cflineClassic(uchar *p, selector_t **pfCurr)
5247
assert(pfCurr != NULL);
5251
/* lines starting with '&' have no new filters and just add
5252
* new actions to the currently processed selector.
5256
skipWhiteSpace(&p); /* on to command */
5258
/* we are finished with the current selector. So we now need to check
5259
* if it has any actions associated and, if so, link it to the linked
5260
* list. If it has nothing associated with it, we can simply discard
5261
* it. In any case, we create a fresh selector for our new filter.
5262
* We have one special case during initialization: then, the current
5263
* selector is NULL, which means we do not need to care about it at
5264
* all. -- rgerhards, 2007-08-01
5266
CHKiRet(selectorAddList(fCurr));
5267
CHKiRet(selectorConstruct(&fCurr)); /* create "fresh" selector */
5268
CHKiRet(cflineDoFilter(&p, fCurr)); /* pull filters */
5271
CHKiRet(cflineDoAction(&p, &pAction));
5272
CHKiRet(llAppend(&fCurr->llActList, NULL, (void*) pAction));
5280
/* process a configuration line
5281
* I re-did this functon because it was desperately time to do so
5282
* rgerhards, 2007-08-01
5284
static rsRetVal cfline(uchar *line, selector_t **pfCurr)
5288
assert(line != NULL);
5290
dbgprintf("cfline: '%s'\n", line);
5292
/* check type of line and call respective processing */
5295
iRet = cflineProcessTagSelector(&line);
5299
iRet = cflineProcessHostSelector(&line);
5302
++line; /* eat '$' */
5303
iRet = cfsysline(line);
5306
iRet = cflineClassic(line, pfCurr);
5314
/* Decode a symbolic name to a numeric value
5316
int decode(uchar *name, struct code *codetab)
5318
register struct code *c;
5322
assert(name != NULL);
5323
assert(codetab != NULL);
5325
dbgprintf("symbolic name: %s", name);
5326
if (isdigit((int) *name))
5329
return (atoi((char*) name));
5331
strncpy((char*) buf, (char*) name, 79);
5332
for (p = buf; *p; p++)
5333
if (isupper((int) *p))
5334
*p = tolower((int) *p);
5335
for (c = codetab; c->c_name; c++)
5336
if (!strcmp((char*) buf, (char*) c->c_name))
5338
dbgprintf(" ==> %d\n", c->c_val);
5344
extern void dbgprintf(char *fmt, ...) __attribute__((format(printf,1, 2)));
5345
void dbgprintf(char *fmt, ...)
5347
# ifdef USE_PTHREADS
5348
static int bWasNL = FALSE;
5352
if ( !(Debug && debugging_on) )
5355
# ifdef USE_PTHREADS
5356
/* The bWasNL handler does not really work. It works if no thread
5357
* switching occurs during non-NL messages. Else, things are messed
5358
* up. Anyhow, it works well enough to provide useful help during
5359
* getting this up and running. It is questionable if the extra effort
5360
* is worth fixing it, giving the limited appliability.
5361
* rgerhards, 2005-10-25
5362
* I have decided that it is not worth fixing it - especially as it works
5364
* rgerhards, 2007-06-15
5367
fprintf(stdout, "%8.8d: ", (unsigned int) pthread_self());
5369
bWasNL = (*(fmt + strlen(fmt) - 1) == '\n') ? TRUE : FALSE;
5372
vfprintf(stdout, fmt, ap);
5381
* The following function is resposible for handling a SIGHUP signal. Since
5382
* we are now doing mallocs/free as part of init we had better not being
5383
* doing this during a signal handler. Instead this function simply sets
5384
* a flag variable which will tell the main loop to go through a restart.
5386
void sighup_handler()
5388
struct sigaction sigAct;
5392
memset(&sigAct, 0, sizeof (sigAct));
5393
sigemptyset(&sigAct.sa_mask);
5394
sigAct.sa_handler = sighup_handler;
5395
sigaction(SIGHUP, &sigAct, NULL);
5404
* Copy a string byte by byte until the occurrence
5405
* of a given separator.
5407
* \param ppSrc Pointer to a pointer of the source array of characters. If a
5408
separator detected the Pointer points to the next char after the
5409
separator. Except if the end of the string is dedected ('\n').
5410
Then it points to the terminator char.
5411
* \param pDst Pointer to the destination array of characters. Here the substing
5413
* \param DstSize Maximum numbers of characters to store.
5414
* \param cSep Separator char.
5415
* \ret int Returns 0 if no error occured.
5417
int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep)
5419
uchar *pSrc = *ppSrc;
5420
int iErr = 0; /* 0 = no error, >0 = error */
5421
while(*pSrc != cSep && *pSrc != '\n' && *pSrc != '\0' && DstSize>1) {
5422
*pDst++ = *(pSrc)++;
5425
/* check if the Dst buffer was to small */
5426
if (*pSrc != cSep && *pSrc != '\n' && *pSrc != '\0')
5428
dbgprintf("in getSubString, error Src buffer > Dst buffer\n");
5431
if (*pSrc == '\0' || *pSrc == '\n')
5432
/* this line was missing, causing ppSrc to be invalid when it
5433
* was returned in case of end-of-string. rgerhards 2005-07-29
5443
/* print out which socket we are listening on. This is only
5444
* a debug aid. rgerhards, 2007-07-02
5446
static void debugListenInfo(int fd, char *type)
5451
struct sockaddr_in *ipv4;
5452
struct sockaddr_in6 *ipv6;
5453
socklen_t saLen = sizeof(sa);
5455
if(getsockname(fd, &sa, &saLen) == 0) {
5456
switch(sa.sa_family) {
5459
ipv4 = (struct sockaddr_in*) &sa;
5460
port = ntohs(ipv4->sin_port);
5464
ipv6 = (struct sockaddr_in6*) &sa;
5465
port = ntohs(ipv6->sin6_port);
5472
dbgprintf("Listening on %s syslogd socket %d (%s/port %d).\n",
5473
type, fd, szFamily, port);
5477
/* we can not obtain peer info. We are just providing
5478
* debug info, so this is no reason to break the program
5479
* or do any serious error reporting.
5481
dbgprintf("Listening on syslogd socket %d - could not obtain peer info.\n", fd);
5485
/* this function pulls all internal messages from the buffer
5486
* and puts them into the processing engine.
5487
* We can only do limited error handling, as this would not
5488
* really help us. TODO: add error messages?
5489
* rgerhards, 2007-08-03
5491
static void processImInternal(void)
5497
while(iminternalRemoveMsg(&iPri, &pMsg, &iFlags) == RS_RET_OK) {
5498
logmsg(iPri, pMsg, iFlags);
5504
/* helper function for mainloop(). This is used to add all module
5505
* writeFDsfor Select via llExecFunc().
5506
* rgerhards, 2007-08-02
5508
typedef struct selectHelperWriteFDSInfo_s { /* struct for pParam */
5511
} selectHelperWriteFDSInfo_t;
5512
DEFFUNC_llExecFunc(mainloopAddModWriteFDSforSelect)
5515
action_t *pAction = (action_t*) pData;
5516
selectHelperWriteFDSInfo_t *pState = (selectHelperWriteFDSInfo_t*) pParam;
5519
assert(pAction != NULL);
5520
assert(pState != NULL);
5522
if(pAction->pMod->getWriteFDForSelect(pAction->pModData, &fdMod) == RS_RET_OK) {
5523
FD_SET(fdMod, pState->pWritefds);
5524
if(fdMod > *pState->pMaxfds)
5525
*pState->pMaxfds = fdMod;
5532
/* helper function for mainloop(). This is used to call module action
5533
* handlers after select if a fd is writable.
5534
* HINT: when we change to the new threading model, this function
5535
* is probably no longer needed.
5536
* rgerhards, 2007-08-02
5538
DEFFUNC_llExecFunc(mainloopCallWithWritableFDsActions)
5541
action_t *pAction = (action_t*) pData;
5542
selectHelperWriteFDSInfo_t *pState = (selectHelperWriteFDSInfo_t*) pParam;
5545
assert(pAction != NULL);
5546
assert(pState != NULL);
5548
if(pAction->pMod->getWriteFDForSelect(pAction->pModData, &fdMod) == RS_RET_OK) {
5549
if(FD_ISSET(fdMod, pState->pWritefds)) {
5550
if((iRet = pAction->pMod->onSelectReadyWrite(pAction->pModData))
5552
dbgprintf("error %d from onSelectReadyWrite() - continuing\n", iRet);
5554
if(--(pState->pMaxfds) == 0) {
5555
ABORT_FINALIZE(RS_RET_FINISHED); /* all processed, nothing left to do */
5565
/* process the select() selector array after the successful select.
5566
* processing is completed as soon as all selectors needing attention
5568
* rgerhards, 2007-08-08
5570
static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_set *pWritefds)
5576
char line[MAXLINE +1];
5577
selectHelperWriteFDSInfo_t writeFDSInfo;
5580
struct sockaddr_storage frominet;
5582
uchar fromHost[NI_MAXHOST];
5583
uchar fromHostFQDN[NI_MAXHOST];
5586
#endif /* #ifdef SYSLOG_INET */
5588
/* the following macro is used to decrement the number of to-be-probed
5589
* fds and abort this function when we are done with all.
5591
# define FDPROCESSED() if(--nfds == 0) { ABORT_FINALIZE(RS_RET_OK); }
5596
dbgprintf("Select interrupted.\n");
5597
ABORT_FINALIZE(RS_RET_OK); /* we are done in any case */
5601
dbgprintf("\nSuccessful select, descriptor count = %d, Activity on: ", nfds);
5602
for (i = 0; i <= maxfds; ++i)
5603
if ( FD_ISSET(i, pReadfds) )
5604
dbgprintf("%d ", i);
5609
/* Now check the TCP send sockets. So far, we only see if they become
5610
* writable and then change their internal status. No real async
5611
* writing is currently done. This code will be replaced once liblogging
5612
* is used, thus we try not to focus too much on it.
5614
* IMPORTANT: With the current code, the writefds must be checked first,
5615
* because the readfds might have messages to be forwarded, which
5616
* rely on the status setting that is done here!
5617
* rgerhards 2005-07-20
5619
* liblogging implementation will not happen as anticipated above. So
5620
* this code here will stay for quite a while.
5621
* rgerhards, 2006-12-07
5623
writeFDSInfo.pWritefds = pWritefds;
5624
writeFDSInfo.pMaxfds = &nfds;
5625
for(f = Files; f != NULL ; f = f->f_next) {
5626
iRetLL = llExecFunc(&f->llActList, mainloopCallWithWritableFDsActions, &writeFDSInfo);
5627
if(iRetLL == RS_RET_FINISHED) {
5628
ABORT_FINALIZE(RS_RET_OK); /* we are done in this case */
5631
#endif /* #ifdef SYSLOG_INET */
5632
#ifdef SYSLOG_UNIXAF
5633
for (i = 0; i < nfunix; i++) {
5634
if ((fd = funix[i]) != -1 && FD_ISSET(fd, pReadfds)) {
5636
iRcvd = recv(fd, line, MAXLINE - 1, 0);
5637
dbgprintf("Message from UNIX socket: #%d\n", fd);
5639
printchopped(LocalHostName, line, iRcvd, fd, funixParseHost[i]);
5640
} else if (iRcvd < 0 && errno != EINTR) {
5642
dbgprintf("UNIX socket error: %d = %s.\n", \
5643
errno, strerror_r(errno, errStr, sizeof(errStr)));
5644
logerror("recvfrom UNIX");
5652
if (finet != NULL && AcceptRemote) {
5653
for (i = 0; i < *finet; i++) {
5654
if (FD_ISSET(finet[i+1], pReadfds)) {
5655
socklen = sizeof(frominet);
5656
memset(line, 0xff, sizeof(line)); // TODO: I think we need this for debug only - remove after bug hunt
5657
l = recvfrom(finet[i+1], line, MAXLINE - 1, 0,
5658
(struct sockaddr *)&frominet, &socklen);
5660
if(cvthname(&frominet, fromHost, fromHostFQDN) == RS_RET_OK) {
5661
dbgprintf("Message from inetd socket: #%d, host: %s\n",
5662
finet[i+1], fromHost);
5663
/* Here we check if a host is permitted to send us
5664
* syslog messages. If it isn't, we do not further
5665
* process the message but log a warning (if we are
5666
* configured to do this).
5667
* rgerhards, 2005-09-26
5669
if(isAllowedSender(pAllowedSenders_UDP,
5670
(struct sockaddr *)&frominet, (char*)fromHostFQDN)) {
5671
printchopped((char*)fromHost, line, l, finet[i+1], 1);
5673
if(option_DisallowWarning) {
5674
logerrorSz("UDP message from disallowed sender %s discarded",
5679
} else if (l < 0 && errno != EINTR && errno != EAGAIN) {
5681
dbgprintf("INET socket error: %d = %s.\n",
5682
errno, strerror_r(errno, errStr, sizeof(errStr)));
5683
logerror("recvfrom inet");
5684
/* should be harmless */
5692
if(sockTCPLstn != NULL && *sockTCPLstn) {
5693
for (i = 0; i < *sockTCPLstn; i++) {
5694
if (FD_ISSET(sockTCPLstn[i+1], pReadfds)) {
5695
dbgprintf("New connect on TCP inetd socket: #%d\n", sockTCPLstn[i+1]);
5696
TCPSessAccept(sockTCPLstn[i+1]);
5701
/* now check the sessions */
5702
iTCPSess = TCPSessGetNxtSess(-1);
5703
while(iTCPSess != -1) {
5706
fdSess = pTCPSessions[iTCPSess].sock;
5707
if(FD_ISSET(fdSess, pReadfds)) {
5709
dbgprintf("tcp session socket with new data: #%d\n", fdSess);
5711
/* Receive message */
5712
state = recv(fdSess, buf, sizeof(buf), 0);
5714
/* process any incomplete frames left over */
5715
TCPSessPrepareClose(iTCPSess);
5716
/* Session closed */
5717
TCPSessClose(iTCPSess);
5718
} else if(state == -1) {
5719
logerrorInt("TCP session %d will be closed, error ignored\n",
5721
TCPSessClose(iTCPSess);
5723
/* valid data received, process it! */
5724
if(TCPSessDataRcvd(iTCPSess, buf, state) == 0) {
5725
/* in this case, something went awfully wrong.
5726
* We are instructed to terminate the session.
5728
logerrorInt("Tearing down TCP Session %d - see "
5729
"previous messages for reason(s)\n",
5731
TCPSessClose(iTCPSess);
5736
iTCPSess = TCPSessGetNxtSess(iTCPSess);
5746
/* This is the main processing loop. It is called after successful initialization.
5747
* When it returns, the syslogd terminates.
5749
static void mainloop(void)
5756
selectHelperWriteFDSInfo_t writeFDSInfo;
5760
#endif /* #ifdef SYSLOG_INET */
5763
struct timeval tvSelectTimeout;
5772
/* first check if we have any internal messages queued and spit them out */
5773
processImInternal();
5775
#ifdef SYSLOG_UNIXAF
5776
/* Add the Unix Domain Sockets to the list of read
5778
* rgerhards 2005-08-01: we must now check if there are
5779
* any local sockets to listen to at all. If the -o option
5780
* is given without -a, we do not need to listen at all..
5782
/* Copy master connections */
5783
for (i = startIndexUxLocalSockets; i < nfunix; i++) {
5784
if (funix[i] != -1) {
5785
FD_SET(funix[i], &readfds);
5786
if (funix[i]>maxfds) maxfds=funix[i];
5791
/* Add the UDP listen sockets to the list of read descriptors.
5793
if(finet != NULL && AcceptRemote) {
5794
for (i = 0; i < *finet; i++) {
5795
if (finet[i+1] != -1) {
5797
debugListenInfo(finet[i+1], "UDP");
5798
FD_SET(finet[i+1], &readfds);
5799
if(finet[i+1]>maxfds) maxfds=finet[i+1];
5804
/* Add the TCP listen sockets to the list of read descriptors.
5806
if(sockTCPLstn != NULL && *sockTCPLstn) {
5807
for (i = 0; i < *sockTCPLstn; i++) {
5808
/* The if() below is theoretically not needed, but I leave it in
5809
* so that a socket may become unsuable during execution. That
5810
* feature is not yet supported by the current code base.
5812
if (sockTCPLstn[i+1] != -1) {
5814
debugListenInfo(sockTCPLstn[i+1], "TCP");
5815
FD_SET(sockTCPLstn[i+1], &readfds);
5816
if(sockTCPLstn[i+1]>maxfds) maxfds=sockTCPLstn[i+1];
5819
/* do the sessions */
5820
iTCPSess = TCPSessGetNxtSess(-1);
5821
while(iTCPSess != -1) {
5823
fdSess = pTCPSessions[iTCPSess].sock;
5824
dbgprintf("Adding TCP Session %d\n", fdSess);
5825
FD_SET(fdSess, &readfds);
5826
if (fdSess>maxfds) maxfds=fdSess;
5827
/* now get next... */
5828
iTCPSess = TCPSessGetNxtSess(iTCPSess);
5832
/* TODO: activate the code below only if we actually need to check
5833
* for outstanding writefds.
5836
/* Now add the TCP output sockets to the writefds set. This implementation
5837
* is not optimal (performance-wise) and it should be replaced with something
5838
* better in the longer term. I've not yet done this, as this code is
5839
* scheduled to be replaced after the liblogging integration.
5840
* rgerhards 2005-07-20
5843
writeFDSInfo.pWritefds = &writefds;
5844
writeFDSInfo.pMaxfds = &maxfds;
5845
for (f = Files; f != NULL ; f = f->f_next) {
5846
llExecFunc(&f->llActList, mainloopAddModWriteFDSforSelect, &writeFDSInfo);
5851
if ( debugging_on ) {
5852
dbgprintf("----------------------------------------\n");
5853
dbgprintf("Calling select, active file descriptors (max %d): ", maxfds);
5854
for (nfds= 0; nfds <= maxfds; ++nfds)
5855
if ( FD_ISSET(nfds, &readfds) )
5856
dbgprintf("%d ", nfds);
5860
#define MAIN_SELECT_TIMEVAL NULL
5863
/* There seems to be a problem with BSD and threads. When running on
5864
* multiple threads, a signal will not cause the select call to be
5865
* interrrupted. I am not sure if this is by design or an bug (some
5866
* information on the web let's me think it is a bug), but that really
5867
* does not matter. The issue with our code is that we will not gain
5868
* control when rsyslogd is terminated or huped. What I am doing now is
5869
* make the select call timeout after 10 seconds, so that we can check
5870
* the condition then. Obviously, this causes some sluggish behaviour and
5871
* also the loss of some (very few) cpu cycles. Both, I think, are
5872
* absolutely acceptable.
5873
* rgerhards, 2005-10-26
5874
* TODO: I got some information: this seems to be expected signal() behaviour
5875
* we should investigate the use of sigaction() (see klogd.c for an sample).
5876
* rgerhards, 2007-06-22
5877
* rgerhards, 2007-09-11: code has been converted to sigaction() now. We need
5878
* to re-check on BSD, I think the issue is now solved.
5880
tvSelectTimeout.tv_sec = 10;
5881
tvSelectTimeout.tv_usec = 0;
5882
# undef MAIN_SELECT_TIMEVAL
5883
# define MAIN_SELECT_TIMEVAL &tvSelectTimeout
5887
#define MAIN_SELECT_WRITEFDS (fd_set *) &writefds
5889
#define MAIN_SELECT_WRITEFDS NULL
5891
nfds = select(maxfds+1, (fd_set *) &readfds, MAIN_SELECT_WRITEFDS,
5892
(fd_set *) NULL, MAIN_SELECT_TIMEVAL);
5894
if(bRequestDoMark) {
5897
/* We do not use continue, because domark() is carried out
5898
* only when something else happened.
5902
dbgprintf("\nReceived SIGHUP, reloading rsyslogd.\n");
5903
/* worker thread is stopped as part of init() */
5909
dbgprintf("No select activity.\n");
5913
processSelectAfter(maxfds, nfds, &readfds, MAIN_SELECT_WRITEFDS);
5915
#undef MAIN_SELECT_TIMEVAL
5916
#undef MAIN_SELECT_WRITEFDS
5920
/* If user is not root, prints warnings or even exits
5921
* TODO: check all dynafiles for write permission
5922
* ... but it is probably better to wait here until we have
5923
* a module interface - rgerhards, 2007-07-23
5925
static void checkPermissions()
5927
/* we are not root */
5930
fputs("WARNING: Local messages will not be logged! If you want to log them, run rsyslog as root.\n",stderr);
5932
/* udp enabled and port number less than or equal to 1024 */
5933
if ( AcceptRemote && (atoi(LogPort) <= 1024) )
5934
fprintf(stderr, "WARNING: Will not listen on UDP port %s. Use port number higher than 1024 or run rsyslog as root!\n", LogPort);
5936
/* tcp enabled and port number less or equal to 1024 */
5937
if( bEnableTCP && (atoi(TCPLstnPort) <= 1024) )
5938
fprintf(stderr, "WARNING: Will not listen on TCP port %s. Use port number higher than 1024 or run rsyslog as root!\n", TCPLstnPort);
5940
/* Neither explicit high UDP port nor explicit high TCP port.
5941
* It is useless to run anymore */
5942
if( !(AcceptRemote && (atoi(LogPort) > 1024)) && !( bEnableTCP && (atoi(TCPLstnPort) > 1024)) )
5945
fprintf(stderr, "ERROR: Nothing to log, no reason to run. Please run rsyslog as root.\n");
5954
/* load build-in modules
5955
* very first version begun on 2007-07-23 by rgerhards
5957
static rsRetVal loadBuildInModules(void)
5961
if((iRet = doModInit(modInitFile, (uchar*) "builtin-file", NULL)) != RS_RET_OK)
5964
if((iRet = doModInit(modInitFwd, (uchar*) "builtin-fwd", NULL)) != RS_RET_OK)
5967
if((iRet = doModInit(modInitShell, (uchar*) "builtin-shell", NULL)) != RS_RET_OK)
5969
if((iRet = doModInit(modInitDiscard, (uchar*) "builtin-discard", NULL)) != RS_RET_OK)
5972
/* dirty, but this must be for the time being: the usrmsg module must always be
5973
* loaded as last module. This is because it processes any time of action selector.
5974
* If we load it before other modules, these others will never have a chance of
5975
* working with the config file. We may change that implementation so that a user name
5976
* must start with an alnum, that would definitely help (but would it break backwards
5977
* compatibility?). * rgerhards, 2007-07-23
5978
* User names now must begin with:
5981
if((iRet = doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg", NULL)) != RS_RET_OK)
5984
/* ok, initialization of the command handler probably does not 100% belong right in
5985
* this space here. However, with the current design, this is actually quite a good
5986
* place to put it. We might decide to shuffle it around later, but for the time
5987
* being, the code has found its home here. A not-just-sideeffect of this decision
5988
* is that rsyslog will terminate if we can not register our built-in config commands.
5989
* This, I think, is the right thing to do. -- rgerhards, 2007-07-31
5992
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize));
5994
CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs));
5995
CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp));
5996
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL));
5997
CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar));
5998
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv));
5999
CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs));
6000
CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF));
6001
CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_TEMPLATE));
6002
CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_OUTCHANNEL));
6003
CHKiRet(regCfSysLineHdlr((uchar *)"allowedsender", 0, eCmdHdlrCustomHandler, doNameLine, (void*)DIR_ALLOWEDSENDER));
6004
CHKiRet(regCfSysLineHdlr((uchar *)"modload", 0, eCmdHdlrCustomHandler, doModLoad, NULL));
6005
CHKiRet(regCfSysLineHdlr((uchar *)"includeconfig", 0, eCmdHdlrCustomHandler, doIncludeLine, NULL));
6006
CHKiRet(regCfSysLineHdlr((uchar *)"umask", 0, eCmdHdlrFileCreateMode, setUmask, NULL));
6007
CHKiRet(regCfSysLineHdlr((uchar *)"debugprinttemplatelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintTemplateList));
6008
CHKiRet(regCfSysLineHdlr((uchar *)"debugprintmodulelist", 0, eCmdHdlrBinary, NULL, &bDebugPrintModuleList));
6009
CHKiRet(regCfSysLineHdlr((uchar *)"debugprintcfsyslinehandlerlist", 0, eCmdHdlrBinary,
6010
NULL, &bDebugPrintCfSysLineHandlerList));
6011
CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir));
6012
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL));
6019
/* print version and compile-time setting information.
6021
static void printVersion(void)
6023
printf("rsyslogd %s, ", VERSION);
6024
printf("compiled with:\n");
6026
printf("\tFEATURE_PTHREADS (dual-threading):\tYes\n");
6028
printf("\tFEATURE_PTHREADS (dual-threading):\tNo\n");
6030
#ifdef FEATURE_REGEXP
6031
printf("\tFEATURE_REGEXP:\t\t\t\tYes\n");
6033
printf("\tFEATURE_REGEXP:\t\t\t\tNo\n");
6036
printf("\tFEATURE_LARGEFILE:\t\t\tYes\n");
6038
printf("\tFEATURE_LARGEFILE:\t\t\tNo\n");
6041
printf("\tFEATURE_NETZIP (message compression):\tYes\n");
6043
printf("\tFEATURE_NETZIP (message compression):\tNo\n");
6046
printf("\tSYSLOG_INET (Internet/remote support):\tYes\n");
6048
printf("\tSYSLOG_INET (Internet/remote support):\tNo\n");
6051
printf("\tFEATURE_DEBUG (debug build, slow code):\tYes\n");
6053
printf("\tFEATURE_DEBUG (debug build, slow code):\tNo\n");
6055
printf("\nSee http://www.rsyslog.com for more information.\n");
6059
/* This function is called after initial initalization. It is used to
6060
* move code out of the too-long main() function.
6061
* rgerhards, 2007-10-17
6063
static void mainThread()
6068
/* doing some core initializations */
6069
if((iRet = modInitIminternal()) != RS_RET_OK) {
6070
fprintf(stderr, "fatal error: could not initialize errbuf object (error code %d).\n",
6072
exit(1); /* "good" exit, leaving at init for fatal error */
6075
if((iRet = loadBuildInModules()) != RS_RET_OK) {
6076
fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n",
6078
exit(1); /* "good" exit, leaving at init for fatal error */
6081
/* Note: signals MUST be processed by the thread this code is running in. The reason
6082
* is that we need to interrupt the select() system call. -- rgerhards, 2007-10-17
6085
/* initialize the default templates
6086
* we use template names with a SP in front - these
6087
* can NOT be generated via the configuration file
6089
pTmp = template_TraditionalFormat;
6090
tplAddLine(" TradFmt", &pTmp);
6091
pTmp = template_WallFmt;
6092
tplAddLine(" WallFmt", &pTmp);
6093
pTmp = template_StdFwdFmt;
6094
tplAddLine(" StdFwdFmt", &pTmp);
6095
pTmp = template_StdUsrMsgFmt;
6096
tplAddLine(" StdUsrMsgFmt", &pTmp);
6097
pTmp = template_StdDBFmt;
6098
tplLastStaticInit(tplAddLine(" StdDBFmt", &pTmp));
6100
dbgprintf("Starting.\n");
6103
dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n");
6106
/* Send a signal to the parent so it can terminate.
6109
kill (ppid, SIGTERM);
6111
/* END OF INTIALIZATION
6112
* ... but keep in mind that we might do a restart and thus init() might
6113
* be called again. If that happens, we must shut down the worker thread,
6114
* do the init() and then restart things.
6115
* rgerhards, 2005-10-24
6120
/* do any de-init's that need to be done AFTER this comment */
6125
/* This is the main entry point into rsyslogd. Over time, we should try to
6126
* modularize it a bit more...
6128
int main(int argc, char **argv)
6134
struct hostent *hent;
6136
extern char *optarg;
6137
struct sigaction sigAct;
6138
#if 0 /* see comment for #if 0 below (towards end of function) */
6144
mtrace(); /* this is a debug aid for leak detection - either remove
6145
* or put in conditional compilation. 2005-01-18 RGerhards */
6150
if(chdir ("/") != 0)
6151
fprintf(stderr, "Can not do 'cd /' - still trying to run\n");
6152
for (i = 1; i < MAXFUNIX; i++) {
6157
/* END core initializations */
6159
while ((ch = getopt(argc, argv, "46Aa:dehi:f:l:m:nop:r::s:t:u:vwx")) != EOF) {
6171
if (nfunix < MAXFUNIX)
6172
if(*optarg == ':') {
6173
funixParseHost[nfunix] = 1;
6174
funixn[nfunix++] = optarg+1;
6177
funixParseHost[nfunix] = 0;
6178
funixn[nfunix++] = optarg;
6181
fprintf(stderr, "rsyslogd: Out of descriptors, ignoring %s\n", optarg);
6183
case 'd': /* debug */
6186
case 'e': /* log every message (no repeat message supression) */
6189
case 'f': /* configuration file */
6190
ConfFile = (uchar*) optarg;
6195
case 'i': /* pid file name */
6200
fprintf (stderr, "rsyslogd: Only one -l argument allowed," \
6201
"the first one is taken.\n");
6203
LocalHosts = crunch_list(optarg);
6206
case 'm': /* mark interval */
6207
MarkInterval = atoi(optarg) * 60;
6209
case 'n': /* don't fork */
6212
case 'o': /* omit local logging (/dev/log) */
6213
startIndexUxLocalSockets = 1;
6215
case 'p': /* path to regular log socket */
6218
case 'r': /* accept remote messages */
6226
fprintf(stderr, "rsyslogd: -r not valid - not compiled with network support");
6231
fprintf (stderr, "rsyslogd: Only one -s argument allowed," \
6232
"the first one is taken.\n");
6234
StripDomains = crunch_list(optarg);
6237
case 't': /* enable tcp logging */
6239
configureTCPListen(optarg);
6241
fprintf(stderr, "rsyslogd: -t not valid - not compiled with network support");
6244
case 'u': /* misc user settings */
6245
if(atoi(optarg) == 1)
6246
bParseHOSTNAMEandTAG = 0;
6250
exit(0); /* exit for -v option - so this is a "good one" */
6251
case 'w': /* disable disallowed host warnigs */
6252
option_DisallowWarning = 0;
6254
case 'x': /* disable dns for remote messages */
6263
if ((argc -= optind))
6268
if ( !(Debug || NoFork) )
6270
dbgprintf("Checking pidfile.\n");
6271
if (!check_pid(PidFile))
6273
memset(&sigAct, 0, sizeof (sigAct));
6274
sigemptyset(&sigAct.sa_mask);
6275
sigAct.sa_handler = doexit;
6276
sigaction(SIGTERM, &sigAct, NULL);
6284
* Not reached unless something major went wrong. 5
6285
* minutes should be a fair amount of time to wait.
6286
* Please note that this procedure is important since
6287
* the father must not exit before syslogd isn't
6288
* initialized or the klogd won't be able to flush its
6291
exit(1); /* "good" exit - after forking, not diasabling anything */
6293
num_fds = getdtablesize();
6294
for (i= 0; i < num_fds; i++)
6300
fputs(" Already running.\n", stderr);
6301
exit(1); /* "good" exit, done if syslogd is already running */
6307
/* tuck my process id away */
6310
dbgprintf("Writing pidfile.\n");
6311
if (!check_pid(PidFile))
6313
if (!write_pid(PidFile))
6315
fputs("Can't write pid.\n", stderr);
6316
exit(1); /* exit during startup - questionable */
6321
fputs("Pidfile (and pid) already exist.\n", stderr);
6322
exit(1); /* exit during startup - questionable */
6324
} /* if ( !Debug ) */
6325
myPid = getpid(); /* save our pid for further testing (also used for messages) */
6328
gethostname(LocalHostName, sizeof(LocalHostName));
6329
if ( (p = strchr(LocalHostName, '.')) ) {
6337
/* It's not clearly defined whether gethostname()
6338
* should return the simple hostname or the fqdn. A
6339
* good piece of software should be aware of both and
6340
* we want to distribute good software. Joey
6342
* Good software also always checks its return values...
6343
* If syslogd starts up before DNS is up & /etc/hosts
6344
* doesn't have LocalHostName listed, gethostbyname will
6347
/* TODO: gethostbyname() is not thread-safe, but replacing it is
6348
* not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25
6350
hent = gethostbyname(LocalHostName);
6352
snprintf(LocalHostName, sizeof(LocalHostName), "%s", hent->h_name);
6354
if ( (p = strchr(LocalHostName, '.')) )
6362
/* Convert to lower case to recognize the correct domain laterly
6364
for (p = (char *)LocalDomain; *p ; p++)
6365
if (isupper((int) *p))
6368
memset(&sigAct, 0, sizeof (sigAct));
6369
sigemptyset(&sigAct.sa_mask);
6371
sigAct.sa_handler = doDie;
6372
sigaction(SIGTERM, &sigAct, NULL);
6373
sigAct.sa_handler = Debug ? doDie : SIG_IGN;
6374
sigaction(SIGINT, &sigAct, NULL);
6375
sigaction(SIGQUIT, &sigAct, NULL);
6376
sigAct.sa_handler = reapchild;
6377
sigaction(SIGCHLD, &sigAct, NULL);
6378
sigAct.sa_handler = domarkAlarmHdlr;
6379
sigaction(SIGALRM, &sigAct, NULL);
6380
sigAct.sa_handler = Debug ? debug_switch : SIG_IGN;
6381
sigaction(SIGUSR1, &sigAct, NULL);
6382
sigAct.sa_handler = SIG_IGN;
6383
sigaction(SIGPIPE, &sigAct, NULL);
6384
sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */
6385
(void) alarm(TIMERINTVL);
6390
/* This commented-out code was once used to spawn a separate thread
6391
* for the mainThread(). This was initially done to solve a problem that not
6392
* really existed. Thus the code is now commented out. I do not remove it yet,
6393
* because there may be use for it in the not too distant future. If it is
6394
* still commented out in a year's time, that's a good indication it should
6395
* be removed! -- rgerhards, 2007-10-17
6397
i = pthread_create(&thrdMain, NULL, mainThread, NULL);
6398
dbgprintf("\"main\" thread started with state %d.\n", i);
6400
/* we block all signals - they will be processed by the "main"-thread. This most
6401
* closely resembles previous behaviour. TODO: think about optimizing it, some
6402
* signals may better be delivered here. rgerhards, 2007-10-08
6404
sigfillset(&sigSet);
6405
pthread_sigmask(SIG_BLOCK, &sigSet, NULL);
6407
/* see comment in mainThread on why we start thread and then immediately
6408
* do a blocking wait on it - it makese sense... ;) rgerhards, 2007-10-08
6410
pthread_join(thrdMain, NULL);