opts.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #define _GNU_SOURCE
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <syslog.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <fcntl.h>
  13. #include <getopt.h>
  14. #include <time.h>
  15. #include <faux/faux.h>
  16. #include <faux/str.h>
  17. #include <faux/ini.h>
  18. #include <faux/log.h>
  19. #include <faux/conv.h>
  20. #include <klish/ktp_session.h>
  21. #include "private.h"
  22. /** @brief Initialize option structure by defaults
  23. */
  24. struct options *opts_init(void)
  25. {
  26. struct options *opts = NULL;
  27. opts = faux_zmalloc(sizeof(*opts));
  28. assert(opts);
  29. // Initialize
  30. opts->pidfile = faux_str_dup(DEFAULT_PIDFILE);
  31. opts->cfgfile = faux_str_dup(DEFAULT_CFGFILE);
  32. opts->unix_socket_path = faux_str_dup(KLISH_DEFAULT_UNIX_SOCKET_PATH);
  33. opts->cfgfile_userdefined = BOOL_FALSE;
  34. opts->foreground = BOOL_FALSE; // Daemonize by default
  35. opts->verbose = BOOL_FALSE;
  36. opts->log_facility = LOG_DAEMON;
  37. return opts;
  38. }
  39. /** @brief Free options structure
  40. */
  41. void opts_free(struct options *opts)
  42. {
  43. faux_str_free(opts->pidfile);
  44. faux_str_free(opts->cfgfile);
  45. faux_str_free(opts->unix_socket_path);
  46. faux_free(opts);
  47. }
  48. /** @brief Parse command line options
  49. */
  50. int opts_parse(int argc, char *argv[], struct options *opts)
  51. {
  52. static const char *shortopts = "hp:c:fl:v";
  53. static const struct option longopts[] = {
  54. {"help", 0, NULL, 'h'},
  55. {"pid", 1, NULL, 'p'},
  56. {"conf", 1, NULL, 'c'},
  57. {"foreground", 0, NULL, 'f'},
  58. {"verbose", 0, NULL, 'v'},
  59. {"facility", 1, NULL, 'l'},
  60. {NULL, 0, NULL, 0}
  61. };
  62. optind = 1;
  63. while(1) {
  64. int opt = 0;
  65. opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  66. if (-1 == opt)
  67. break;
  68. switch (opt) {
  69. case 'p':
  70. faux_str_free(opts->pidfile);
  71. opts->pidfile = faux_str_dup(optarg);
  72. break;
  73. case 'c':
  74. faux_str_free(opts->cfgfile);
  75. opts->cfgfile = faux_str_dup(optarg);
  76. opts->cfgfile_userdefined = BOOL_TRUE;
  77. break;
  78. case 'f':
  79. opts->foreground = BOOL_TRUE;
  80. break;
  81. case 'v':
  82. opts->verbose = BOOL_TRUE;
  83. break;
  84. case 'l':
  85. if (faux_log_facility_id(optarg, &(opts->log_facility))) {
  86. fprintf(stderr, "Error: Illegal syslog facility %s.\n", optarg);
  87. _exit(-1);
  88. }
  89. break;
  90. case 'h':
  91. help(0, argv[0]);
  92. _exit(0);
  93. break;
  94. default:
  95. help(-1, argv[0]);
  96. _exit(-1);
  97. break;
  98. }
  99. }
  100. return 0;
  101. }
  102. /** @brief Print help message
  103. */
  104. void help(int status, const char *argv0)
  105. {
  106. const char *name = NULL;
  107. if (!argv0)
  108. return;
  109. // Find the basename
  110. name = strrchr(argv0, '/');
  111. if (name)
  112. name++;
  113. else
  114. name = argv0;
  115. if (status != 0) {
  116. fprintf(stderr, "Try `%s -h' for more information.\n",
  117. name);
  118. } else {
  119. printf("Version : %s\n", VERSION);
  120. printf("Usage : %s [options]\n", name);
  121. printf("Klish daemon\n");
  122. printf("Options :\n");
  123. printf("\t-h, --help Print this help.\n");
  124. printf("\t-f, --foreground Don't daemonize.\n");
  125. printf("\t-v, --verbose Be verbose.\n");
  126. printf("\t-p <path>, --pid=<path> File to save daemon's PID to ("
  127. DEFAULT_PIDFILE ").\n");
  128. printf("\t-c <path>, --conf=<path> Config file ("
  129. DEFAULT_CFGFILE ").\n");
  130. printf("\t-l, --facility Syslog facility (DAEMON).\n");
  131. }
  132. }
  133. /** @brief Parse config file
  134. */
  135. int config_parse(const char *cfgfile, struct options *opts)
  136. {
  137. faux_ini_t *ini = NULL;
  138. const char *tmp = NULL;
  139. ini = faux_ini_new();
  140. assert(ini);
  141. if (!ini)
  142. return -1;
  143. if (faux_ini_parse_file(ini, cfgfile)) {
  144. syslog(LOG_ERR, "Can't parse config file: %s\n", cfgfile);
  145. faux_ini_free(ini);
  146. return -1;
  147. }
  148. if ((tmp = faux_ini_find(ini, "UnixSocketPath"))) {
  149. faux_str_free(opts->unix_socket_path);
  150. opts->unix_socket_path = faux_str_dup(tmp);
  151. }
  152. faux_ini_free(ini);
  153. return 0;
  154. }
  155. /** @brief Show options. For debug purposes.
  156. */
  157. int opts_show(struct options *opts)
  158. {
  159. assert(opts);
  160. if (!opts)
  161. return -1;
  162. syslog(LOG_DEBUG, "opts: Foreground = %s\n", opts->foreground ? "true" : "false");
  163. syslog(LOG_DEBUG, "opts: Verbose = %s\n", opts->verbose ? "true" : "false");
  164. syslog(LOG_DEBUG, "opts: LogFacility = %s\n", faux_log_facility_str(opts->log_facility));
  165. syslog(LOG_DEBUG, "opts: PIDPath = %s\n", opts->pidfile);
  166. syslog(LOG_DEBUG, "opts: ConfigPath = %s\n", opts->cfgfile);
  167. syslog(LOG_DEBUG, "opts: UnixSocketPath = %s\n", opts->unix_socket_path);
  168. return 0;
  169. }