clish.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. //-------------------------------------
  2. // clish.cpp
  3. //
  4. // A simple client for libclish
  5. //-------------------------------------
  6. #ifdef HAVE_CONFIG_H
  7. #include "config.h"
  8. #endif /* HAVE_CONFIG_H */
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #ifdef HAVE_GETOPT_H
  14. #include <getopt.h>
  15. #endif
  16. #include <signal.h>
  17. #include "clish/shell.h"
  18. #include "clish/internal.h"
  19. #ifndef VERSION
  20. #define VERSION 1.2.2
  21. #endif
  22. #define QUOTE(t) #t
  23. /* #define version(v) printf("%s\n", QUOTE(v)) */
  24. #define version(v) printf("%s\n", v)
  25. /* Hooks */
  26. static clish_shell_hooks_t my_hooks = {
  27. NULL, /* don't worry about init callback */
  28. clish_access_callback,
  29. NULL, /* don't worry about cmd_line callback */
  30. clish_script_callback,
  31. NULL, /* don't worry about fini callback */
  32. clish_config_callback,
  33. NULL /* don't register any builtin functions */
  34. };
  35. static void help(int status, const char *argv0);
  36. /*--------------------------------------------------------- */
  37. int main(int argc, char **argv)
  38. {
  39. bool_t running;
  40. int result = -1;
  41. clish_shell_t * shell;
  42. /* Command line options */
  43. const char *socket_path = KONFD_SOCKET_PATH;
  44. bool_t lockless = BOOL_FALSE;
  45. bool_t stop_on_error = BOOL_FALSE;
  46. const char *xml_path = getenv("CLISH_PATH");
  47. const char *view = getenv("CLISH_VIEW");
  48. const char *viewid = getenv("CLISH_VIEWID");
  49. /* Signal vars */
  50. struct sigaction sigpipe_act;
  51. sigset_t sigpipe_set;
  52. static const char *shortopts = "hvs:ledx:w:i:";
  53. #ifdef HAVE_GETOPT_H
  54. static const struct option longopts[] = {
  55. {"help", 0, NULL, 'h'},
  56. {"version", 0, NULL, 'v'},
  57. {"socket", 1, NULL, 's'},
  58. {"lockless", 0, NULL, 'l'},
  59. {"stop-on-error", 0, NULL, 'e'},
  60. {"dry-run", 0, NULL, 'd'},
  61. {"xml-path", 1, NULL, 'x'},
  62. {"view", 1, NULL, 'w'},
  63. {"viewid", 1, NULL, 'i'},
  64. {NULL, 0, NULL, 0}
  65. };
  66. #endif
  67. /* Ignore SIGPIPE */
  68. sigemptyset(&sigpipe_set);
  69. sigaddset(&sigpipe_set, SIGPIPE);
  70. sigpipe_act.sa_flags = 0;
  71. sigpipe_act.sa_mask = sigpipe_set;
  72. sigpipe_act.sa_handler = SIG_IGN;
  73. sigaction(SIGPIPE, &sigpipe_act, NULL);
  74. /* Parse command line options */
  75. optind = 0;
  76. while(1) {
  77. int opt;
  78. #ifdef HAVE_GETOPT_H
  79. opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  80. #else
  81. opt = getopt(argc, argv, shortopts);
  82. #endif
  83. if (-1 == opt)
  84. break;
  85. switch (opt) {
  86. case 's':
  87. socket_path = optarg;
  88. break;
  89. case 'l':
  90. lockless = BOOL_TRUE;
  91. break;
  92. case 'e':
  93. stop_on_error = BOOL_TRUE;
  94. break;
  95. case 'd':
  96. my_hooks.script_fn = clish_dryrun_callback;
  97. break;
  98. case 'x':
  99. xml_path = optarg;
  100. break;
  101. case 'w':
  102. view = optarg;
  103. break;
  104. case 'i':
  105. viewid = optarg;
  106. break;
  107. case 'h':
  108. help(0, argv[0]);
  109. exit(0);
  110. break;
  111. case 'v':
  112. version(VERSION);
  113. exit(0);
  114. break;
  115. default:
  116. help(-1, argv[0]);
  117. exit(-1);
  118. break;
  119. }
  120. }
  121. /* Create shell instance */
  122. shell = clish_shell_new(&my_hooks, NULL, NULL, stdout, stop_on_error);
  123. if (!shell) {
  124. fprintf(stderr, "Cannot run clish.\n");
  125. return -1;
  126. }
  127. /* Load the XML files */
  128. clish_shell_load_scheme(shell, xml_path);
  129. /* Set communication to the konfd */
  130. clish_shell__set_socket(shell, socket_path);
  131. /* Set lockless mode */
  132. if (lockless)
  133. clish_shell__set_lockfile(shell, NULL);
  134. /* Set startup view */
  135. if (view)
  136. clish_shell__set_startup_view(shell, view);
  137. /* Set startup viewid */
  138. if (viewid)
  139. clish_shell__set_startup_viewid(shell, viewid);
  140. /* Execute startup */
  141. running = clish_shell_startup(shell);
  142. if (!running) {
  143. fprintf(stderr, "Cannot startup clish.\n");
  144. clish_shell_delete(shell);
  145. return -1;
  146. }
  147. if(optind < argc) {
  148. int i;
  149. /* Run the commands from the files */
  150. for (i = argc - 1; i >= optind; i--)
  151. clish_shell_push_file(shell, argv[i], stop_on_error);
  152. } else {
  153. /* The interactive shell */
  154. clish_shell_push_fd(shell, fdopen(dup(fileno(stdin)), "r"), stop_on_error);
  155. }
  156. result = clish_shell_loop(shell);
  157. /* Cleanup */
  158. clish_shell_delete(shell);
  159. return result ? 0 : -1;
  160. }
  161. /*--------------------------------------------------------- */
  162. /* Print help message */
  163. static void help(int status, const char *argv0)
  164. {
  165. const char *name = NULL;
  166. if (!argv0)
  167. return;
  168. /* Find the basename */
  169. name = strrchr(argv0, '/');
  170. if (name)
  171. name++;
  172. else
  173. name = argv0;
  174. if (status != 0) {
  175. fprintf(stderr, "Try `%s -h' for more information.\n",
  176. name);
  177. } else {
  178. printf("Usage: %s [options]\n", name);
  179. printf("CLI utility. "
  180. "The part of the klish project.\n");
  181. printf("Options:\n");
  182. printf("\t-v, --version\tPrint version.\n");
  183. printf("\t-h, --help\tPrint this help.\n");
  184. printf("\t-s <path>, --socket=<path>\tSpecify listen socket "
  185. "of the konfd daemon.\n");
  186. printf("\t-l, --lockless\tDon't use locking mechanism.\n");
  187. printf("\t-e, --stop-on-error\tStop programm execution on error.\n");
  188. printf("\t-d, --dry-run\tDon't actually execute ACTION scripts.\n");
  189. printf("\t-x, --xml-path\tPath to XML scheme files.\n");
  190. printf("\t-w, --view\tSet the startup view.\n");
  191. printf("\t-i, --viewid\tSet the startup viewid.\n");
  192. }
  193. }