summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes6
-rw-r--r--README6
-rw-r--r--include/ulogd/ulogd.h35
-rw-r--r--input/packet/ulogd_inppkt_ULOG.c31
-rw-r--r--output/mysql/ulogd_MYSQL.c63
-rw-r--r--output/ulogd_output_OPRINT.c10
-rw-r--r--ulogd.c181
7 files changed, 217 insertions, 115 deletions
diff --git a/Changes b/Changes
index 886f86e..cbba483 100644
--- a/Changes
+++ b/Changes
@@ -1,3 +1,9 @@
+Version 2.00alpha (2004-Oct-03)
+- Total re-work. ulogd2 is almost unrelated to the ULOG netfilter target.
+ Instead, it has become a generic logging framework for anything from
+ firewall logs, flow-based accounting to kernel network performance
+ statistics.
+
Version 1.10 (2003-Oct-xx)
- Change format of configuration file. Now every plugin has it's own section
in the config file, making the whole parsing procedure easier - and
diff --git a/README b/README
index 3510007..545e7f7 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
Userspace logging facility for iptables / linux 2.4
-$Id: README,v 1.7 2002/04/16 12:44:41 laforge Exp $
+$Id$
Project Homepage: http://www.gnumonks.org/projects/ulogd
Mailinglist: http://lists.gnumonks.org/mailman/listinfo/ulogd/
@@ -88,10 +88,10 @@ Setting --ulog-cprange to 0 does always copy the whole packet. Default is 0
===> COPYRIGHT + CREDITS
-The code is (C) 2000-2003 by Harald Welte <laforge@gnumonks.org>
+The code is (C) 2000-2004 by Harald Welte <laforge@gnumonks.org>
Thanks also to the valuable Contributions of Daniel Stone, Alexander
Janssen and Michael Stolovitzsky.
-Credits to Rusty Russel, James Morris, Marc Boucher and all the other
+Credits to Rusty Russell, James Morris, Marc Boucher and all the other
netfilter hackers.
diff --git a/include/ulogd/ulogd.h b/include/ulogd/ulogd.h
index b3ce46e..7c3aa15 100644
--- a/include/ulogd/ulogd.h
+++ b/include/ulogd/ulogd.h
@@ -68,9 +68,9 @@ enum ulogd_dtype {
};
/* structure describing an input / output parameter of a plugin */
-typedef struct ulogd_key {
+struct ulogd_key {
/* next interpreter return (key) in the global list */
- struct ulog_iret *next;
+ struct ulogd_iret *next;
/* length of the returned value (only for lengthed types */
u_int32_t len;
/* type of the returned value (ULOGD_IRET_...) */
@@ -99,11 +99,11 @@ typedef struct ulogd_key {
int64_t i64;
void *ptr;
} value;
- struct ulog_ket *source;
+ struct ulogd_iret *source;
} u;
-} ulogd_iret_t;
+};
-typedef struct ulogd_plugin {
+struct ulogd_plugin {
/* global list of plugins */
struct list_head list;
/* name of this plugin (predefined by plugin) */
@@ -134,28 +134,33 @@ typedef struct ulogd_plugin {
/* function to destruct an existing pluginstance */
int (*destructor)(struct ulogd_pluginstance *instance);
/* configuration parameters */
- config_entry_t *configs;
-} ulogd_interpreter_t;
+ struct config_keyest config_kset;
+};
/* an instance of a plugin, element in a stack */
-typedef struct ulogd_pluginstance {
- /* global list of pluginstance stacks */
+struct ulogd_pluginstance {
+ /* global list of pluginstance stacks. only valid for first item */
struct list_head stack_list;
/* local list of plugins in this stack */
struct list_head list;
/* plugin (master) */
struct ulogd_plugin *plugin;
+ /* name / id of this instance*/
+ char id[ULOGD_MAX_KEYLEN];
/* per-instance input keys */
struct ulogd_input *input;
/* per-instance output keys */
struct ulogd_iret *output;
+ /* per-instance config parameters (array) */
+ config_entry_t *configs;
+ unsigned int num_configs;
/* private data */
char private[0];
-} ulogd_pluginstance_t;
+};
/* entries of the key hash */
struct ulogd_keyh_entry {
- ulog_interpreter_t *interp; /* interpreter for this key */
+ struct ulogd_plugin *interp; /* interpreter for this key */
unsigned int offset; /* offset within interpreter */
const char *name; /* name of this particular key */
};
@@ -165,10 +170,10 @@ struct ulogd_keyh_entry {
***********************************************************************/
/* register a new interpreter plugin */
-void ulogd_register_plugin(ulog_plugin_t *me);
+void ulogd_register_plugin(struct ulogd_plugin *me);
-/* allocate a new ulog_iret_t */
-ulog_iret_t *alloc_ret(const u_int16_t type, const char*);
+/* allocate a new ulogd_iret */
+struct ulogd_iret *alloc_ret(const u_int16_t type, const char*);
/* write a message to the daemons' logfile */
void __ulogd_log(int level, char *file, int line, const char *message, ...);
@@ -185,7 +190,7 @@ unsigned int interh_getid(const char *name);
unsigned int keyh_getid(const char *name);
/* get a result for a given key id */
-ulog_iret_t *keyh_getres(unsigned int id);
+struct ulogd_iret *keyh_getres(unsigned int id);
/* the key hash itself */
extern struct ulogd_keyh_entry *ulogd_keyh;
diff --git a/input/packet/ulogd_inppkt_ULOG.c b/input/packet/ulogd_inppkt_ULOG.c
index ee3840d..640b86c 100644
--- a/input/packet/ulogd_inppkt_ULOG.c
+++ b/input/packet/ulogd_inppkt_ULOG.c
@@ -24,6 +24,33 @@ struct ulog_input {
};
/* configuration entries */
+
+static struct config_entry ulog_ces[] = {
+ {
+ .key = "bufsize",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = ULOGD_BUFSIZE_DEFAULT,
+ },
+ {
+ .key = "nlgroup",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = ULOGD_NLGROUP_DEFAULT,
+ },
+ {
+ .key = "rmem",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = ULOGD_RMEM_DEFAULT,
+ },
+};
+
+#define bufsiz_ce(x) (x[0])
+#define nlgroup_ce(x) (x[1])
+#define rmem_cd(x) (x[2])
+
+#if 0
static config_entry_t bufsiz_ce = { NULL, "bufsize", CONFIG_TYPE_INT,
CONFIG_OPT_NONE, 0,
{ value: ULOGD_BUFSIZE_DEFAULT } };
@@ -35,6 +62,7 @@ static config_entry_t nlgroup_ce = { &bufsiz_ce, "nlgroup", CONFIG_TYPE_INT,
static config_entry_t rmem_ce = { &nlgroup_ce, "rmem", CONFIG_TYPE_INT,
CONFIG_OPT_NONE, 0,
{ value: ULOGD_RMEM_DEFAULT } };
+#endif
static struct ulogd_key output_keys[] = {
@@ -239,7 +267,8 @@ struct ulogd_plugin libulog_plugin = {
},
.constructor = &init,
.destructor = &fini,
- .configs = &rmem_ce,
+ .num_configs = (sizeof(ulog_ces)/sizeof(struct config_entry)),
+ .configs = &ulog_ces,
};
void _init(void)
diff --git a/output/mysql/ulogd_MYSQL.c b/output/mysql/ulogd_MYSQL.c
index 894098f..78c799d 100644
--- a/output/mysql/ulogd_MYSQL.c
+++ b/output/mysql/ulogd_MYSQL.c
@@ -65,39 +65,45 @@ static char *stmt_val;
static char *stmt_ins;
/* our configuration directives */
-static config_entry_t db_ce = {
- .key = "db",
- .type = CONFIG_TYPE_STRING,
- .options = CONFIG_OPT_MANDATORY,
+static struct config_entry mysql_ces[] = {
+ {
+ .key = "db",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_MANDATORY,
+ },
+ {
+ .key = "host",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_MANDATORY,
+ },
+ {
+ .key = "user",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_MANDATORY,
+ },
+ {
+ .key = "pass",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_MANDATORY,
+ },
+ {
+ .key = "table",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_MANDATORY,
+ },
};
-static config_entry_t host_ce = {
- .next = &db_ce,
- .key = "host",
- .type = CONFIG_TYPE_STRING,
- .options = CONFIG_OPT_MANDATORY,
+static struct config_keyset mysql_keyset = {
+ .num_ces = sizeof(mysql_ces)/sizeof(struct config_entry),
+ .ces = &mysql_ces,
};
-static config_entry_t user_ce = {
- .next = &host_ce,
- .key = "user",
- .type = CONFIG_TYPE_STRING,
- .options = CONFIG_OPT_MANDATORY,
-};
-
-static config_entry_t pass_ce = {
- .next = &user_ce,
- .key = "pass",
- .type = CONFIG_TYPE_STRING,
- .options = CONFIG_OPT_MANDATORY,
-};
-static config_entry_t table_ce = {
- .next = &pass_ce,
- .key = "table",
- .type = CONFIG_TYPE_STRING,
- .options = CONFIG_OPT_MANDATORY,
-};
+#define db_ce(x) x[0]
+#define host_ce(x) x[1]
+#define user_ce(x) x[2]
+#define pass_ce(x) x[3]
+#define table_ce(x) x[4]
/* our main output function, called by ulogd */
static int mysql_output(ulog_iret_t *result)
@@ -357,6 +363,7 @@ static ulog_output_t mysql_plugin = {
.output = &mysql_output,
.init = &mysql_init,
.fini = &mysql_fini,
+ .config_kset = &mysql_keyset,
};
void _init(void)
diff --git a/output/ulogd_output_OPRINT.c b/output/ulogd_output_OPRINT.c
index ea5ff6a..dfcad05 100644
--- a/output/ulogd_output_OPRINT.c
+++ b/output/ulogd_output_OPRINT.c
@@ -81,9 +81,12 @@ static int oprint_interp(struct ulogd_pluginstance *instance)
return 0;
}
-static config_entry_t outf_ce = { NULL, "file", CONFIG_TYPE_STRING,
- CONFIG_OPT_NONE, 0,
- { string: ULOGD_OPRINT_DEFAULT } };
+static struct config_entry outf_ce = {
+ .key = "file",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_NONE,
+ .u.string = ULOGD_OPRINT_DEFAULT
+};
static void sighup_handler_print(int signal)
{
@@ -155,6 +158,7 @@ static struct ulogd_plugin oprint_plugin = {
.destructor = &oprint_fini,
.signal = &sighup_handler_print,
.configs = &outf_ce,
+ .num_configs = 1,
};
void _init(void)
diff --git a/ulogd.c b/ulogd.c
index 50ac6b4..be8804c 100644
--- a/ulogd.c
+++ b/ulogd.c
@@ -87,10 +87,10 @@ static int loglevel = 1; /* current loglevel */
static char *ulogd_configfile = ULOGD_CONFIGFILE;
/* linked list for all registered interpreters */
-//static ulog_interpreter_t *ulogd_interpreters;
+//static struct ulog_interpreter *ulogd_interpreters;
/* linked list for all registered plugins */
-static ulog_output_t *ulogd_plugins;
+static struct ulogd_plugin *ulogd_plugins;
LIST_HEAD(ulogd_pi_stacks);
/***********************************************************************
@@ -108,7 +108,7 @@ LIST_HEAD(ulogd_pi_stacks);
#define INTERH_ALLOC_GRAN 5
/* hashtable for all registered interpreters */
-static ulog_interpreter_t **ulogd_interh;
+static struct ulogd_interpreter **ulogd_interh;
/* current hashtable size */
static unsigned int ulogd_interh_ids_alloc;
@@ -117,7 +117,7 @@ static unsigned int ulogd_interh_ids_alloc;
static unsigned int ulogd_interh_ids;
/* allocate a new interpreter id and write it into the interpreter struct */
-static unsigned int interh_allocid(ulog_interpreter_t *ip)
+static unsigned int interh_allocid(struct ulogd_interpreter *ip)
{
unsigned int id;
@@ -125,15 +125,15 @@ static unsigned int interh_allocid(ulog_interpreter_t *ip)
if (id >= ulogd_interh_ids_alloc) {
if (!ulogd_interh)
- ulogd_interh = (ulog_interpreter_t **)
+ ulogd_interh = (struct ulogd_interpreter **)
malloc(INTERH_ALLOC_GRAN *
- sizeof(ulog_interpreter_t));
+ sizeof(struct ulogd_interpreter));
else
- ulogd_interh = (ulog_interpreter_t **)
+ ulogd_interh = (struct ulogd_interpreter **)
realloc(ulogd_interh,
(INTERH_ALLOC_GRAN +
ulogd_interh_ids_alloc) *
- sizeof(ulog_interpreter_t));
+ sizeof(struct ulogd_interpreter));
ulogd_interh_ids_alloc += INTERH_ALLOC_GRAN;
}
@@ -180,7 +180,7 @@ static unsigned int ulogd_keyh_ids_alloc;
static unsigned int ulogd_keyh_ids;
/* allocate a new key_id */
-static unsigned int keyh_allocid(ulog_interpreter_t *ip, unsigned int offset,
+static unsigned int keyh_allocid(struct ulogd_interpreter *ip, unsigned int offset,
const char *name)
{
unsigned int id;
@@ -255,9 +255,9 @@ char *keyh_getname(unsigned int id)
}
/* get result for given key id. does not check if result valid */
-ulog_iret_t *keyh_getres(unsigned int id)
+struct ulogd_iret *keyh_getres(unsigned int id)
{
- ulog_iret_t *ret;
+ struct ulogd_iret *ret;
if (id > ulogd_keyh_ids) {
ulogd_log(ULOGD_NOTICE,
@@ -275,7 +275,7 @@ ulog_iret_t *keyh_getres(unsigned int id)
***********************************************************************/
/* try to lookup a registered interpreter for a given name */
-static ulog_interpreter_t *find_interpreter(const char *name)
+static struct ulogd_interpreter *find_interpreter(const char *name)
{
unsigned int id;
@@ -288,7 +288,7 @@ static ulog_interpreter_t *find_interpreter(const char *name)
/* the function called by all interpreter plugins for registering their
* target. */
-void register_interpreter(ulog_interpreter_t *me)
+void register_interpreter(struct ulogd_interpreter *me)
{
unsigned int i;
@@ -334,9 +334,9 @@ void register_interpreter(ulog_interpreter_t *me)
***********************************************************************/
/* try to lookup a registered plugin for a given name */
-static ulog_plugin_t *find_plugin(const char *name)
+static struct ulogd_plugin *find_plugin(const char *name)
{
- ulog_output_t *ptr;
+ struct ulogd_plugin *ptr;
for (ptr = ulogd_outputs; ptr; ptr = ptr->next) {
if (strcmp(name, ptr->name) == 0)
@@ -347,7 +347,7 @@ static ulog_plugin_t *find_plugin(const char *name)
}
/* the function called by all plugins for registering themselves */
-void register_plugin(ulog_plugin_t *me)
+void register_plugin(struct ulogd_plugin *me)
{
if (find_plugin(me->name)) {
ulogd_log(ULOGD_NOTICE, "output `%s' already registered\n",
@@ -395,9 +395,9 @@ void __ulogd_log(int level, char *file, int line, const char *format, ...)
}
/* propagate results to all registered output plugins */
-static void propagate_results(ulog_iret_t *ret)
+static void propagate_results(struct ulogd_iret *ret)
{
- ulog_output_t *p;
+ struct ulogd_plugin *p;
for (p = ulogd_outputs; p; p = p->next) {
(*p->output)(ret);
@@ -405,9 +405,9 @@ static void propagate_results(ulog_iret_t *ret)
}
/* clean results (set all values to 0 and free pointers) */
-static void clean_results(ulog_iret_t *ret)
+static void clean_results(struct ulogd_iret *ret)
{
- ulog_iret_t *r;
+ struct ulogd_iret *r;
for (r = ret; r; r = r->next) {
if (r->flags & ULOGD_RETF_FREE) {
@@ -421,17 +421,37 @@ static void clean_results(ulog_iret_t *ret)
-static int ulogd_pluginstance_t *ulogd_pluginsance_alloc(int len)
+static struct ulogd_pluginstance *
+pluginstance_alloc_init(struct ulogd_plugin *pl, char *pi_id,
+ struct ulogd_pluginstance *stack)
{
- ulogd_pluginstance_t *pi = malloc(sizeof(ulogd_pluginstance_t)+len);
+ unsigned int ce_size;
+ struct ulogd_pluginstance *pi = malloc(sizeof(struct ulogd_pluginstance)+len);
if (!pi)
return NULL;
- memset(pi, 0, sizeof(ulogd_pluginstance_t)+len);
+
+ /* initialize */
+ memset(pi, 0, sizeof(struct ulogd_pluginstance)+len);
INIT_LIST_HEAD(&pi->list);
+ pi->plugin = pl;
+ memcpy(pi->id, pi_id, sizeof(pi->id));
+
+ /* copy config keys */
+ pi->config_kset.num_ces = pl->config_kset.num_ces;
+ ce_size = pl->config_kset.num_ces*sizeof(struct config_entry);
+ pi->config_kset.ces = malloc(ce_size);
+ if (!pi->configs) {
+ free(pi);
+ return NULL;
+ }
+ memcpy(pi->config_kset.ces, pl->config_kset.ces, ce_size);
+ /* FIXME: allocate input and output keys ?*/
+
return pi;
}
+
/* plugin loader to dlopen() a plugins */
static int load_plugin(char *file)
{
@@ -446,7 +466,7 @@ static int load_plugin(char *file)
/* create a new stack of plugins */
static int create_stack(char *option)
{
- ulogd_pluginstance_t *stack = NULL;
+ struct ulogd_pluginstance *stack = NULL;
char *buf = strdup(option);
char *tok;
@@ -457,19 +477,43 @@ static int create_stack(char *option)
ulogd_log(ULOGD_DEBUG, "building new pluginstance stack:\n");
- for (tok = strtok(buf, ":\n"); tok; tok = strtok(NULL, ":\n")) {
- ulogd_pluginstance_t *pi = ulogd_pluginstance_alloc(0);
- ulogd_plugin_t *pl = find_plugin(tok);
+ for (tok = strtok(buf, ",\n"); tok; tok = strtok(NULL, ",\n")) {
+ char *plname, *equals;
+ char pi_id[ULOGD_MAX_KEYLEN];
+ struct ulogd_pluginstance *pi;
+ struct ulogd_plugin *pl;
+
+ /* parse token into sub-tokens */
+ equals = strchr(tok, '=');
+ if (!equals || (equals - tok >= ULOGD_MAX_KEYLEN)) {
+ ulogd_log(ULOGD_ERROR, "syntax error while parsing `%s'"
+ "of line `%s'\n", tok, buf);
+ }
+ strncpy(pi_id, tok, ULOGD_MAX_KEYLEN-1);
+ pi_id[equals-tok] = '\0';
+ plname = equals+1;
+
+ /* find matching plugin */
+ pl = find_plugin(plname);
if (!pl) {
ulogd_log(ULOGD_ERROR, "can't find requested plugin "
"%s\n", );
return 1;
}
- pi->plugin = pl;
- ulogd_log(ULOGD_DEBUG, "pushing `%s' on stack\n", pl->name);
- /* FIXME: allocate input and output keys */
+ /* allocate */
+ pi = ulogd_pluginstance_alloc_init(pl. pi_id, stack);
+ if (!pi) {
+ ulogd_log(ULOGD_ERROR,
+ "unable to allocate pluginstance for %s\n",
+ pi_id);
+ return 1;
+ }
+ /* FIXME: call constructor routine from end to beginning,
+ * fix up input/output keys */
+
+ ulogd_log(ULOGD_DEBUG, "pushing `%s' on stack\n", pl->name);
if (!stack)
stack = pi;
else
@@ -498,7 +542,7 @@ static int logfile_open(const char *name)
}
/* wrapper to handle conffile error codes */
-static int parse_conffile(const char *section, config_entry_t *ce)
+static int parse_conffile(const char *section, struct config_keyset *ce)
{
int err;
@@ -538,42 +582,47 @@ static int parse_conffile(const char *section, config_entry_t *ce)
}
/* configuration directives of the main program */
-static config_entry_t logf_ce = {
- .next = NULL,
- .key = "logfile",
- .type = CONFIG_TYPE_STRING,
- .options = CONFIG_OPT_NONE,
- .u.string = ULOGD_LOGFILE_DEFAULT,
-};
-
-static config_entry_t plugin_ce = {
- .next = &logf_ce,
- .key = "plugin",
- .type = CONFIG_TYPE_CALLBACK,
- .options = CONFIG_OPT_MULTI,
- .u.parser: &load_plugin,
+static struct config_entry ulogd_ces[] = {
+ {
+ .key = "logfile",
+ .type = CONFIG_TYPE_STRING,
+ .options = CONFIG_OPT_NONE,
+ .u.string = ULOGD_LOGFILE_DEFAULT,
+ },
+ {
+ .key = "plugin",
+ .type = CONFIG_TYPE_CALLBACK,
+ .options = CONFIG_OPT_MULTI,
+ .u.parser = &load_plugin,
+ },
+ {
+ .key = "loglevel",
+ .type = CONFIG_TYPE_INT,
+ .options = CONFIG_OPT_NONE,
+ .u.value = 1,
+ },
+ {
+ .key = "stack",
+ .type = CONFIG_TYPE_CALLBACK,
+ .options = CONFIG_OPT_NONE,
+ .u.parser = &create_stack,
+ },
};
-static config_entry_t loglevel_ce = {
- .next = &logf_ce,
- .key = "loglevel",
- .type = CONFIG_TYPE_INT,
- .options = CONFIG_OPT_NONE,
- .u.value = 1,
+static struct config_keyset ulogd_kset = {
+ .ces = &ulogd_ces,
+ .num_ces = sizeof(ulogd_ces)/sizeof(struct config_entry),
};
-static config_entry_t stack_ce = {
- .next = &loglevel_ce,
- .key = "stack",
- .type = CONFIG_TYPE_CALLBACK,
- .options = CONFIG_OPT_NONE,
- .u.parser = &create_stack,
-};
+#define logfile_ce ulogd_ces[0]
+#define plugin_ce ulogd_ces[1]
+#define loglevel_ce ulogd_ces[2]
+#define stack_ce ulogd_ces[3]
static void sigterm_handler(int signal)
{
- ulog_output_t *p;
+ struct ulogd_plugin *p;
ulogd_log(ULOGD_NOTICE, "sigterm received, exiting\n");
@@ -592,7 +641,7 @@ static void sigterm_handler(int signal)
static void sighup_handler(int signal)
{
- ulog_output_t *p;
+ struct ulogd_plugin *p;
if (logfile != stdout) {
fclose(logfile);
@@ -697,7 +746,7 @@ int main(int argc, char* argv[])
}
/* parse config file */
- if (parse_conffile("global", &logf_ce)) {
+ if (parse_conffile("global", &ulogd_kset)) {
ulogd_log(ULOGD_FATAL, "parse_conffile\n");
exit(1);
}
@@ -705,12 +754,13 @@ int main(int argc, char* argv[])
if (change_uid) {
ulogd_log(ULOGD_NOTICE, "Changing UID / GID\n");
if (setgid(gid)) {
- ulogd_log(ULOGD_FATAL, "can't set GID\n");
+ ulogd_log(ULOGD_FATAL, "can't set GID %u\n", gid);
ipulog_perror(NULL);
exit(1);
}
if (setegid(gid)) {
- ulogd_log(ULOGD_FATAL, "can't sett effective GID\n");
+ ulogd_log(ULOGD_FATAL, "can't sett effective GID %u\n",
+ gid);
ipulog_perror(NULL);
exit(1);
}
@@ -720,12 +770,13 @@ int main(int argc, char* argv[])
exit(1);
}
if (setuid(uid)) {
- ulogd_log(ULOGD_FATAL, "can't set UID\n");
+ ulogd_log(ULOGD_FATAL, "can't set UID %u\n", uid);
ipulog_perror(NULL);
exit(1);
}
if (seteuid(uid)) {
- ulogd_log(ULOGD_FATAL, "can't set effective UID\n");
+ ulogd_log(ULOGD_FATAL, "can't set effective UID %u\n",
+ uid);
ipulog_perror(NULL);
exit(1);
}