From 0334d1bf754bf285668cdbc4243a972495f25dd7 Mon Sep 17 00:00:00 2001 From: octo Date: Sun, 8 Jan 2006 08:22:46 +0000 Subject: [PATCH] Moved `exit_usage' from `collectd.c' to `configfile.c' and renamed it to `cf_callback_usage'. Removed the `getopt' code. Argument parsing is now done by `libconfig' as well. Fixed a typo in `collectd.c' which prevented collectd from catching a SIGINT.. --- src/collectd.c | 149 +++++++---------------------------------------- src/configfile.c | 72 ++++++++++++++++++++--- src/configfile.h | 9 ++- 3 files changed, 92 insertions(+), 138 deletions(-) diff --git a/src/collectd.c b/src/collectd.c index ad0b6fbd..71c11677 100644 --- a/src/collectd.c +++ b/src/collectd.c @@ -122,45 +122,6 @@ static void update_kstat (void) } /* static void update_kstat (void) */ #endif /* HAVE_LIBKSTAT */ -static void exit_usage (char *name) -{ - printf ("Usage: "PACKAGE" [OPTIONS]\n\n" - - "Available options:\n" - " General:\n" - " -C Configuration file.\n" - " Default: "CONFIGFILE"\n" -#if COLLECT_DAEMON - " -P PID file.\n" - " Default: "PIDFILE"\n" -#endif - " -M Module/Plugin directory.\n" - " Default: "PLUGINDIR"\n" - " -D Data storage directory.\n" - " Default: "PKGLOCALSTATEDIR"\n" -#if COLLECT_DEBUG - " -L Log file.\n" - " Default: "LOGFILE"\n" -#endif -#if COLLECT_DAEMON - " -f Don't fork to the background.\n" -#endif -#if HAVE_LIBRRD - " -l Start in local mode (no network).\n" - " -c Start in client (sender) mode.\n" - " -s Start in server (listener) mode.\n" -#endif /* HAVE_LIBRRD */ -#if COLLECT_PING - " Ping:\n" - " -p Host to ping periodically, may be repeated to ping\n" - " more than one host.\n" -#endif /* COLLECT_PING */ - "\n"PACKAGE" "VERSION", http://verplant.org/collectd/\n" - "by Florian octo Forster \n" - "for contributions see `AUTHORS'\n"); - exit (0); -} /* static void exit_usage (char *name) */ - static int start_client (void) { int sleepingtime; @@ -267,9 +228,7 @@ int main (int argc, char **argv) #endif struct sigaction sigIntAction; struct sigaction sigTermAction; - char *configfile = CONFIGFILE; - char *plugindir = NULL; - char *datadir = PKGLOCALSTATEDIR; + char *datadir; #if COLLECT_DAEMON char *pidfile = PIDFILE; pid_t pid; @@ -286,94 +245,15 @@ int main (int argc, char **argv) /* open syslog */ openlog (PACKAGE, LOG_CONS | LOG_PID, LOG_DAEMON); - /* read options */ - while (1) - { - int c; - - c = getopt (argc, argv, "C:M:D:h" -#if COLLECT_DAEMON - "fP:" -#endif -#if COLLECT_DEBUG - "L:" -#endif -#if HAVE_LIBRRD - "csl" -#endif /* HAVE_LIBRRD */ -#if COLLECT_PING - "p:" -#endif /* COLLECT_PING */ - ); - - if (c == -1) - break; - - switch (c) - { -#if HAVE_LIBRRD - case 'c': - operating_mode = MODE_CLIENT; - break; - - case 's': - operating_mode = MODE_SERVER; - break; - - case 'l': - operating_mode = MODE_LOCAL; - break; -#endif /* HAVE_LIBRRD */ - case 'C': - configfile = optarg; - break; -#if COLLECT_DAEMON - case 'P': - pidfile = optarg; - break; - case 'f': - daemonize = 0; - break; -#endif /* COLLECT_DAEMON */ - case 'M': - plugindir = optarg; - break; - case 'D': - datadir = optarg; - break; -#if COLLECT_DEBUG - case 'L': - logfile = optarg; - break; -#endif -#if COLLECT_PING - case 'p': - if (num_pinghosts < MAX_PINGHOSTS) - pinghosts[num_pinghosts++] = optarg; - else - fprintf (stderr, "Maximum of %i ping hosts reached.\n", MAX_PINGHOSTS); - break; -#endif /* COLLECT_PING */ - case 'h': - default: - exit_usage (argv[0]); - } /* switch (c) */ - } /* while (1) */ - - DBG_STARTFILE(logfile, "debug file opened."); - - /* FIXME this is the wrong place to call this function, because - * `cf_read' is called below. We'll need an extra callback for this. - * Right now though I'm to tired to do this. G'night. -octo */ - if ((plugindir == NULL) && ((plugindir = cf_get_mode_option ("PluginDir")) == NULL)) - plugindir = PLUGINDIR; + DBG_STARTFILE(logfile, "Debug file opened."); /* - * Read the config file. This will load any modules automagically. + * Read options from the config file, the environment and the command + * line (in that order, with later options overwriting previous ones in + * general). + * Also, this will automatically load modules. */ - plugin_set_dir (plugindir); - - if (cf_read (configfile)) + if (cf_read (argc, argv, CONFIGFILE)) { fprintf (stderr, "Error: Reading the config file failed!\n" "Read the syslog for details.\n"); @@ -384,19 +264,30 @@ int main (int argc, char **argv) * Change directory. We do this _after_ reading the config and loading * modules to relative paths work as expected. */ + if ((datadir = cf_get_mode_option ("DataDir")) == NULL) + { + fprintf (stderr, "Don't have a datadir to use. This should not happen. Ever."); + return (1); + } if (change_basedir (datadir)) { fprintf (stderr, "Error: Unable to change to directory `%s'.\n", datadir); return (1); } +#if COLLECT_DAEMON /* * fork off child */ -#if COLLECT_DAEMON sigChldAction.sa_handler = SIG_IGN; sigaction (SIGCHLD, &sigChldAction, NULL); + if ((pidfile = cf_get_mode_option ("PIDFile")) == NULL) + { + fprintf (stderr, "Cannot obtain pidfile. This shoud not happen. Ever."); + return (1); + } + if (daemonize) { if ((pid = fork ()) == -1) @@ -448,7 +339,7 @@ int main (int argc, char **argv) sigIntAction.sa_handler = sigIntHandler; sigaction (SIGINT, &sigIntAction, NULL); - sigIntAction.sa_handler = sigTermHandler; + sigTermAction.sa_handler = sigTermHandler; sigaction (SIGTERM, &sigTermAction, NULL); /* diff --git a/src/configfile.c b/src/configfile.c index 76e54217..9b1b83a1 100644 --- a/src/configfile.c +++ b/src/configfile.c @@ -61,10 +61,10 @@ typedef struct cf_mode_item static cf_mode_item_t cf_mode_list[] = { - {"Server", NULL, MODE_CLIENT }, - {"Port", NULL, MODE_CLIENT | MODE_SERVER }, - {"PIDFile", NULL, MODE_CLIENT | MODE_SERVER | MODE_LOCAL}, - {"DataDir", NULL, MODE_SERVER | MODE_LOCAL} + {"Server", NULL, MODE_CLIENT }, + {"Port", NULL, MODE_CLIENT | MODE_SERVER }, + {"PIDFile", PIDFILE, MODE_CLIENT | MODE_SERVER | MODE_LOCAL}, + {"DataDir", PKGLOCALSTATEDIR, MODE_SERVER | MODE_LOCAL} }; static int cf_mode_num = 4; @@ -101,6 +101,8 @@ int cf_dispatch (char *type, const char *orig_key, const char *orig_value) int ret; int i; + DBG ("type = %s, key = %s, value = %s", type, orig_key, orig_value); + if ((cf_cb = cf_search (type)) == NULL) { syslog (LOG_WARNING, "Plugin `%s' did not register a callback.\n", type); @@ -214,6 +216,47 @@ char *cf_get_mode_option (const char *key) return (NULL); } +int cf_callback_usage (const char *shortvar, const char *var, + const char *arguments, const char *value, lc_flags_t flags, + void *extra) +{ + DBG ("shortvar = %s, var = %s, arguments = %s, value = %s, ...", + shortvar, var, arguments, value); + + printf ("Usage: "PACKAGE" [OPTIONS]\n\n" + + "Available options:\n" +#if COLLECT_DAEMON + " -P PID file.\n" + " Default: "PIDFILE"\n" +#endif + " -M Module/Plugin directory.\n" + " Default: "PLUGINDIR"\n" + " -D Data storage directory.\n" + " Default: "PKGLOCALSTATEDIR"\n" +#if COLLECT_DEBUG + " -L Log file.\n" + " Default: "LOGFILE"\n" +#endif +#if COLLECT_DAEMON + " -f Don't fork to the background.\n" +#endif +#if HAVE_LIBRRD + " -l Start in local mode (no network).\n" + " -c Start in client (sender) mode.\n" + " -s Start in server (listener) mode.\n" +#endif /* HAVE_LIBRRD */ +#if COLLECT_PING + " Ping:\n" + " -p Host to ping periodically, may be repeated to ping\n" + " more than one host.\n" +#endif /* COLLECT_PING */ + "\n"PACKAGE" "VERSION", http://verplant.org/collectd/\n" + "by Florian octo Forster \n" + "for contributions see `AUTHORS'\n"); + exit (0); +} /* exit_usage */ + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Functions for the actual parsing * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -482,12 +525,17 @@ int cf_callback_plugin_dispatch (const char *shortvar, const char *var, return (LC_CBRET_OKAY); } -int cf_read (char *filename) +void cf_init (void) { + static int run_once = 0; int i; - if (filename == NULL) - filename = CONFIGFILE; + if (run_once != 0) + return; + run_once = 1; + + lc_register_callback ("Help", 'h', LC_VAR_NONE, + cf_callback_usage, NULL); lc_register_callback ("Client", 'c', LC_VAR_NONE, cf_callback_mode_switch, NULL); @@ -519,8 +567,16 @@ int cf_read (char *filename) lc_register_callback (longvar, SHORTOPT_NONE, LC_VAR_STRING, cf_callback_mode_option, (void *) item); } +} + +int cf_read (int argc, char **argv, char *filename) +{ + cf_init (); + + if (filename == NULL) + filename = CONFIGFILE; - if (lc_process_file ("collectd", filename, LC_CONF_APACHE)) + if (lc_process (argc, argv, "collectd", LC_CONF_APACHE, filename)) { syslog (LOG_ERR, "lc_process_file (%s): %s", filename, lc_geterrstr ()); return (-1); diff --git a/src/configfile.h b/src/configfile.h index 4f82eef1..7d89fadb 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -81,10 +81,17 @@ char *cf_get_mode_option (const char *key); * information to functions/variables. Most important: Is calls `plugin_load' * to load specific plugins, depending on the current mode of operation. * + * PARAMETERS + * `argc' Same as `argc' passed to `main' + * `argv' Same as `argv' passed to `main' + * `filename' An additional filename to look for. This function calls + * `lc_process' which already searches many standard locations.. + * If set to NULL will use the `CONFIGFILE' define. + * * RETURN VALUE * Returns zero upon success and non-zero otherwise. A error-message will have * been printed in this case. */ -int cf_read (char *filename); +int cf_read (int argc, char **argv, char *filename); #endif /* defined(CONFIGFILE_H) */ -- 2.30.2