aboutsummaryrefslogtreecommitdiff
path: root/jabberd/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'jabberd/main.c')
-rw-r--r--jabberd/main.c341
1 files changed, 243 insertions, 98 deletions
diff --git a/jabberd/main.c b/jabberd/main.c
index f195f72..f073e1e 100644
--- a/jabberd/main.c
+++ b/jabberd/main.c
@@ -145,24 +145,33 @@ usage ()
}
-/* Configuration file handling */
-
-typedef void (*cfg_fun) (unsigned line, char *kw, char *val);
+struct kw_int
+{
+ char *name;
+ int tok;
+};
-void
-cfg_syslog_tag (unsigned line, char *kw, char *val)
+int
+syslog_to_n (struct kw_int *kw, char *str, int *pint)
{
- syslog_tag = strdup (val);
+ int i;
+
+ if (strncasecmp (str, "LOG_", 4) == 0)
+ str += 4;
+
+ for (; kw->name; kw++)
+ if (strcasecmp (kw->name, str) == 0)
+ {
+ *pint = kw->tok;
+ return 0;
+ }
+ return 1;
}
-void
-cfg_syslog_facility (unsigned line, char *kw, char *val)
+int
+str_to_facility (char *str, int *pfacility)
{
- int i;
- static struct {
- char *name;
- int facility;
- } syslog_kw[] = {
+ static struct kw_int kw_facility[] = {
{ "USER", LOG_USER },
{ "DAEMON", LOG_DAEMON },
{ "AUTH", LOG_AUTH },
@@ -174,29 +183,141 @@ cfg_syslog_facility (unsigned line, char *kw, char *val)
{ "LOCAL5", LOG_LOCAL5 },
{ "LOCAL6", LOG_LOCAL6 },
{ "LOCAL7", LOG_LOCAL7 },
- { "MAIL", LOG_MAIL }
+ { "MAIL", LOG_MAIL },
+ { NULL }
};
+ return syslog_to_n (kw_facility, str, pfacility);
+}
- if (strncasecmp (val, "LOG_", 4) == 0)
- val += 4;
+int
+str_to_priority (char *str, int *pprio)
+{
+ static struct kw_int kw_prio[] = {
+ { "EMERG", LOG_EMERG },
+ { "ALERT", LOG_ALERT },
+ { "CRIT", LOG_CRIT },
+ { "ERR", LOG_ERR },
+ { "WARNING", LOG_WARNING },
+ { "NOTICE", LOG_NOTICE },
+ { "INFO", LOG_INFO },
+ { "DEBUG", LOG_DEBUG },
+ { NULL }
+ };
+ return syslog_to_n (kw_prio, str, pprio);
+}
- for (i = 0; i < sizeof (syslog_kw) / sizeof (syslog_kw[0]); i++)
- if (strcasecmp (syslog_kw[i].name, val) == 0)
- {
- log_facility = syslog_kw[i].facility;
- return;
- }
- logmsg (LOG_ERR, "%s:%u: Unknown facility `%s'", config_file, line, val);
+
+
+/* Configuration file handling */
+
+struct cfg_file
+{
+ FILE *fp;
+ unsigned line;
+ char *buf;
+ size_t size;
+};
+
+typedef void (*cfg_fun) (struct cfg_file *file, char *kw, char *val, void *data);
+
+struct kw_handler
+{
+ char *kw;
+ cfg_fun handler;
+};
+
+static cfg_fun
+find_cfg_fun (struct kw_handler *kwtab, char *kw)
+{
+ for (; kwtab->kw; kwtab++)
+ if (strcmp (kwtab->kw, kw) == 0)
+ return kwtab->handler;
+ return NULL;
+}
+
+void
+parse_block (struct cfg_file *file, void *data,
+ struct kw_handler *kwtab, const char *end)
+{
+ while (getline (&file->buf, &file->size, file->fp) > 0)
+ {
+ size_t len;
+ char *p, *kw, *val = NULL;
+ cfg_fun fun;
+
+ file->line++;
+ for (p = file->buf; *p && isspace (*p); p++)
+ ;
+ if (*p == '#' || *p == 0)
+ continue;
+
+ len = strlen (p);
+ if (p[len-1] == '\n')
+ p[--len] = 0;
+
+ for (;len > 0 && isspace (p[len-1]); len--)
+ ;
+
+ if (len > 0)
+ p[len] = 0;
+ else
+ continue;
+
+ kw = p;
+ for (; *p && !isspace (*p); p++)
+ ;
+
+ if (*p)
+ {
+ *p++ = 0;
+ for (; *p && isspace (*p); p++)
+ ;
+
+ val = p;
+ }
+
+ if (end && val == NULL && strcmp (kw, end) == 0)
+ break;
+
+ fun = find_cfg_fun (kwtab, kw);
+ if (fun)
+ fun (file, kw, val, data);
+ else
+ {
+#ifdef ALLOW_LEGACY_CONFIG
+ logmsg (LOG_WARNING, "%s:%u: legacy line", config_file, file->line);
+ register_jabber_process (kw, val);
+#else
+ logmsg (LOG_ERR, "%s:%u: unrecognized line", config_file, file->line);
+#endif
+ }
+ }
+}
+
+void
+cfg_syslog_tag (struct cfg_file *file, char *kw, char *val, void *unused)
+{
+ syslog_tag = strdup (val);
}
void
-cfg_user (unsigned line, char *kw, char *val)
+cfg_syslog_facility (struct cfg_file *file, char *kw, char *val, void *unused)
+{
+ if (str_to_facility (val, &log_facility))
+ logmsg (LOG_ERR, "%s:%u: Unknown facility `%s'",
+ config_file, file->line, val);
+}
+
+void
+cfg_user (struct cfg_file *file, char *kw, char *val, void *unused)
{
struct passwd *pwd = getpwnam (val);
if (!pwd)
- logmsg (LOG_ERR, "%s:%u: no such user `%s'", config_file, line, val);
+ logmsg (LOG_ERR, "%s:%u: no such user `%s'",
+ config_file, file->line, val);
else if (pwd->pw_uid == 0)
- logmsg (LOG_ERR, "%s:%u: user `%s' has zero UID", config_file, line, val);
+ logmsg (LOG_ERR, "%s:%u: user `%s' has zero UID", config_file,
+ file->line, val);
else
user = strdup (val);
}
@@ -210,7 +331,7 @@ struct group_list
static struct group_list *group_list;
void
-cfg_group (unsigned line, char *kw, char *val)
+cfg_group (struct cfg_file *file, char *kw, char *val, void *unused)
{
struct group *group = getgrnam (val);
if (group)
@@ -222,17 +343,17 @@ cfg_group (unsigned line, char *kw, char *val)
}
else
logmsg(LOG_ERR, "%s:%u: unknown group `%s'", config_file,
- line, val);
+ file->line, val);
}
void
-cfg_pidfile (unsigned line, char *kw, char *val)
+cfg_pidfile (struct cfg_file *file, char *kw, char *val, void *unused)
{
pidfile = strdup (val);
}
void
-cfg_prog (unsigned line, char *kw, char *val)
+cfg_prog (struct cfg_file *file, char *kw, char *val, void *unused)
{
char *prog = val;
char *p = val;
@@ -251,15 +372,84 @@ cfg_prog (unsigned line, char *kw, char *val)
else
val = 0;
- register_prog (prog, val);
+ register_jabber_process (prog, val);
}
-struct kw_handler
-{
- char *kw;
- cfg_fun handler;
+struct exec_rec {
+ char *tag;
+ char *command;
+ int facility;
+ int retr[2];
};
+static void
+cfg_exec_command (struct cfg_file *file, char *kw, char *val, void *data)
+{
+ struct exec_rec *prec = data;
+ prec->command = strdup (val);
+}
+
+void
+cfg_exec_facility (struct cfg_file *file, char *kw, char *val, void *data)
+{
+ struct exec_rec *prec = data;
+ if (str_to_facility (val, &prec->facility))
+ logmsg (LOG_ERR, "%s:%u: Unknown facility `%s'",
+ config_file, file->line, val);
+}
+
+void
+cfg_exec_stdout (struct cfg_file *file, char *kw, char *val, void *data)
+{
+ struct exec_rec *prec = data;
+ if (str_to_priority (val, &prec->retr[RETR_OUT]))
+ logmsg (LOG_ERR, "%s:%u: Unknown priority `%s'",
+ config_file, file->line, val);
+}
+
+void
+cfg_exec_stderr (struct cfg_file *file, char *kw, char *val, void *data)
+{
+ struct exec_rec *prec = data;
+ if (str_to_priority (val, &prec->retr[RETR_ERR]))
+ logmsg (LOG_ERR, "%s:%u: Unknown priority `%s'",
+ config_file, file->line, val);
+}
+
+void
+cfg_exec (struct cfg_file *file, char *kw, char *val, void *unused)
+{
+ int rc;
+ int argc;
+ char **argv;
+
+ struct exec_rec rec;
+ static struct kw_handler kwtab[] = {
+ { "command", cfg_exec_command },
+ { "stdout", cfg_exec_stdout },
+ { "stderr", cfg_exec_stderr },
+ { "facility", cfg_exec_facility },
+ { NULL }
+ };
+ memset (&rec, 0, sizeof rec);
+ rec.retr[RETR_OUT] = rec.retr[RETR_ERR] = -1;
+ if (val)
+ rec.tag = strdup (val);
+
+ parse_block (file, &rec, kwtab, "end");
+
+ if (rc = argcv_get (rec.command, NULL, NULL, &argc, &argv))
+ {
+ logmsg (LOG_ERR, "%s:%u: cannot split command line: %s",
+ config_file, file->line, strerror (rc));
+ return;
+ }
+ register_prog (rec.tag, argv, rec.retr);
+ free (rec.tag);
+ free (rec.command);
+ argcv_free (argc, argv);
+}
+
struct kw_handler kw_handler[] = {
{ "syslog-tag", cfg_syslog_tag },
{ "syslog-facility", cfg_syslog_facility },
@@ -267,82 +457,31 @@ struct kw_handler kw_handler[] = {
{ "group", cfg_group },
{ "pidfile", cfg_pidfile },
{ "prog", cfg_prog },
+ { "exec", cfg_exec },
{ NULL }
};
-cfg_fun
-find_cfg_fun (char *kw)
-{
- struct kw_handler *p;
- for (p = kw_handler; p->kw; p++)
- if (strcmp (p->kw, kw) == 0)
- return p->handler;
- return NULL;
-}
-
void
parse_config ()
{
- FILE *fp = fopen (config_file, "r");
- char *buf = NULL;
- size_t size = 0;
- unsigned line = 0;
+ struct cfg_file file;
- if (!fp)
+ file.fp = fopen (config_file, "r");
+ file.buf = NULL;
+ file.size = 0;
+ file.line = 0;
+
+ if (!file.fp)
{
logmsg (LOG_EMERG, "cannot open config file `%s': %s",
config_file, strerror (errno));
exit (1);
}
- while (getline (&buf, &size, fp) > 0)
- {
- size_t len;
- char *p, *kw, *val = NULL;
- cfg_fun fun;
-
- line++;
- for (p = buf; *p && isspace (*p); p++)
- ;
- if (*p == '#' || *p == 0)
- continue;
-
- len = strlen (p);
- if (p[len-1] == '\n')
- p[--len] = 0;
-
- for (;len > 0 && isspace (p[len-1]); len--)
- ;
+ parse_block (&file, NULL, kw_handler, NULL);
- if (len > 0)
- p[len] = 0;
- else
- continue;
-
- kw = p;
- for (; *p && !isspace (*p); p++)
- ;
-
- if (*p)
- {
- *p++ = 0;
- for (; *p && isspace (*p); p++)
- ;
-
- val = p;
- }
-
- fun = find_cfg_fun (kw);
- if (fun)
- fun(line, kw, val);
- else
- {
- logmsg(LOG_WARNING, "%s:%u: legacy line", config_file, line);
- register_prog (kw, val);
- }
- }
- free (buf);
- fclose (fp);
+ free (file.buf);
+ fclose (file.fp);
}
@@ -574,6 +713,12 @@ signal_setup (RETSIGTYPE (*sf)(int))
signal (SIGALRM, sf);
}
+void
+syslog_setup ()
+{
+ log_printer = syslog_printer;
+}
+
int
main(int argc, char **argv)
@@ -625,7 +770,7 @@ main(int argc, char **argv)
}
parse_config();
-
+
if (!log_to_stderr)
{
openlog (syslog_tag, LOG_PID, log_facility);

Return to:

Send suggestions and report system problems to the System administrator.