opts.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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->unix_socket_path = faux_str_dup(KLISH_DEFAULT_UNIX_SOCKET_PATH);
  27. // Don't free command list because elements are the pointers to
  28. // command line options and don't need to be freed().
  29. opts->commands = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
  30. NULL, NULL, NULL);
  31. opts->files = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
  32. NULL, NULL, NULL);
  33. return opts;
  34. }
  35. /** @brief Free options structure
  36. */
  37. void opts_free(struct options *opts)
  38. {
  39. if (!opts)
  40. return;
  41. faux_str_free(opts->unix_socket_path);
  42. faux_list_free(opts->commands);
  43. faux_list_free(opts->files);
  44. faux_free(opts);
  45. }
  46. /** @brief Parse command line options
  47. */
  48. int opts_parse(int argc, char *argv[], struct options *opts)
  49. {
  50. static const char *shortopts = "hvS:c:";
  51. static const struct option longopts[] = {
  52. {"socket", 1, NULL, 'S'},
  53. {"help", 0, NULL, 'h'},
  54. {"verbose", 0, NULL, 'v'},
  55. {"command", 1, NULL, 'c'},
  56. {NULL, 0, NULL, 0}
  57. };
  58. optind = 1;
  59. while(1) {
  60. int opt = 0;
  61. opt = getopt_long(argc, argv, shortopts, longopts, NULL);
  62. if (-1 == opt)
  63. break;
  64. switch (opt) {
  65. case 'S':
  66. faux_str_free(opts->unix_socket_path);
  67. opts->unix_socket_path = faux_str_dup(optarg);
  68. break;
  69. case 'v':
  70. opts->verbose = BOOL_TRUE;
  71. break;
  72. case 'h':
  73. help(0, argv[0]);
  74. _exit(0);
  75. break;
  76. case 'c':
  77. faux_list_add(opts->commands, optarg);
  78. break;
  79. default:
  80. help(-1, argv[0]);
  81. _exit(-1);
  82. break;
  83. }
  84. }
  85. // Input files
  86. if(optind < argc) {
  87. int i;
  88. for (i = argc - 1; i >= optind; i--)
  89. faux_list_add(opts->files, argv[i]);
  90. }
  91. // Validate options
  92. // Commands specified by '-c' option can't coexist with input files
  93. if (!faux_list_is_empty(opts->commands) &&
  94. !faux_list_is_empty(opts->files)) {
  95. fprintf(stderr, "Error: Commands specified by '-c' can't coexist "
  96. "with input files\n");
  97. _exit(-1);
  98. }
  99. return 0;
  100. }
  101. /** @brief Print help message
  102. */
  103. void help(int status, const char *argv0)
  104. {
  105. const char *name = NULL;
  106. if (!argv0)
  107. return;
  108. // Find the basename
  109. name = strrchr(argv0, '/');
  110. if (name)
  111. name++;
  112. else
  113. name = argv0;
  114. if (status != 0) {
  115. fprintf(stderr, "Try `%s -h' for more information.\n",
  116. name);
  117. } else {
  118. printf("Version : %s\n", VERSION);
  119. printf("Usage : %s [options]\n", name);
  120. printf("Klish client\n");
  121. printf("Options :\n");
  122. printf("\t-S <path>, --socket=<path> UNIX socket path.\n");
  123. printf("\t-h, --help Print this help.\n");
  124. printf("\t-v, --verbose Be verbose.\n");
  125. printf("\t-c <line>, --command=<line> Command to execute.\n");
  126. }
  127. }