diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-06-02 18:45:53 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-06-02 18:45:53 +0000 |
commit | 2c26c67fae94e783d5cc5ee634273b639aa405e5 (patch) | |
tree | 2a06b7393fa97e5ce6a4b5e166ae412de063f1ad /jabberd/main.c | |
parent | 2a37423d019dbfdfd8c11072dd6abe624aa5c286 (diff) | |
download | gsc-2c26c67fae94e783d5cc5ee634273b639aa405e5.tar.gz gsc-2c26c67fae94e783d5cc5ee634273b639aa405e5.tar.bz2 |
Update
git-svn-id: file:///svnroot/gsc/trunk@250 d2de0444-eb31-0410-8365-af798a554d48
Diffstat (limited to 'jabberd/main.c')
-rw-r--r-- | jabberd/main.c | 341 |
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 @@ -142,64 +142,185 @@ usage () printf (" -v display program version\n"); printf ("\n"); printf ("Report bugs to <%s>\n", PACKAGE_BUGREPORT); } -/* 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 }, { "LOCAL0", LOG_LOCAL0 }, { "LOCAL1", LOG_LOCAL1 }, { "LOCAL2", LOG_LOCAL2 }, { "LOCAL3", LOG_LOCAL3 }, { "LOCAL4", LOG_LOCAL4 }, { "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); } struct group_list { @@ -207,35 +328,35 @@ struct group_list gid_t gid; }; 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) { struct group_list *p = emalloc (sizeof *p); p->gid = group->gr_gid; p->next = group_list; group_list = p; } 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; for (; *p && !isspace (*p); p++) ; @@ -248,104 +369,122 @@ cfg_prog (unsigned line, char *kw, char *val) val = p; } 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 }, { "user", cfg_user }, { "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); } void pidfile_write () { @@ -571,12 +710,18 @@ signal_setup (RETSIGTYPE (*sf)(int)) signal (SIGQUIT, sf); signal (SIGINT, sf); signal (SIGHUP, sf); signal (SIGALRM, sf); } +void +syslog_setup () +{ + log_printer = syslog_printer; +} + int main(int argc, char **argv) { int c; @@ -622,13 +767,13 @@ main(int argc, char **argv) { logmsg (LOG_CRIT, "extra command line arguments"); exit (1); } parse_config(); - + if (!log_to_stderr) { openlog (syslog_tag, LOG_PID, log_facility); log_printer = syslog_printer; } |