Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
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.

config.c 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * The MySensors Arduino library handles the wireless radio link and protocol
  3. * between your home built sensors/actuators and HA controller of choice.
  4. * The sensors forms a self healing radio network with optional repeaters. Each
  5. * repeater and gateway builds a routing tables in EEPROM which keeps track of the
  6. * network topology allowing messages to be routed to nodes.
  7. *
  8. * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
  9. * Copyright (C) 2013-2018 Sensnology AB
  10. * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
  11. *
  12. * Documentation: http://www.mysensors.org
  13. * Support Forum: http://forum.mysensors.org
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * version 2 as published by the Free Software Foundation.
  18. *
  19. * Based on mosquitto project, Copyright (c) 2012 Roger Light <roger@atchoo.org>
  20. */
  21. #include "config.h"
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #include <sys/stat.h>
  27. #include "log.h"
  28. static int _config_create(const char *config_file);
  29. static int _config_parse_int(char *token, const char *name, int *value);
  30. static int _config_parse_string(char *token, const char *name, char **value);
  31. int config_parse(const char *config_file)
  32. {
  33. FILE *fptr;
  34. char buf[1024];
  35. struct stat fileInfo;
  36. if (stat(config_file, &fileInfo) != 0) {
  37. //File does not exist. Create it.
  38. logInfo("Config file %s does not exist, creating new file.\n", config_file);
  39. _config_create(config_file);
  40. }
  41. fptr = fopen(config_file, "rt");
  42. if (!fptr) {
  43. logError("Error opening config file \"%s\".\n", config_file);
  44. return -1;
  45. }
  46. conf.verbose = 7;
  47. conf.log_pipe = 0;
  48. conf.log_pipe_file = NULL;
  49. conf.syslog = 0;
  50. conf.eeprom_file = NULL;
  51. conf.eeprom_size = 0;
  52. conf.soft_hmac_key = NULL;
  53. conf.soft_serial_key = NULL;
  54. conf.aes_key = NULL;
  55. while (fgets(buf, 1024, fptr)) {
  56. if (buf[0] != '#' && buf[0] != 10 && buf[0] != 13) {
  57. while (buf[strlen(buf)-1] == 10 || buf[strlen(buf)-1] == 13) {
  58. buf[strlen(buf)-1] = 0;
  59. }
  60. if (!strncmp(buf, "verbose=", 8)) {
  61. char *verbose = NULL;
  62. if (_config_parse_string(&(buf[8]), "verbose", &verbose)) {
  63. fclose(fptr);
  64. return -1;
  65. } else {
  66. if (!strncmp(verbose, "err", 3)) {
  67. conf.verbose = 3;
  68. } else if (!strncmp(verbose, "warn", 4)) {
  69. conf.verbose = 4;
  70. } else if (!strncmp(verbose, "notice", 6)) {
  71. conf.verbose = 5;
  72. } else if (!strncmp(verbose, "info", 4)) {
  73. conf.verbose = 6;
  74. } else if (!strncmp(verbose, "debug", 5)) {
  75. conf.verbose = 7;
  76. } else {
  77. logError("Invalid value for verbose in configuration.\n");
  78. fclose(fptr);
  79. free(verbose);
  80. return -1;
  81. }
  82. free(verbose);
  83. }
  84. } else if (!strncmp(buf, "log_file=", 9)) {
  85. if (_config_parse_int(&(buf[9]), "log_file", &conf.log_file)) {
  86. fclose(fptr);
  87. return -1;
  88. } else {
  89. if (conf.log_file != 0 && conf.log_file != 1) {
  90. logError("log_file must be 1 or 0 in configuration.\n");
  91. fclose(fptr);
  92. return -1;
  93. }
  94. }
  95. } else if (!strncmp(buf, "log_filepath=", 13)) {
  96. if (_config_parse_string(&(buf[13]), "log_filepath", &conf.log_filepath)) {
  97. fclose(fptr);
  98. return -1;
  99. }
  100. } else if (!strncmp(buf, "log_pipe=", 9)) {
  101. if (_config_parse_int(&(buf[9]), "log_pipe", &conf.log_pipe)) {
  102. fclose(fptr);
  103. return -1;
  104. } else {
  105. if (conf.log_pipe != 0 && conf.log_pipe != 1) {
  106. logError("log_pipe must be 1 or 0 in configuration.\n");
  107. fclose(fptr);
  108. return -1;
  109. }
  110. }
  111. } else if (!strncmp(buf, "log_pipe_file=", 14)) {
  112. if (_config_parse_string(&(buf[14]), "log_pipe_file", &conf.log_pipe_file)) {
  113. fclose(fptr);
  114. return -1;
  115. }
  116. } else if (!strncmp(buf, "syslog=", 7)) {
  117. if (_config_parse_int(&(buf[7]), "syslog", &conf.syslog)) {
  118. fclose(fptr);
  119. return -1;
  120. } else {
  121. if (conf.syslog != 0 && conf.syslog != 1) {
  122. logError("syslog must be 1 or 0 in configuration.\n");
  123. fclose(fptr);
  124. return -1;
  125. }
  126. }
  127. } else if (!strncmp(buf, "eeprom_file=", 12)) {
  128. if (_config_parse_string(&(buf[12]), "eeprom_file", &conf.eeprom_file)) {
  129. fclose(fptr);
  130. return -1;
  131. }
  132. } else if (!strncmp(buf, "eeprom_size=", 12)) {
  133. if (_config_parse_int(&(buf[12]), "eeprom_size", &conf.eeprom_size)) {
  134. fclose(fptr);
  135. return -1;
  136. } else {
  137. if (conf.eeprom_size <= 0) {
  138. logError("eeprom_size value must be greater than 0 in configuration.\n");
  139. fclose(fptr);
  140. return -1;
  141. }
  142. }
  143. } else if (!strncmp(buf, "soft_hmac_key=", 14)) {
  144. if (_config_parse_string(&(buf[14]), "soft_hmac_key", &conf.soft_hmac_key)) {
  145. fclose(fptr);
  146. return -1;
  147. }
  148. } else if (!strncmp(buf, "soft_serial_key=", 16)) {
  149. if (_config_parse_string(&(buf[16]), "soft_serial_key", &conf.soft_serial_key)) {
  150. fclose(fptr);
  151. return -1;
  152. }
  153. } else if (!strncmp(buf, "aes_key=", 8)) {
  154. if (_config_parse_string(&(buf[8]), "aes_key", &conf.aes_key)) {
  155. fclose(fptr);
  156. return -1;
  157. }
  158. } else {
  159. logWarning("Unknown config option \"%s\".\n", buf);
  160. }
  161. }
  162. }
  163. fclose(fptr);
  164. if (!conf.eeprom_file) {
  165. logError("No eeprom_file found in configuration.\n");
  166. return -1;
  167. }
  168. if (conf.log_file && !conf.log_filepath) {
  169. logError("log_filepath must be set if you enable log_file in configuration.\n");
  170. return -1;
  171. }
  172. if (conf.log_pipe && !conf.log_pipe_file) {
  173. logError("log_pipe_file must be set if you enable log_pipe in configuration.\n");
  174. return -1;
  175. }
  176. return 0;
  177. }
  178. void config_cleanup(void)
  179. {
  180. if (conf.log_filepath) {
  181. free(conf.log_filepath);
  182. }
  183. if (conf.log_pipe_file) {
  184. free(conf.log_pipe_file);
  185. }
  186. if (conf.eeprom_file) {
  187. free(conf.eeprom_file);
  188. }
  189. if (conf.soft_hmac_key) {
  190. free(conf.soft_hmac_key);
  191. }
  192. if (conf.soft_serial_key) {
  193. free(conf.soft_serial_key);
  194. }
  195. if (conf.aes_key) {
  196. free(conf.aes_key);
  197. }
  198. }
  199. int _config_create(const char *config_file)
  200. {
  201. FILE *myFile;
  202. int ret;
  203. const char default_conf[] = "# Logging\n" \
  204. "# Verbosity: debug,info,notice,warn,err\n" \
  205. "verbose=debug\n" \
  206. "\n" \
  207. "# Enable logging to a file.\n" \
  208. "log_file=0\n" \
  209. "# Log file path.\n" \
  210. "log_filepath=/tmp/mysgw.log\n" \
  211. "\n" \
  212. "# Enable logging to a named pipe.\n" \
  213. "# Use this option to view your gateway's log messages\n" \
  214. "# from the log_pipe_file defined bellow.\n" \
  215. "# To do so, run the following command on another terminal:\n" \
  216. "# cat \"log_pipe_file\"\n" \
  217. "log_pipe=0\n" \
  218. "log_pipe_file=/tmp/mysgw.pipe\n" \
  219. "\n" \
  220. "# Enable logging to syslog.\n" \
  221. "syslog=0\n" \
  222. "\n" \
  223. "# EEPROM settings\n" \
  224. "eeprom_file=/etc/mysensors.eeprom\n" \
  225. "eeprom_size=1024\n" \
  226. "\n" \
  227. "# Software signing settings\n" \
  228. "# Note: The gateway must have been built with signing\n" \
  229. "# support to use the options below.\n" \
  230. "#\n" \
  231. "# To generate a HMAC key run mysgw with: --gen-soft-hmac-key\n" \
  232. "# copy the new key in the line below and uncomment it.\n" \
  233. "#soft_hmac_key=\n" \
  234. "# To generate a serial key run mysgw with: --gen-soft-serial-key\n" \
  235. "# copy the new key in the line below and uncomment it.\n" \
  236. "#soft_serial_key=\n" \
  237. "\n" \
  238. "# Encryption settings\n" \
  239. "# Note: The gateway must have been built with encryption\n" \
  240. "# support to use the options below.\n" \
  241. "#\n" \
  242. "# To generate a AES key run mysgw with: --gen-aes-key\n" \
  243. "# copy the new key in the line below and uncomment it.\n" \
  244. "#aes_key=\n";
  245. myFile = fopen(config_file, "w");
  246. if (!myFile) {
  247. logError("Unable to create config file %s.\n", config_file);
  248. return -1;
  249. }
  250. ret = fputs(default_conf, myFile);
  251. fclose(myFile);
  252. return (ret > 0);
  253. }
  254. int _config_parse_int(char *token, const char *name, int *value)
  255. {
  256. if (token) {
  257. *value = atoi(token);
  258. } else {
  259. logError("Empty %s value in configuration.\n", name);
  260. return 1;
  261. }
  262. return 0;
  263. }
  264. int _config_parse_string(char *token, const char *name, char **value)
  265. {
  266. if (token) {
  267. if (*value) {
  268. logError("Duplicate %s value in configuration.\n", name);
  269. return 1;
  270. }
  271. while (token[0] == ' ' || token[0] == '\t') {
  272. token++;
  273. }
  274. *value = strdup(token);
  275. if (!*value) {
  276. logError("Out of memory.\n");
  277. return 1;
  278. }
  279. } else {
  280. logError("Empty %s value in configuration.\n", name);
  281. return 1;
  282. }
  283. return 0;
  284. }