summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am6
-rw-r--r--tools/gethostn.c47
-rw-r--r--tools/iminternal.c3
-rw-r--r--tools/omfwd.c5
-rw-r--r--tools/rsyslogd.833
-rw-r--r--tools/syslogd.c287
6 files changed, 275 insertions, 106 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index b2b7a8ca..a265af9c 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -21,9 +21,13 @@ rsyslogd_SOURCES = \
pidfile.h \
\
../dirty.h
-
rsyslogd_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
rsyslogd_LDADD = $(zlib_libs) $(pthreads_libs) $(rsrt_libs)
rsyslogd_LDFLAGS = -export-dynamic
+if ENABLE_DIAGTOOLS
+sbin_PROGRAMS += rsyslog_diag_hostname
+rsyslog_diag_hostname_SOURCES = gethostn.c
+endif
+
EXTRA_DIST = $(man_MANS)
diff --git a/tools/gethostn.c b/tools/gethostn.c
new file mode 100644
index 00000000..df7ce38b
--- /dev/null
+++ b/tools/gethostn.c
@@ -0,0 +1,47 @@
+/* gethostn - a small diagnostic utility to show what the
+ * gethostname() API returns. Of course, this tool duplicates
+ * functionality already found in other tools. But the point is
+ * that the API shall be called by a program that is compiled like
+ * rsyslogd and does exactly what rsyslog does.
+ *
+ * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int __attribute__((unused)) argc, char __attribute__((unused)) *argv[])
+{
+ char hostname[4096]; /* this should always be sufficient ;) */
+ int err;
+
+ err = gethostname(hostname, sizeof(hostname));
+
+ if(err) {
+ perror("gethostname failed");
+ exit(1);
+ }
+
+ printf("hostname of this system is '%s'.\n", hostname);
+
+ return 0;
+}
diff --git a/tools/iminternal.c b/tools/iminternal.c
index 60460a99..0ceff3d8 100644
--- a/tools/iminternal.c
+++ b/tools/iminternal.c
@@ -185,6 +185,5 @@ rsRetVal modExitIminternal(void)
RETiRet;
}
-/*
- * vi:set ai:
+/* vim:set ai:
*/
diff --git a/tools/omfwd.c b/tools/omfwd.c
index 1b617ee1..df2f0342 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -509,6 +509,9 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
* applies to TCP-based syslog only and is ignored when specified with UDP).
* That is not yet implemented.
* rgerhards, 2006-12-07
+ * In order to support IPv6 addresses, we must introduce an extension to
+ * the hostname. If it is in square brackets, whatever is in them is treated as
+ * the hostname - without any exceptions ;) -- rgerhards, 2008-08-05
*/
if(*p == '(') {
/* at this position, it *must* be an option indicator */
@@ -555,6 +558,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
*/
errmsg.LogError(0, NO_ERRCODE, "Option block not terminated in forwarding action.");
}
+
/* extract the host first (we do a trick - we replace the ';' or ':' with a '\0')
* now skip to port and then template name. rgerhards 2005-07-06
*/
@@ -604,6 +608,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
} else {
CHKmalloc(pData->f_hname = strdup((char*) q));
}
+dbgprintf("hostname '%s', port '%s'\n", pData->f_hname, pData->port);
/* process template */
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
diff --git a/tools/rsyslogd.8 b/tools/rsyslogd.8
index 91f2016e..05905412 100644
--- a/tools/rsyslogd.8
+++ b/tools/rsyslogd.8
@@ -1,7 +1,7 @@
.\" Copyright 2004-2008 Rainer Gerhards and Adiscon for the rsyslog modifications
.\" May be distributed under the GNU General Public License
.\"
-.TH RSYSLOGD 8 "11 July 2008" "Version 3.18.0" "Linux System Administration"
+.TH RSYSLOGD 8 "29 July 2008" "Version 3.21.1" "Linux System Administration"
.SH NAME
rsyslogd \- reliable and extended syslogd
.SH SYNOPSIS
@@ -21,12 +21,18 @@ rsyslogd \- reliable and extended syslogd
.I hostlist
]
.RB [ " \-n " ]
+.RB [ " \-N "
+.I level
+]
.br
.RB [ " \-q " ]
.RB [ " \-Q " ]
.RB [ " \-s "
.I domainlist
]
+.RB [ " \-u "
+.I userlevel
+]
.RB [ " \-v " ]
.RB [ " \-w " ]
.RB [ " \-x " ]
@@ -166,6 +172,19 @@ Avoid auto-backgrounding. This is needed especially if the
is started and controlled by
.BR init (8).
.TP
+.B "\-N " "level"
+Do a coNfig check. Do NOT run in regular mode, just check configuration
+file correctness.
+This option is meant to verify a config file. To do so, run rsyslogd
+interactively in foreground, specifying -f <config-file> and -N level.
+The level argument modifies behaviour. Currently, 0 is the same as
+not specifying the -N option at all (so this makes limited sense) and
+1 actually activates the code. Later, higher levels will mean more
+verbosity (this is a forward-compatibility option).
+.B rsyslogd
+is started and controlled by
+.BR init (8).
+.TP
.BI "\-q " "add hostname if DNS fails during ACL processing"
During ACL processing, hostnames are resolved to IP addreses for
performance reasons. If DNS fails during that process, the hostname
@@ -186,6 +205,18 @@ is specified and the host logging resolves to satu.infodrom.north.de
no domain would be cut, you will have to specify two domains like:
.BR "\-s north.de:infodrom.north.de" .
.TP
+.BI "\-u " "userlevel"
+This is a "catch all" option for some very seldomly-used user settings.
+The "userlevel" variable selects multiple things. Add the specific values
+to get the combined effect of them.
+A value of 1 prevents rsyslogd from parsing hostnames and tags inside
+messages.
+A value of 2 prevents rsyslogd from changing to the root directory. This
+is almost never a good idea in production use. This option was introduced
+in support of the internal testbed.
+To combine these two features, use a userlevel of 3 (1+2). Whenever you use
+an -u option, make sure you really understand what you do and why you do it.
+.TP
.B "\-v"
Print version and exit.
.TP
diff --git a/tools/syslogd.c b/tools/syslogd.c
index e432a67d..758d5ed1 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -255,6 +255,7 @@ static int bFinished = 0; /* used by termination signal handler, read-only excep
* is either 0 or the number of the signal that requested the
* termination.
*/
+static int iConfigVerify = 0; /* is this just a config verify run? */
/* Intervals at which we flush out "message repeated" messages,
* in seconds after previous message is logged. After each flush,
@@ -285,6 +286,7 @@ static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list i
static int bDebugPrintModuleList = 1;/* output module list in debug mode? */
static uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */
static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */
+static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */
int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */
int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */
int iActExecOnceInterval = 0; /* execute action once every nn seconds */
@@ -418,7 +420,7 @@ static void processImInternal(void);
static int usage(void)
{
fprintf(stderr, "usage: rsyslogd [-cversion] [-46AdnqQvwx] [-lhostlist] [-sdomainlist]\n"
- " [-fconffile] [-ipidfile]\n"
+ " [-fconffile] [-ipidfile] [-Nlevel]\n"
"To run rsyslogd in native mode, use \"rsyslogd -c3 <other options>\"\n\n"
"For further information see http://www.rsyslog.com/doc\n");
exit(1); /* "good" exit - done to terminate usage() */
@@ -870,6 +872,7 @@ submitErrMsg(int iErr, uchar *msg)
RETiRet;
}
+
/* rgerhards 2004-11-09: the following is a function that can be used
* to log a message orginating from the syslogd itself. In sysklogd code,
* this is done by simply calling logmsg(). However, logmsg() is changed in
@@ -908,6 +911,18 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags)
datetime.getCurrTime(&(pMsg->tTIMESTAMP)); /* use the current time! */
flags |= INTERNAL_MSG;
+ /* we now check if we should print internal messages out to stderr. This was
+ * suggested by HKS as a way to help people troubleshoot rsyslog configuration
+ * (by running it interactively. This makes an awful lot of sense, so I add
+ * it here. -- rgerhards, 2008-07-28
+ * Note that error messages can not be disable during a config verify. This
+ * permits us to process unmodified config files which otherwise contain a
+ * supressor statement.
+ */
+ if(bErrMsgToStderr || iConfigVerify) {
+ fprintf(stderr, "rsyslogd: %s\n", msg);
+ }
+
if(bHaveMainQueue == 0) { /* not yet in queued mode */
iminternalAddMsg(pri, pMsg, flags);
} else {
@@ -1771,7 +1786,7 @@ void legacyOptsParseTCP(char ch, char *arg)
static char conflict = '\0';
if((conflict == 'g' && ch == 't') || (conflict == 't' && ch == 'g')) {
- fprintf(stderr, "rsyslog: If you want to use both -g and -t, use directives instead, -%c ignored.\n", ch);
+ fprintf(stderr, "rsyslogd: If you want to use both -g and -t, use directives instead, -%c ignored.\n", ch);
return;
} else
conflict = ch;
@@ -2190,11 +2205,15 @@ startInputModules(void)
/* INIT -- Initialize syslogd from configuration table
* init() is called at initial startup AND each time syslogd is HUPed
+ * Note that if iConfigVerify is set, only the config file is verified but nothing
+ * else happens. -- rgerhards, 2008-07-28
*/
-static void
+static rsRetVal
init(void)
{
DEFiRet;
+ rsRetVal localRet;
+ int iNbrActions;
char cbuf[BUFSIZ];
char bufStartUpMsg[512];
struct sigaction sigAct;
@@ -2237,22 +2256,42 @@ init(void)
*/
conf.cfsysline((uchar*)"ResetConfigVariables");
+ conf.ReInitConf();
+
/* open the configuration file */
- if((iRet = conf.processConfFile(ConfFile)) != RS_RET_OK) {
+ localRet = conf.processConfFile(ConfFile);
+ CHKiRet(conf.GetNbrActActions(&iNbrActions));
+
+ if(localRet != RS_RET_OK) {
+ errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", ConfFile);
+ } else if(iNbrActions == 0) {
+ errmsg.LogError(0, RS_RET_NO_ACTIONS, "CONFIG ERROR: there are no active actions configured. Inputs will "
+ "run, but no output whatsoever is created.");
+ }
+
+ if(localRet != RS_RET_OK || iNbrActions == 0) {
/* rgerhards: this code is executed to set defaults when the
* config file could not be opened. We might think about
* abandoning the run in this case - but this, too, is not
* very clever... So we stick with what we have.
* We ignore any errors while doing this - we would be lost anyhow...
*/
+ errmsg.LogError(0, NO_ERRCODE, "EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!");
selector_t *f = NULL;
- char szTTYNameBuf[_POSIX_TTY_NAME_MAX+1]; /* +1 for NULL character */
- dbgprintf("primary config file could not be opened - using emergency definitions.\n");
+
+ /* note: we previously used _POSIY_TTY_NAME_MAX+1, but this turned out to be
+ * too low on linux... :-S -- rgerhards, 2008-07-28
+ */
+ char szTTYNameBuf[128];
conf.cfline((uchar*)"*.ERR\t" _PATH_CONSOLE, &f);
+ conf.cfline((uchar*)"syslog.*\t" _PATH_CONSOLE, &f);
conf.cfline((uchar*)"*.PANIC\t*", &f);
+ conf.cfline((uchar*)"syslog.*\troot", &f);
if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) {
snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf);
conf.cfline((uchar*)cbuf, &f);
+ } else {
+ dbgprintf("error %d obtaining controlling terminal, not using that emergency rule\n", errno);
}
selectorAddList(f);
}
@@ -2290,6 +2329,12 @@ init(void)
}
}
+ /* we are done checking the config - now validate if we should actually run or not.
+ * If not, terminate. -- rgerhards, 2008-07-25
+ */
+ if(iConfigVerify)
+ ABORT_FINALIZE(RS_RET_VALIDATION_RUN);
+
/* switch the message object to threaded operation, if necessary */
if(MainMsgQueType == QUEUETYPE_DIRECT || iMainMsgQueueNumWorkers > 1) {
MsgEnableThreadSafety();
@@ -2371,7 +2416,9 @@ init(void)
sigaction(SIGHUP, &sigAct, NULL);
dbgprintf(" (re)started.\n");
- ENDfunc
+
+finalize_it:
+ RETiRet;
}
@@ -2638,7 +2685,6 @@ static rsRetVal loadBuildInModules(void)
* is that rsyslog will terminate if we can not register our built-in config commands.
* This, I think, is the right thing to do. -- rgerhards, 2007-07-31
*/
-// CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL));
@@ -2679,6 +2725,7 @@ static rsRetVal loadBuildInModules(void)
NULL, &bDebugPrintCfSysLineHandlerList, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"moddir", 0, eCmdHdlrGetWord, NULL, &pModDir, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"errormessagestostderr", 0, eCmdHdlrBinary, NULL, &bErrMsgToStderr, NULL));
/* now add other modules handlers (we should work on that to be able to do it in ClassInit(), but so far
* that is not possible). -- rgerhards, 2008-01-28
@@ -2734,9 +2781,9 @@ static void printVersion(void)
* move code out of the too-long main() function.
* rgerhards, 2007-10-17
*/
-static void mainThread()
+static rsRetVal mainThread()
{
- BEGINfunc
+ DEFiRet;
uchar *pTmp;
/* Note: signals MUST be processed by the thread this code is running in. The reason
@@ -2765,7 +2812,8 @@ static void mainThread()
pTmp = template_StdPgSQLFmt;
tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp));
- init();
+ CHKiRet(init());
+
if(Debug) {
dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n");
debugging_on = 1;
@@ -2784,7 +2832,9 @@ static void mainThread()
dbgprintf("initialization completed, transitioning to regular run mode\n");
mainloop();
- ENDfunc
+
+finalize_it:
+ RETiRet;
}
@@ -2967,6 +3017,98 @@ finalize_it:
}
+/* global initialization, to be done only once and before the mainloop is started.
+ * rgerhards, 2008-07-28 (extracted from realMain())
+ */
+static rsRetVal
+doGlblProcessInit(void)
+{
+ struct sigaction sigAct;
+ int num_fds;
+ int i;
+ DEFiRet;
+
+ checkPermissions();
+ thrdInit();
+
+ if( !(Debug || NoFork) )
+ {
+ dbgprintf("Checking pidfile.\n");
+ if (!check_pid(PidFile))
+ {
+ memset(&sigAct, 0, sizeof (sigAct));
+ sigemptyset(&sigAct.sa_mask);
+ sigAct.sa_handler = doexit;
+ sigaction(SIGTERM, &sigAct, NULL);
+
+ if (fork()) {
+ /* Parent process
+ */
+ sleep(300);
+ /* Not reached unless something major went wrong. 5
+ * minutes should be a fair amount of time to wait.
+ * Please note that this procedure is important since
+ * the father must not exit before syslogd isn't
+ * initialized or the klogd won't be able to flush its
+ * logs. -Joey
+ */
+ exit(1); /* "good" exit - after forking, not diasabling anything */
+ }
+ num_fds = getdtablesize();
+ for (i= 0; i < num_fds; i++)
+ (void) close(i);
+ untty();
+ }
+ else
+ {
+ fputs(" Already running.\n", stderr);
+ exit(1); /* "good" exit, done if syslogd is already running */
+ }
+ }
+ else
+ debugging_on = 1;
+
+ /* tuck my process id away */
+ dbgprintf("Writing pidfile %s.\n", PidFile);
+ if (!check_pid(PidFile))
+ {
+ if (!write_pid(PidFile))
+ {
+ fputs("Can't write pid.\n", stderr);
+ exit(1); /* exit during startup - questionable */
+ }
+ }
+ else
+ {
+ fputs("Pidfile (and pid) already exist.\n", stderr);
+ exit(1); /* exit during startup - questionable */
+ }
+ myPid = getpid(); /* save our pid for further testing (also used for messages) */
+
+ memset(&sigAct, 0, sizeof (sigAct));
+ sigemptyset(&sigAct.sa_mask);
+
+ sigAct.sa_handler = sigsegvHdlr;
+ sigaction(SIGSEGV, &sigAct, NULL);
+ sigAct.sa_handler = sigsegvHdlr;
+ sigaction(SIGABRT, &sigAct, NULL);
+ sigAct.sa_handler = doDie;
+ sigaction(SIGTERM, &sigAct, NULL);
+ sigAct.sa_handler = Debug ? doDie : SIG_IGN;
+ sigaction(SIGINT, &sigAct, NULL);
+ sigaction(SIGQUIT, &sigAct, NULL);
+ sigAct.sa_handler = reapchild;
+ sigaction(SIGCHLD, &sigAct, NULL);
+ sigAct.sa_handler = Debug ? debug_switch : SIG_IGN;
+ sigaction(SIGUSR1, &sigAct, NULL);
+ sigAct.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sigAct, NULL);
+ sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */
+
+ RETiRet;
+}
+
+
/* This is the main entry point into rsyslogd. Over time, we should try to
* modularize it a bit more...
*/
@@ -2974,16 +3116,15 @@ int realMain(int argc, char **argv)
{
DEFiRet;
- register int i;
register uchar *p;
- int num_fds;
int ch;
struct hostent *hent;
extern int optind;
extern char *optarg;
- struct sigaction sigAct;
int bEOptionWasGiven = 0;
int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */
+ int iHelperUOpt;
+ int bChDirRoot = 1; /* change the current working directory to "/"? */
char *arg; /* for command line option processing */
uchar legacyConfLine[80];
uchar *LocalHostName;
@@ -3003,7 +3144,7 @@ int realMain(int argc, char **argv)
* only when actually neeeded.
* rgerhards, 2008-04-04
*/
- while ((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nopqQr::s:t:u:vwx")) != EOF) {
+ while((ch = getopt(argc, argv, "46aAc:def:g:hi:l:m:M:nN:opqQr::s:t:u:vwx")) != EOF) {
switch((char)ch) {
case '4':
case '6':
@@ -3015,6 +3156,7 @@ int realMain(int argc, char **argv)
case 'l':
case 'm': /* mark interval */
case 'n': /* don't fork */
+ case 'N': /* enable config verify mode */
case 'o':
case 'p':
case 'q': /* add hostname if DNS resolving has failed */
@@ -3078,9 +3220,6 @@ int realMain(int argc, char **argv)
ppid = getpid();
- if(chdir ("/") != 0)
- fprintf(stderr, "Can not do 'cd /' - still trying to run\n");
-
CHKiRet_Hdlr(InitGlobalClasses()) {
fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n"
"Did you do a \"make install\"?\n"
@@ -3213,6 +3352,9 @@ int realMain(int argc, char **argv)
case 'n': /* don't fork */
NoFork = 1;
break;
+ case 'N': /* enable config verify mode */
+ iConfigVerify = atoi(arg);
+ break;
case 'o':
if(iCompatibilityMode < 3) {
if(!bImUxSockLoaded) {
@@ -3263,8 +3405,11 @@ int realMain(int argc, char **argv)
fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n");
break;
case 'u': /* misc user settings */
- if(atoi(arg) == 1)
+ iHelperUOpt = atoi(arg);
+ if(iHelperUOpt & 0x01)
bParseHOSTNAMEandTAG = 0;
+ if(iHelperUOpt & 0x02)
+ bChDirRoot = 0;
break;
case 'w': /* disable disallowed host warnigs */
glbl.SetOption_DisallowWarning(0);
@@ -3281,6 +3426,17 @@ int realMain(int argc, char **argv)
if(iRet != RS_RET_END_OF_LINKEDLIST)
FINALIZE;
+ if(iConfigVerify) {
+ fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n",
+ VERSION, iConfigVerify, ConfFile);
+ }
+
+ if(bChDirRoot) {
+ if(chdir("/") != 0)
+ fprintf(stderr, "Can not do 'cd /' - still trying to run\n");
+ }
+
+
/* process compatibility mode settings */
if(iCompatibilityMode < 3) {
errmsg.LogError(0, NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically "
@@ -3304,86 +3460,10 @@ int realMain(int argc, char **argv)
"more and cast your vote if you want us to keep this feature.");
}
- checkPermissions();
- thrdInit();
+ if(!iConfigVerify)
+ CHKiRet(doGlblProcessInit());
- if( !(Debug || NoFork) )
- {
- dbgprintf("Checking pidfile.\n");
- if (!check_pid(PidFile))
- {
- memset(&sigAct, 0, sizeof (sigAct));
- sigemptyset(&sigAct.sa_mask);
- sigAct.sa_handler = doexit;
- sigaction(SIGTERM, &sigAct, NULL);
-
- if (fork()) {
- /*
- * Parent process
- */
- sleep(300);
- /*
- * Not reached unless something major went wrong. 5
- * minutes should be a fair amount of time to wait.
- * Please note that this procedure is important since
- * the father must not exit before syslogd isn't
- * initialized or the klogd won't be able to flush its
- * logs. -Joey
- */
- exit(1); /* "good" exit - after forking, not diasabling anything */
- }
- num_fds = getdtablesize();
- for (i= 0; i < num_fds; i++)
- (void) close(i);
- untty();
- }
- else
- {
- fputs(" Already running.\n", stderr);
- exit(1); /* "good" exit, done if syslogd is already running */
- }
- }
- else
- debugging_on = 1;
-
- /* tuck my process id away */
- dbgprintf("Writing pidfile %s.\n", PidFile);
- if (!check_pid(PidFile))
- {
- if (!write_pid(PidFile))
- {
- fputs("Can't write pid.\n", stderr);
- exit(1); /* exit during startup - questionable */
- }
- }
- else
- {
- fputs("Pidfile (and pid) already exist.\n", stderr);
- exit(1); /* exit during startup - questionable */
- }
- myPid = getpid(); /* save our pid for further testing (also used for messages) */
-
- memset(&sigAct, 0, sizeof (sigAct));
- sigemptyset(&sigAct.sa_mask);
-
- sigAct.sa_handler = sigsegvHdlr;
- sigaction(SIGSEGV, &sigAct, NULL);
- sigAct.sa_handler = sigsegvHdlr;
- sigaction(SIGABRT, &sigAct, NULL);
- sigAct.sa_handler = doDie;
- sigaction(SIGTERM, &sigAct, NULL);
- sigAct.sa_handler = Debug ? doDie : SIG_IGN;
- sigaction(SIGINT, &sigAct, NULL);
- sigaction(SIGQUIT, &sigAct, NULL);
- sigAct.sa_handler = reapchild;
- sigaction(SIGCHLD, &sigAct, NULL);
- sigAct.sa_handler = Debug ? debug_switch : SIG_IGN;
- sigaction(SIGUSR1, &sigAct, NULL);
- sigAct.sa_handler = SIG_IGN;
- sigaction(SIGPIPE, &sigAct, NULL);
- sigaction(SIGXFSZ, &sigAct, NULL); /* do not abort if 2gig file limit is hit */
-
- mainThread();
+ CHKiRet(mainThread());
/* do any de-init's that need to be done AFTER this comment */
@@ -3392,9 +3472,12 @@ int realMain(int argc, char **argv)
thrdExit();
finalize_it:
- if(iRet != RS_RET_OK)
- fprintf(stderr, "rsyslogd run failed with error %d\n(see rsyslog.h "
- "or http://www.rsyslog.com/errcode to learn what that number means)\n", iRet);
+ if(iRet == RS_RET_VALIDATION_RUN) {
+ fprintf(stderr, "rsyslogd: End of config validation run. Bye.\n");
+ } else if(iRet != RS_RET_OK) {
+ fprintf(stderr, "rsyslogd run failed with error %d (see rsyslog.h "
+ "or try http://www.rsyslog.com/e/%d to learn what that number means)\n", iRet, iRet*-1);
+ }
ENDfunc
return 0;