konf.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * konf.c
  3. *
  4. * The client to communicate to konfd configuration daemon.
  5. */
  6. #ifdef HAVE_CONFIG_H
  7. #include "config.h"
  8. #endif /* HAVE_CONFIG_H */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <string.h>
  13. #include <signal.h>
  14. #if WITH_INTERNAL_GETOPT
  15. #include "libc/getopt.h"
  16. #else
  17. #ifdef HAVE_GETOPT_H
  18. #include <getopt.h>
  19. #endif
  20. #endif
  21. #include "konf/net.h"
  22. #include "konf/query.h"
  23. #include "konf/buf.h"
  24. #include "lub/string.h"
  25. #ifndef VERSION
  26. #define VERSION 1.2.2
  27. #endif
  28. #define QUOTE(t) #t
  29. #define version(v) printf("%s\n", v)
  30. static void help(int status, const char *argv0);
  31. static const char *escape_chars = "\"\\'";
  32. /*--------------------------------------------------------- */
  33. int main(int argc, char **argv)
  34. {
  35. int res = -1;
  36. konf_client_t *client = NULL;
  37. konf_buf_t *buf = NULL;
  38. char *line = NULL;
  39. char *str = NULL;
  40. const char *socket_path = KONFD_SOCKET_PATH;
  41. int i = 0;
  42. /* Signal vars */
  43. struct sigaction sigpipe_act;
  44. sigset_t sigpipe_set;
  45. static const char *shortopts = "hvs:";
  46. #ifdef HAVE_GETOPT_LONG
  47. static const struct option longopts[] = {
  48. {"help", 0, NULL, 'h'},
  49. {"version", 0, NULL, 'v'},
  50. {"socket", 1, NULL, 's'},
  51. {NULL, 0, NULL, 0}
  52. };
  53. #endif
  54. /* Ignore SIGPIPE */
  55. sigemptyset(&sigpipe_set);
  56. sigaddset(&sigpipe_set, SIGPIPE);
  57. sigpipe_act.sa_flags = 0;
  58. sigpipe_act.sa_mask = sigpipe_set;
  59. sigpipe_act.sa_handler = SIG_IGN;
  60. sigaction(SIGPIPE, &sigpipe_act, NULL);
  61. /* Parse command line options */
  62. while(1) {
  63. int opt;
  64. #ifdef HAVE_GETOPT_LONG
  65. opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  66. #else
  67. opt = getopt(argc, argv, shortopts);
  68. #endif
  69. if (-1 == opt)
  70. break;
  71. switch (opt) {
  72. case 's':
  73. socket_path = optarg;
  74. break;
  75. case 'h':
  76. help(0, argv[0]);
  77. exit(0);
  78. break;
  79. case 'v':
  80. version(VERSION);
  81. exit(0);
  82. break;
  83. default:
  84. help(-1, argv[0]);
  85. exit(-1);
  86. break;
  87. }
  88. }
  89. /* Get request line from the args */
  90. for (i = optind; i < argc; i++) {
  91. char *space = NULL;
  92. if (NULL != line)
  93. lub_string_cat(&line, " ");
  94. space = strchr(argv[i], ' ');
  95. if (space)
  96. lub_string_cat(&line, "\"");
  97. str = lub_string_encode(argv[i], escape_chars);
  98. lub_string_cat(&line, str);
  99. lub_string_free(str);
  100. if (space)
  101. lub_string_cat(&line, "\"");
  102. }
  103. if (!line) {
  104. help(-1, argv[0]);
  105. goto err;
  106. }
  107. #ifdef DEBUG
  108. fprintf(stderr, "REQUEST: %s\n", line);
  109. #endif
  110. if (!(client = konf_client_new(socket_path))) {
  111. fprintf(stderr, "Error: Can't create internal data structures.\n");
  112. goto err;
  113. }
  114. if (konf_client_connect(client) < 0) {
  115. fprintf(stderr, "Error: Can't connect to %s socket.\n", socket_path);
  116. goto err;
  117. }
  118. if (konf_client_send(client, line) < 0) {
  119. fprintf(stderr, "Error: Can't send request to %s socket.\n", socket_path);
  120. goto err;
  121. }
  122. if (konf_client_recv_answer(client, &buf) < 0) {
  123. fprintf(stderr, "Error: The error code from the konfd daemon.\n");
  124. goto err;
  125. }
  126. if (buf) {
  127. konf_buf_lseek(buf, 0);
  128. while ((str = konf_buf_preparse(buf))) {
  129. if (strlen(str) == 0) {
  130. lub_string_free(str);
  131. break;
  132. }
  133. fprintf(stdout, "%s\n", str);
  134. lub_string_free(str);
  135. }
  136. konf_buf_delete(buf);
  137. }
  138. res = 0;
  139. err:
  140. lub_string_free(line);
  141. konf_client_free(client);
  142. return res;
  143. }
  144. /*--------------------------------------------------------- */
  145. /* Print help message */
  146. static void help(int status, const char *argv0)
  147. {
  148. const char *name = NULL;
  149. if (!argv0)
  150. return;
  151. /* Find the basename */
  152. name = strrchr(argv0, '/');
  153. if (name)
  154. name++;
  155. else
  156. name = argv0;
  157. if (status != 0) {
  158. fprintf(stderr, "Try `%s -h' for more information.\n",
  159. name);
  160. } else {
  161. printf("Usage: %s [options] -- <command for konfd daemon>\n", name);
  162. printf("Utility for communication to the konfd "
  163. "configuration daemon.\n");
  164. printf("Options:\n");
  165. printf("\t-v, --version\tPrint utility version.\n");
  166. printf("\t-h, --help\tPrint this help.\n");
  167. printf("\t-s <path>, --socket=<path>\tSpecify listen socket "
  168. "of the konfd daemon.\n");
  169. }
  170. }