konf.c 3.8 KB

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