conf.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* Gearman server and library
  2. * Copyright (C) 2009 Eric Day
  3. * All rights reserved.
  4. *
  5. * Use and distribution licensed under the BSD license. See
  6. * the COPYING file in the parent directory for full text.
  7. */
  8. /**
  9. * @file
  10. * @brief Gearman conf definitions
  11. */
  12. #include "common.h"
  13. /*
  14. * Public definitions
  15. */
  16. gearman_conf_st *gearman_conf_create(gearman_conf_st *conf)
  17. {
  18. if (conf == NULL)
  19. {
  20. conf= (gearman_conf_st *)malloc(sizeof(gearman_conf_st));
  21. if (conf == NULL)
  22. {
  23. gearmand_perror("malloc");
  24. return NULL;
  25. }
  26. conf->options.allocated= true;
  27. }
  28. else
  29. {
  30. conf->options.allocated= false;
  31. }
  32. conf->last_return= GEARMAN_SUCCESS;
  33. conf->last_errno= 0;
  34. conf->module_count= 0;
  35. conf->option_count= 0;
  36. conf->short_count= 0;
  37. conf->module_list= NULL;
  38. conf->option_list= NULL;
  39. conf->option_short[0]= 0;
  40. conf->last_error[0]= 0;
  41. /* We always need a NULL terminated getopt list. */
  42. conf->option_getopt= (struct option *)malloc(sizeof(struct option));
  43. if (conf->option_getopt == NULL)
  44. {
  45. gearmand_perror("malloc");
  46. gearman_conf_free(conf);
  47. return NULL;
  48. }
  49. memset(conf->option_getopt, 0, sizeof(sizeof(struct option)));
  50. return conf;
  51. }
  52. void gearman_conf_free(gearman_conf_st *conf)
  53. {
  54. uint32_t x;
  55. for (x= 0; x < conf->module_count; x++)
  56. gearman_conf_module_free(conf->module_list[x]);
  57. for (x= 0; x < conf->option_count; x++)
  58. {
  59. free((char *)conf->option_getopt[x].name);
  60. if (conf->option_list[x].value_list != NULL)
  61. free(conf->option_list[x].value_list);
  62. }
  63. if (conf->module_list != NULL)
  64. free(conf->module_list);
  65. if (conf->option_list != NULL)
  66. free(conf->option_list);
  67. if (conf->option_getopt != NULL)
  68. free(conf->option_getopt);
  69. if (conf->options.allocated)
  70. free(conf);
  71. }
  72. gearmand_error_t gearman_conf_return(gearman_conf_st *conf)
  73. {
  74. return conf->last_return;
  75. }
  76. const char *gearman_conf_error(gearman_conf_st *conf)
  77. {
  78. return (const char *)(conf->last_error);
  79. }
  80. int gearman_conf_errno(gearman_conf_st *conf)
  81. {
  82. return conf->last_errno;
  83. }
  84. gearmand_error_t gearman_conf_parse_args(gearman_conf_st *conf, int argc,
  85. char *argv[])
  86. {
  87. int c;
  88. int opt_index;
  89. gearman_conf_option_st *option;
  90. char **value_list;
  91. /* This will supress errors being printed to stderr. */
  92. opterr= 0;
  93. while (1)
  94. {
  95. c= getopt_long(argc, argv, conf->option_short, conf->option_getopt,
  96. &opt_index);
  97. if (c == -1)
  98. break;
  99. switch (c)
  100. {
  101. case 0:
  102. /* We have a long option, use index. */
  103. break;
  104. default:
  105. /* Find the long option index that matches the short character. */
  106. for (opt_index= 0; opt_index < (int)conf->option_count; opt_index++)
  107. {
  108. if (conf->option_getopt[opt_index].val == c)
  109. break;
  110. }
  111. if (opt_index == (int)conf->option_count)
  112. {
  113. gearman_conf_error_set(conf, "ERROR", " Unknown option: %s", argv[optind - 1]);
  114. return GEARMAN_UNKNOWN_OPTION;
  115. }
  116. }
  117. option= &conf->option_list[opt_index];
  118. value_list= (char **)realloc(option->value_list,
  119. sizeof(char *) * (option->value_count + 1));
  120. if (value_list == NULL)
  121. {
  122. gearman_conf_error_set(conf, "gearman_conf_parse_args", " realloc");
  123. return GEARMAN_MEMORY_ALLOCATION_FAILURE;
  124. }
  125. option->value_list= value_list;
  126. option->value_list[option->value_count]= optarg;
  127. option->value_count++;
  128. }
  129. if (optind < argc)
  130. {
  131. gearman_conf_error_set(conf, "gearman_conf_parse_args", "Unknown option: %s", argv[optind]);
  132. return GEARMAN_UNKNOWN_OPTION;
  133. }
  134. return GEARMAN_SUCCESS;
  135. }
  136. void gearman_conf_usage(gearman_conf_st *conf)
  137. {
  138. uint32_t x;
  139. uint32_t y;
  140. gearman_conf_module_st *module;
  141. gearman_conf_option_st *option;
  142. bool print_header;
  143. char display[GEARMAN_CONF_DISPLAY_WIDTH];
  144. size_t max_length;
  145. size_t new_length;
  146. const char *help_start;
  147. const char *help_next;
  148. for (x= 0; x < conf->module_count; x++)
  149. {
  150. module= conf->module_list[x];
  151. print_header= true;
  152. /* Find the maximum option length for this module. */
  153. max_length= 0;
  154. for (y= 0; y < conf->option_count; y++)
  155. {
  156. if (module != conf->option_list[y].module)
  157. continue;
  158. new_length= strlen(conf->option_getopt[y].name);
  159. if (conf->option_list[y].value_name != NULL)
  160. new_length+= strlen(conf->option_list[y].value_name) + 1;
  161. if (new_length > max_length)
  162. max_length= new_length;
  163. }
  164. /* Truncate option length if it's too long. */
  165. max_length+= 8;
  166. if (max_length > GEARMAN_CONF_DISPLAY_WIDTH - 2)
  167. max_length= GEARMAN_CONF_DISPLAY_WIDTH - 2;
  168. /* Print out all options.allocated for this module. */
  169. for (y= 0; y < conf->option_count; y++)
  170. {
  171. option= &conf->option_list[y];
  172. if (option->module != module)
  173. continue;
  174. if (print_header)
  175. {
  176. printf("\n%s Options:\n\n",
  177. module->name == NULL ? "Main" : module->name);
  178. print_header= false;
  179. }
  180. /* Build string with possible short option. */
  181. snprintf(display, GEARMAN_CONF_DISPLAY_WIDTH, " --%s%s%s%80s",
  182. conf->option_getopt[y].name,
  183. option->value_name == NULL ? "" : "=",
  184. option->value_name == NULL ? "" : option->value_name, "");
  185. display[max_length - 1]= ' ';
  186. display[max_length]= 0;
  187. if (conf->option_getopt[y].val != 0)
  188. {
  189. display[1]= '-';
  190. display[2]= (signed char)conf->option_getopt[y].val;
  191. display[3]= ',';
  192. }
  193. /* If there is no help, just print the option. */
  194. if (option->help == NULL)
  195. {
  196. printf("%s\n", display);
  197. continue;
  198. }
  199. /* Make sure the help string is properly wrapped. */
  200. help_start= option->help;
  201. while (strlen(help_start) > (GEARMAN_CONF_DISPLAY_WIDTH - max_length))
  202. {
  203. help_next= help_start + (GEARMAN_CONF_DISPLAY_WIDTH - max_length);
  204. while (help_next != help_start && *help_next != ' ')
  205. help_next--;
  206. if (help_next == help_start)
  207. help_next= strchr(help_start, ' ');
  208. if (help_next == NULL)
  209. break;
  210. printf("%s%.*s\n", display, (int)(help_next - help_start), help_start);
  211. memset(display, ' ', max_length - 1);
  212. help_start= help_next + 1;
  213. }
  214. printf("%s%s\n", display, help_start);
  215. }
  216. }
  217. printf("\n\n");
  218. }