A small USV for ALIX boards with i2c support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
5.7KB

  1. /***************************************************************************
  2. * Copyright (C) 07/2007 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; version 2 of the License *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <unistd.h>
  23. #include <sys/socket.h>
  24. #include <netinet/in.h>
  25. #include <netinet/ip.h>
  26. #include <arpa/inet.h>
  27. #include "configfile.h"
  28. #include "list.h"
  29. #include "logging.h"
  30. #define BUFSIZE 1024
  31. struct conf_section {
  32. struct list_head list;
  33. struct list_head tupel_list;
  34. const char *name;
  35. };
  36. struct conf_tupel {
  37. struct list_head list;
  38. const char *option;
  39. const char *parameter;
  40. };
  41. static LIST_HEAD(config_list);
  42. static struct conf_section * config_add_section(const char *name)
  43. {
  44. struct conf_section *section;
  45. section = malloc(sizeof(struct conf_section) + strlen(name));
  46. if (section == NULL)
  47. return NULL;
  48. INIT_LIST_HEAD(&section->list);
  49. INIT_LIST_HEAD(&section->tupel_list);
  50. section->name = strdup(name);
  51. if (section->name == NULL) {
  52. free(section);
  53. return NULL;
  54. }
  55. list_add_tail(&section->list, &config_list);
  56. return section;
  57. }
  58. static int config_add_tupel(struct conf_section *section, const char *option, const char *parameter)
  59. {
  60. struct conf_tupel *tupel = malloc(sizeof(struct conf_tupel));
  61. if (tupel == NULL)
  62. return -1;
  63. INIT_LIST_HEAD(&tupel->list);
  64. tupel->option = strdup(option);
  65. tupel->parameter = strdup(parameter);
  66. if (tupel->option == NULL || tupel->parameter == NULL) {
  67. free(tupel);
  68. return -1;
  69. }
  70. list_add_tail(&tupel->list, &section->tupel_list);
  71. return 0;
  72. }
  73. int config_parse(const char *config)
  74. {
  75. FILE *fz = fopen(config, "r");
  76. if (fz == NULL) {
  77. log_print(LOG_ERROR, "config_parse(): %s", config);
  78. return -1;
  79. }
  80. char *line = malloc(BUFSIZE);
  81. if (line == NULL) {
  82. log_print(LOG_ERROR, "config_parse(): out of memory");
  83. fclose(fz);
  84. return -1;
  85. }
  86. int linenum = 0;
  87. struct conf_section *section = NULL;
  88. while (fgets(line, BUFSIZE, fz) != NULL) {
  89. linenum++;
  90. if (line[0] == '#' || line[0] <= ' ') {
  91. continue;
  92. } else if (line[0] == '[') {
  93. char *tok = strtok(line +1, " ]\n");
  94. if (tok == NULL || (section = config_add_section(tok)) == NULL) {
  95. log_print(LOG_WARN, "config_parse(): invalid section in row %d", linenum);
  96. free(line);
  97. fclose(fz);
  98. return -1;
  99. }
  100. continue;
  101. } else if (section == NULL) {
  102. log_print(LOG_WARN, "config_parse(): missing section in row %d", linenum);
  103. free(line);
  104. fclose(fz);
  105. return -1;
  106. }
  107. char *tok = strtok(line, " \n");
  108. if (tok != NULL) {
  109. char *tok2;
  110. while ((tok2 = strtok(NULL, " \n"))) {
  111. if (config_add_tupel(section, tok, tok2) != 0)
  112. log_print(LOG_WARN, "config_parse(): invalid row %d", linenum);
  113. }
  114. }
  115. }
  116. fclose(fz);
  117. free(line);
  118. return 0;
  119. }
  120. void config_free(void)
  121. {
  122. struct conf_section *section, *section_tmp;
  123. struct conf_tupel *tupel, *tupel_tmp;
  124. list_for_each_entry_safe(section, section_tmp, &config_list, list) {
  125. list_for_each_entry_safe(tupel, tupel_tmp, &section->tupel_list, list) {
  126. list_del(&tupel->list);
  127. free((char *)tupel->option);
  128. free((char *)tupel->parameter);
  129. free(tupel);
  130. }
  131. list_del(&section->list);
  132. free(section);
  133. }
  134. }
  135. static struct conf_section * config_get_section(const char *name)
  136. {
  137. struct conf_section *section;
  138. list_for_each_entry(section, &config_list, list) {
  139. if (!strcmp(section->name, name))
  140. return section;
  141. }
  142. return NULL;
  143. }
  144. const char * config_get_string(const char *section_str, const char *option, const char *def)
  145. {
  146. struct conf_section *section = config_get_section(section_str);
  147. if (section != NULL) {
  148. struct conf_tupel *tupel;
  149. list_for_each_entry(tupel, &section->tupel_list, list) {
  150. if (!strcmp(tupel->option, option))
  151. return tupel->parameter;
  152. }
  153. }
  154. if (def != NULL)
  155. log_print(LOG_WARN, "config [%s:%s] not found, using default: '%s'",
  156. section_str, option, def);
  157. return def;
  158. }
  159. int config_get_int(const char *section, const char *option, int def)
  160. {
  161. const char *ret = config_get_string(section, option, NULL);
  162. if (ret == NULL) {
  163. log_print(LOG_WARN, "config [%s:%s] not found, using default: '%d'",
  164. section, option, def);
  165. return def;
  166. }
  167. return atoi(ret);
  168. }
  169. int config_get_strings(const char *section_str, const char *option,
  170. int (*callback)(const char *value, void *privdata),
  171. void *privdata)
  172. {
  173. struct conf_section *section = config_get_section(section_str);
  174. if (section == NULL)
  175. return -1;
  176. int cnt = 0;
  177. struct conf_tupel *tupel;
  178. list_for_each_entry(tupel, &section->tupel_list, list) {
  179. if (!strcmp(tupel->option, option))
  180. if (callback(tupel->parameter, privdata) == 0)
  181. cnt++;
  182. }
  183. return cnt;
  184. }