Implemented '--syslog' and '--syslog-facility'.
[captive.git] / src / libcaptive / client / options.c
index da06bb0..0d92b91 100644 (file)
 #include "captive/macros.h"
 #include <glib/gstrfuncs.h>
 #include <stdlib.h>
+#include <syslog.h>
+
+
+/* Config: */
+#define DEFAULT_SYSLOG_FACILITY LOG_DAEMON
 
 
 void captive_options_init(struct captive_options *options)
@@ -37,6 +42,7 @@ void captive_options_init(struct captive_options *options)
        options->debug_messages=FALSE;
        options->load_module=NULL;
        options->sandbox=FALSE;
+       options->syslog_facility=-1;
 }
 
 
@@ -203,6 +209,104 @@ static void arg_bug_pathname(void)
        captive_options->bug_pathname=g_strdup(captive_popt_optarg);
 }
 
+/* Do not: #define SYSLOG_NAMES 1
+ * to enable <syslog.h>/facilitynames[] as such array is global (non-static)
+ * and it is likely it would conflict with facilitynames[] defined elsewhere
+ * (such as even conflicts by libcaptive.so).
+ */
+static const struct syslog_facility {
+       const gchar *name;
+       int value;
+       } syslog_facility[]={
+#ifdef LOG_AUTHPRIV
+               { "authpriv", LOG_AUTHPRIV },
+#endif
+#ifdef LOG_CRON
+               { "cron"    , LOG_CRON },
+#endif
+#ifdef LOG_DAEMON
+               { "daemon"  , LOG_DAEMON },
+#endif
+#ifdef LOG_FTP
+               { "ftp"     , LOG_FTP },
+#endif
+#ifdef LOG_KERN
+               { "kern"    , LOG_KERN },
+#endif
+#ifdef LOG_LPR
+               { "lpr"     , LOG_LPR },
+#endif
+#ifdef LOG_MAIL
+               { "mail"    , LOG_MAIL },
+#endif
+#ifdef LOG_NEWS
+               { "news"    , LOG_NEWS },
+#endif
+#ifdef LOG_SYSLOG
+               { "syslog"  , LOG_SYSLOG },
+#endif
+#ifdef LOG_USER
+               { "user"    , LOG_USER },
+#endif
+#ifdef LOG_UUCP
+               { "uucp"    , LOG_UUCP },
+#endif
+#ifdef LOG_LOCAL0
+               { "local0"  , LOG_LOCAL0 },
+#endif
+#ifdef LOG_LOCAL1
+               { "local1"  , LOG_LOCAL1 },
+#endif
+#ifdef LOG_LOCAL2
+               { "local2"  , LOG_LOCAL2 },
+#endif
+#ifdef LOG_LOCAL3
+               { "local3"  , LOG_LOCAL3 },
+#endif
+#ifdef LOG_LOCAL4
+               { "local4"  , LOG_LOCAL4 },
+#endif
+#ifdef LOG_LOCAL5
+               { "local5"  , LOG_LOCAL5 },
+#endif
+#ifdef LOG_LOCAL6
+               { "local6"  , LOG_LOCAL6 },
+#endif
+#ifdef LOG_LOCAL7
+               { "local7"  , LOG_LOCAL7 },
+#endif
+       };
+
+static void arg_syslog(void)
+{
+       captive_options->syslog_facility=DEFAULT_SYSLOG_FACILITY;
+}
+
+static int arg_syslog_facility_value;
+
+static void arg_syslog_facility(void)
+{
+const struct syslog_facility *facility;
+GString *gstring;
+gchar *gs;
+
+       for (facility=syslog_facility;facility<syslog_facility+G_N_ELEMENTS(syslog_facility);facility++)
+               if (!strcmp(captive_popt_optarg,facility->name)) {
+                       arg_syslog_facility_value=facility->value;
+                       return;
+                       }
+
+       gstring=g_string_new(captive_printf_alloca(_("Unknown '--syslog' facility '%s'; known:"),captive_popt_optarg));
+       for (facility=syslog_facility;facility<syslog_facility+G_N_ELEMENTS(syslog_facility);facility++) {
+               gstring=g_string_append_c(gstring,' ');
+               gstring=g_string_append(gstring,facility->name);
+               }
+       gs=g_string_free(gstring,
+                       FALSE); /* free_segment */
+       g_warning(gs);
+       g_free(gs);
+}
+
 
 static void captive_popt_callback
                (poptContext con,enum poptCallbackReason reason,const struct poptOption *opt,const char *arg,const void *data);
@@ -238,6 +342,11 @@ const struct poptOption captive_popt[]={
                CAPTIVE_POPT_STRING("sandbox-server-ior",N_("CORBA IOR of 'captive-sandbox-server', turns on sandboxing"),N_("IOR")),
                CAPTIVE_POPT_NONE(  "no-sandbox"        ,N_("Turn off sandboxing feature")),
                CAPTIVE_POPT_STRING("bug-pathname"      ,N_("Pathname to strftime(3) for .captivebug.xml.gz bugreports"),N_("pathname")),
+               /* Do not: POPT_ARGFLAG_OPTIONAL
+                * as it always eats one argument unless it is at end of argv[].
+                */
+               CAPTIVE_POPT_NONE(  "syslog"            ,N_("Messages sent to syslog(3) instead of stderr")),
+               CAPTIVE_POPT_STRING("syslog-facility"   ,N_("openlog(3) facility for --syslog"),N_("facility")),
 
 #undef CAPTIVE_POPT_NONE
 #undef CAPTIVE_POPT_STRING
@@ -265,6 +374,8 @@ static void (*const popt_func_table[])(void)={
                arg_sandbox_server_ior,
                arg_no_sandbox,
                arg_bug_pathname,
+               arg_syslog,
+               arg_syslog_facility,
                };
 
 
@@ -282,7 +393,7 @@ gint funci;
        if (popt_func_table[funci])
                (*popt_func_table[funci])();
        free(captive_popt_optarg);
-       captive_popt_optarg=NULL;       /* sanity, shouldn't be needed */
+       captive_popt_optarg=NULL;       /* sanity */
 }
 
 
@@ -300,6 +411,8 @@ gboolean r=FALSE;
        g_assert(captive_options==NULL);
        captive_options=options;
 
+       captive_popt_optarg=NULL;       /* sanity */
+       arg_syslog_facility_value=-1;
        errint=poptParseArgvString(captive_args,&captive_args_argc,&captive_args_argv);
        if (errint!=0) {
                g_assert_not_reached(); /* argument parsing args_error */
@@ -341,6 +454,9 @@ args_err:
                g_return_val_if_reached(r);
                }
 
+       if (captive_options->syslog_facility!=-1)
+               captive_options->syslog_facility=arg_syslog_facility_value;
+
        g_assert(captive_options!=NULL);
        captive_options=NULL;