123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #define _GNU_SOURCE
- #include <stdlib.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include <syslog.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <getopt.h>
- #include <time.h>
- #include <faux/faux.h>
- #include <faux/str.h>
- #include <faux/ini.h>
- #include <faux/log.h>
- #include <faux/conv.h>
- #include <klish/ktp_session.h>
- #include "private.h"
- /** @brief Initialize option structure by defaults
- */
- struct options *opts_init(void)
- {
- struct options *opts = NULL;
- opts = faux_zmalloc(sizeof(*opts));
- assert(opts);
- // Initialize
- opts->pidfile = faux_str_dup(DEFAULT_PIDFILE);
- opts->cfgfile = faux_str_dup(DEFAULT_CFGFILE);
- opts->unix_socket_path = faux_str_dup(KLISH_DEFAULT_UNIX_SOCKET_PATH);
- opts->cfgfile_userdefined = BOOL_FALSE;
- opts->foreground = BOOL_FALSE; // Daemonize by default
- opts->verbose = BOOL_FALSE;
- opts->log_facility = LOG_DAEMON;
- opts->dbs = faux_str_dup(DEFAULT_DBS);
- return opts;
- }
- /** @brief Free options structure
- */
- void opts_free(struct options *opts)
- {
- faux_str_free(opts->pidfile);
- faux_str_free(opts->cfgfile);
- faux_str_free(opts->unix_socket_path);
- faux_str_free(opts->dbs);
- faux_free(opts);
- }
- /** @brief Parse command line options
- */
- int opts_parse(int argc, char *argv[], struct options *opts)
- {
- static const char *shortopts = "hp:f:dl:v";
- static const struct option longopts[] = {
- {"help", 0, NULL, 'h'},
- {"pid", 1, NULL, 'p'},
- {"conf", 1, NULL, 'f'},
- {"foreground", 0, NULL, 'd'},
- {"verbose", 0, NULL, 'v'},
- {"facility", 1, NULL, 'l'},
- {NULL, 0, NULL, 0}
- };
- optind = 1;
- while(1) {
- int opt = 0;
- opt = getopt_long(argc, argv, shortopts, longopts, NULL);
- if (-1 == opt)
- break;
- switch (opt) {
- case 'p':
- faux_str_free(opts->pidfile);
- opts->pidfile = faux_str_dup(optarg);
- break;
- case 'f':
- faux_str_free(opts->cfgfile);
- opts->cfgfile = faux_str_dup(optarg);
- opts->cfgfile_userdefined = BOOL_TRUE;
- break;
- case 'd':
- opts->foreground = BOOL_TRUE;
- break;
- case 'v':
- opts->verbose = BOOL_TRUE;
- break;
- case 'l':
- if (faux_log_facility_id(optarg, &(opts->log_facility))) {
- fprintf(stderr, "Error: Illegal syslog facility %s.\n", optarg);
- _exit(-1);
- }
- break;
- case 'h':
- help(0, argv[0]);
- _exit(0);
- break;
- default:
- help(-1, argv[0]);
- _exit(-1);
- break;
- }
- }
- return 0;
- }
- /** @brief Print help message
- */
- void help(int status, const char *argv0)
- {
- const char *name = NULL;
- if (!argv0)
- return;
- // Find the basename
- name = strrchr(argv0, '/');
- if (name)
- name++;
- else
- name = argv0;
- if (status != 0) {
- fprintf(stderr, "Try `%s -h' for more information.\n",
- name);
- } else {
- printf("Version : %s\n", VERSION);
- printf("Usage : %s [options]\n", name);
- printf("Klish daemon\n");
- printf("Options :\n");
- printf("\t-h, --help Print this help.\n");
- printf("\t-d, --foreground Don't daemonize.\n");
- printf("\t-v, --verbose Be verbose.\n");
- printf("\t-p <path>, --pid=<path> File to save daemon's PID to ("
- DEFAULT_PIDFILE ").\n");
- printf("\t-f <path>, --conf=<path> Config file ("
- DEFAULT_CFGFILE ").\n");
- printf("\t-l, --facility Syslog facility (DAEMON).\n");
- }
- }
- /** @brief Parse config file
- *
- * It parses known options and put them to opts arg. But also it returns
- * parsed config file. The parts of config file can be unknown to klish
- * itself but can be known to third party plugins. For example DBs
- * subsystem get settings from config file.
- */
- faux_ini_t *config_parse(const char *cfgfile, struct options *opts)
- {
- faux_ini_t *ini = NULL;
- const char *tmp = NULL;
- ini = faux_ini_new();
- assert(ini);
- if (!ini)
- NULL;
- if (!faux_ini_parse_file(ini, cfgfile)) {
- syslog(LOG_ERR, "Can't parse config file: %s\n", cfgfile);
- faux_ini_free(ini);
- return NULL;
- }
- // UnixSocketPath
- if ((tmp = faux_ini_find(ini, "UnixSocketPath"))) {
- faux_str_free(opts->unix_socket_path);
- opts->unix_socket_path = faux_str_dup(tmp);
- }
- // DBs
- if ((tmp = faux_ini_find(ini, "DBs"))) {
- faux_str_free(opts->dbs);
- opts->dbs = faux_str_dup(tmp);
- }
- return ini;
- }
- /** @brief Show options. For debug purposes.
- */
- int opts_show(struct options *opts)
- {
- assert(opts);
- if (!opts)
- return -1;
- syslog(LOG_DEBUG, "opts: Foreground = %s\n", opts->foreground ? "true" : "false");
- syslog(LOG_DEBUG, "opts: Verbose = %s\n", opts->verbose ? "true" : "false");
- syslog(LOG_DEBUG, "opts: LogFacility = %s\n", faux_log_facility_str(opts->log_facility));
- syslog(LOG_DEBUG, "opts: PIDPath = %s\n", opts->pidfile);
- syslog(LOG_DEBUG, "opts: ConfigPath = %s\n", opts->cfgfile);
- syslog(LOG_DEBUG, "opts: UnixSocketPath = %s\n", opts->unix_socket_path);
- syslog(LOG_DEBUG, "opts: DBs = %s\n", opts->dbs);
- return 0;
- }
|