esl_config.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. * Copyright (c) 2007-2014, Anthony Minessale II
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. *
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * * Neither the name of the original author; nor the names of any contributors
  17. * may be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  24. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  25. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  29. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. #include "esl.h"
  34. #include "esl_config.h"
  35. ESL_DECLARE(int) esl_config_open_file(esl_config_t *cfg, const char *file_path)
  36. {
  37. FILE *f;
  38. const char *path = NULL;
  39. char path_buf[1024];
  40. if (file_path[0] == '/') {
  41. path = file_path;
  42. } else {
  43. esl_snprintf(path_buf, sizeof(path_buf), "%s%s%s", ESL_CONFIG_DIR, ESL_PATH_SEPARATOR, file_path);
  44. path = path_buf;
  45. }
  46. if (!path) {
  47. return 0;
  48. }
  49. memset(cfg, 0, sizeof(*cfg));
  50. cfg->lockto = -1;
  51. esl_log(ESL_LOG_DEBUG, "Configuration file is %s.\n", path);
  52. f = fopen(path, "r");
  53. if (!f) {
  54. if (file_path[0] != '/') {
  55. int last = -1;
  56. char *var, *val;
  57. esl_snprintf(path_buf, sizeof(path_buf), "%s%sopenesl.conf", ESL_CONFIG_DIR, ESL_PATH_SEPARATOR);
  58. path = path_buf;
  59. if ((f = fopen(path, "r")) == 0) {
  60. return 0;
  61. }
  62. cfg->file = f;
  63. esl_set_string(cfg->path, path);
  64. while (esl_config_next_pair(cfg, &var, &val)) {
  65. if ((cfg->sectno != last) && !strcmp(cfg->section, file_path)) {
  66. cfg->lockto = cfg->sectno;
  67. return 1;
  68. }
  69. }
  70. esl_config_close_file(cfg);
  71. memset(cfg, 0, sizeof(*cfg));
  72. return 0;
  73. }
  74. return 0;
  75. } else {
  76. cfg->file = f;
  77. esl_set_string(cfg->path, path);
  78. return 1;
  79. }
  80. }
  81. ESL_DECLARE(void) esl_config_close_file(esl_config_t *cfg)
  82. {
  83. if (cfg->file) {
  84. fclose(cfg->file);
  85. }
  86. memset(cfg, 0, sizeof(*cfg));
  87. }
  88. ESL_DECLARE(int) esl_config_next_pair(esl_config_t *cfg, char **var, char **val)
  89. {
  90. int ret = 0;
  91. char *p, *end;
  92. *var = *val = NULL;
  93. if (!cfg || !cfg->file) {
  94. return 0;
  95. }
  96. for (;;) {
  97. cfg->lineno++;
  98. if (!fgets(cfg->buf, sizeof(cfg->buf), cfg->file)) {
  99. ret = 0;
  100. break;
  101. }
  102. *var = cfg->buf;
  103. if (**var == '[' && (end = strchr(*var, ']')) != 0) {
  104. *end = '\0';
  105. (*var)++;
  106. if (**var == '+') {
  107. (*var)++;
  108. esl_copy_string(cfg->section, *var, sizeof(cfg->section));
  109. cfg->sectno++;
  110. if (cfg->lockto > -1 && cfg->sectno != cfg->lockto) {
  111. break;
  112. }
  113. cfg->catno = 0;
  114. cfg->lineno = 0;
  115. *var = (char *) "";
  116. *val = (char *) "";
  117. return 1;
  118. } else {
  119. esl_copy_string(cfg->category, *var, sizeof(cfg->category));
  120. cfg->catno++;
  121. }
  122. continue;
  123. }
  124. if (**var == '#' || **var == ';' || **var == '\n' || **var == '\r') {
  125. continue;
  126. }
  127. if (!strncmp(*var, "__END__", 7)) {
  128. break;
  129. }
  130. if ((end = strchr(*var, ';')) && *(end+1) == *end) {
  131. *end = '\0';
  132. end--;
  133. } else if ((end = strchr(*var, '\n')) != 0) {
  134. if (*(end - 1) == '\r') {
  135. end--;
  136. }
  137. *end = '\0';
  138. }
  139. p = *var;
  140. while ((*p == ' ' || *p == '\t') && p != end) {
  141. *p = '\0';
  142. p++;
  143. }
  144. *var = p;
  145. if ((*val = strchr(*var, '=')) == 0) {
  146. ret = -1;
  147. /* log_printf(0, server.log, "Invalid syntax on %s: line %d\n", cfg->path, cfg->lineno); */
  148. continue;
  149. } else {
  150. p = *val - 1;
  151. *(*val) = '\0';
  152. (*val)++;
  153. if (*(*val) == '>') {
  154. *(*val) = '\0';
  155. (*val)++;
  156. }
  157. while ((*p == ' ' || *p == '\t') && p != *var) {
  158. *p = '\0';
  159. p--;
  160. }
  161. p = *val;
  162. while ((*p == ' ' || *p == '\t') && p != end) {
  163. *p = '\0';
  164. p++;
  165. }
  166. *val = p;
  167. ret = 1;
  168. break;
  169. }
  170. }
  171. return ret;
  172. }
  173. ESL_DECLARE(int) esl_config_get_cas_bits(char *strvalue, unsigned char *outbits)
  174. {
  175. char cas_bits[5];
  176. unsigned char bit = 0x8;
  177. char *double_colon = strchr(strvalue, ':');
  178. int x = 0;
  179. if (!double_colon) {
  180. esl_log(ESL_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
  181. return -1;
  182. }
  183. double_colon++;
  184. *outbits = 0;
  185. cas_bits[4] = 0;
  186. if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) {
  187. esl_log(ESL_LOG_ERROR, "Invalid CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
  188. return -1;
  189. }
  190. esl_log(ESL_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits);
  191. for (; cas_bits[x]; x++) {
  192. if ('1' == cas_bits[x]) {
  193. *outbits |= bit;
  194. } else if ('0' != cas_bits[x]) {
  195. esl_log(ESL_LOG_ERROR, "Invalid CAS pattern specified: %s, just 0 or 1 allowed for each bit\n");
  196. return -1;
  197. }
  198. bit >>= 1;
  199. }
  200. return 0;
  201. }
  202. /* For Emacs:
  203. * Local Variables:
  204. * mode:c
  205. * indent-tabs-mode:t
  206. * tab-width:4
  207. * c-basic-offset:4
  208. * End:
  209. * For VIM:
  210. * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
  211. */