opts.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include <stdlib.h>
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <getopt.h>
  12. #include <faux/faux.h>
  13. #include <faux/str.h>
  14. #include <faux/list.h>
  15. #include <klish/ktp_session.h>
  16. #include "private.h"
  17. /** @brief Initialize option structure by defaults
  18. */
  19. struct options *opts_init(void)
  20. {
  21. struct options *opts = NULL;
  22. opts = faux_zmalloc(sizeof(*opts));
  23. assert(opts);
  24. // Initialize
  25. opts->verbose = BOOL_FALSE;
  26. opts->stop_on_error = BOOL_FALSE;
  27. opts->dry_run = BOOL_FALSE;
  28. opts->quiet = BOOL_FALSE;
  29. opts->unix_socket_path = faux_str_dup(KLISH_DEFAULT_UNIX_SOCKET_PATH);
  30. // Don't free command list because elements are the pointers to
  31. // command line options and don't need to be freed().
  32. opts->commands = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
  33. NULL, NULL, NULL);
  34. opts->files = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
  35. NULL, NULL, NULL);
  36. return opts;
  37. }
  38. /** @brief Free options structure
  39. */
  40. void opts_free(struct options *opts)
  41. {
  42. if (!opts)
  43. return;
  44. faux_str_free(opts->unix_socket_path);
  45. faux_list_free(opts->commands);
  46. faux_list_free(opts->files);
  47. faux_free(opts);
  48. }
  49. /** @brief Parse command line options
  50. */
  51. int opts_parse(int argc, char *argv[], struct options *opts)
  52. {
  53. static const char *shortopts = "hvS:c:edq";
  54. static const struct option longopts[] = {
  55. {"socket", 1, NULL, 'S'},
  56. {"help", 0, NULL, 'h'},
  57. {"verbose", 0, NULL, 'v'},
  58. {"command", 1, NULL, 'c'},
  59. {"stop-on-error", 0, NULL, 'e'},
  60. {"dry-run", 0, NULL, 'd'},
  61. {"quiet", 0, NULL, 'q'},
  62. {NULL, 0, NULL, 0}
  63. };
  64. optind = 1;
  65. while(1) {
  66. int opt = 0;
  67. opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  68. if (-1 == opt)
  69. break;
  70. switch (opt) {
  71. case 'S':
  72. faux_str_free(opts->unix_socket_path);
  73. opts->unix_socket_path = faux_str_dup(optarg);
  74. break;
  75. case 'v':
  76. opts->verbose = BOOL_TRUE;
  77. break;
  78. case 'e':
  79. opts->stop_on_error = BOOL_TRUE;
  80. break;
  81. case 'd':
  82. opts->dry_run = BOOL_TRUE;
  83. break;
  84. case 'q':
  85. opts->quiet = BOOL_TRUE;
  86. break;
  87. case 'h':
  88. help(0, argv[0]);
  89. _exit(0);
  90. break;
  91. case 'c':
  92. faux_list_add(opts->commands, optarg);
  93. break;
  94. default:
  95. help(-1, argv[0]);
  96. _exit(-1);
  97. break;
  98. }
  99. }
  100. // Input files
  101. if(optind < argc) {
  102. int i;
  103. for (i = argc - 1; i >= optind; i--)
  104. faux_list_add(opts->files, argv[i]);
  105. }
  106. // Validate options
  107. // Commands specified by '-c' option can't coexist with input files
  108. if (!faux_list_is_empty(opts->commands) &&
  109. !faux_list_is_empty(opts->files)) {
  110. fprintf(stderr, "Error: Commands specified by '-c' can't coexist "
  111. "with input files\n");
  112. _exit(-1);
  113. }
  114. return 0;
  115. }
  116. /** @brief Print help message
  117. */
  118. void help(int status, const char *argv0)
  119. {
  120. const char *name = NULL;
  121. if (!argv0)
  122. return;
  123. // Find the basename
  124. name = strrchr(argv0, '/');
  125. if (name)
  126. name++;
  127. else
  128. name = argv0;
  129. if (status != 0) {
  130. fprintf(stderr, "Try `%s -h' for more information.\n",
  131. name);
  132. } else {
  133. printf("Version : %s\n", VERSION);
  134. printf("Usage : %s [options] [filename] ... [filename]\n", name);
  135. printf("Klish client\n");
  136. printf("Options :\n");
  137. printf("\t-S <path>, --socket=<path> UNIX socket path.\n");
  138. printf("\t-h, --help Print this help.\n");
  139. printf("\t-v, --verbose Be verbose.\n");
  140. printf("\t-c <line>, --command=<line> Command to execute.\n"
  141. "\t\tMultiple options are allowed.\n");
  142. printf("\t-e, --stop-on-error Stop script execution on error.\n");
  143. printf("\t-q, --quiet Disable echo while executing commands\n\t\tfrom the file stream.\n");
  144. printf("\t-d, --dry-run Don't actually execute ACTION scripts.\n");
  145. }
  146. }