2
0

config.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "common.h"
  2. #include "config.h"
  3. #include <esp_spiffs.h>
  4. #include <ctype.h>
  5. #define MAX_CONFIG_LINE 256
  6. #define CONFIG_FILE "/spiffs/config.txt"
  7. struct configvar {
  8. const char *name;
  9. const char *val;
  10. };
  11. static const struct configvar default_config[] = {
  12. { "TZ", "CET-1CEST,M3.5.0,M10.5.0/3" }, /* Sweden */
  13. { "hostname", "max80" }
  14. };
  15. #ifndef HAVE_CLEARENV
  16. static void clearenv(void)
  17. {
  18. char **new_environ = calloc(ARRAY_SIZE(default_config)+1, sizeof(char *));
  19. char **old_environ = environ;
  20. environ = new_environ;
  21. for (char **envp = old_environ; *envp; envp++)
  22. free(*envp);
  23. free(old_environ);
  24. }
  25. #endif /* HAVE_CLEARENV */
  26. static void reset_config(void)
  27. {
  28. clearenv();
  29. for (size_t i = 0; i < ARRAY_SIZE(default_config); i++)
  30. setenv(default_config[i].name, default_config[i].val, 1);
  31. }
  32. static bool is_end_of_string(int c)
  33. {
  34. return c <= 0 || c == '\n' || c == '\r';
  35. }
  36. static void skip_rest_of_line(FILE *f)
  37. {
  38. int c;
  39. do {
  40. c = getc(f);
  41. } while (!is_end_of_string(c));
  42. }
  43. int read_config(FILE *f)
  44. {
  45. char *linebuf = NULL;
  46. int err = -1;
  47. linebuf = malloc(MAX_CONFIG_LINE);
  48. if (!linebuf)
  49. goto exit;
  50. while (fgets(linebuf, MAX_CONFIG_LINE, f)) {
  51. char *p, *q;
  52. unsigned char c;
  53. p = linebuf;
  54. do {
  55. c = *p++;
  56. } while (isalnum(c) || c == '.' || c == '-');
  57. if (c != '=')
  58. continue; /* Invalid config line (blank, comment...) */
  59. p[-1] = '\0';
  60. q = p;
  61. do {
  62. c = *q++;
  63. } while (!is_end_of_string(c));
  64. if (q >= linebuf + MAX_CONFIG_LINE) {
  65. /* Overlong line, discard rest and drop */
  66. skip_rest_of_line(f);
  67. } else {
  68. q[-1] = '\0';
  69. if (linebuf[0] == '-')
  70. unsetenv(linebuf+1);
  71. else
  72. setenv(linebuf, p, 1);
  73. }
  74. }
  75. err = 0;
  76. exit:
  77. if (linebuf)
  78. free(linebuf);
  79. tzset();
  80. return err;
  81. };
  82. int write_config(FILE *f)
  83. {
  84. for (char **var = environ; *var; var++) {
  85. fputs(*var, f);
  86. putc('\n', f);
  87. }
  88. return ferror(f) ? -1 : 0;
  89. }
  90. int save_config(void)
  91. {
  92. FILE *f = fopen(CONFIG_FILE, "w");
  93. if (!f)
  94. return -1;
  95. int err = write_config(f);
  96. fclose(f);
  97. return err;
  98. }
  99. static const esp_vfs_spiffs_conf_t spiffs_conf = {
  100. .base_path = "/spiffs",
  101. .partition_label = NULL,
  102. .max_files = 4,
  103. .format_if_mount_failed = true
  104. };
  105. void init_config(void)
  106. {
  107. reset_config();
  108. if (!esp_spiffs_mounted(spiffs_conf.partition_label))
  109. esp_vfs_spiffs_register(&spiffs_conf);
  110. FILE *f = fopen(CONFIG_FILE, "r");
  111. if (!f)
  112. return; /* No config file */
  113. read_config(f);
  114. fclose(f);
  115. }
  116. long getenv_l(const char *var, long def)
  117. {
  118. const char *ep;
  119. var = getenv(var);
  120. if (!var || !*var)
  121. return def;
  122. long val = strtol(var, (char **)&ep, 0);
  123. return *ep ? def : val;
  124. }
  125. void setenv_l(const char *var, long val)
  126. {
  127. char vbuf[2+3*sizeof val];
  128. snprintf(vbuf, sizeof vbuf, "%ld", val);
  129. setenv(var, vbuf, 1);
  130. }
  131. unsigned long getenv_ul(const char *var, unsigned long def)
  132. {
  133. const char *ep;
  134. var = getenv(var);
  135. if (!var || !*var)
  136. return def;
  137. unsigned long val = strtol(var, (char **)&ep, 0);
  138. return *ep ? def : val;
  139. }
  140. void setenv_ul(const char *var, unsigned long val)
  141. {
  142. char vbuf[2+3*sizeof val];
  143. snprintf(vbuf, sizeof vbuf, "%lu", val);
  144. setenv(var, vbuf, 1);
  145. }
  146. bool getenv_bool(const char *var)
  147. {
  148. var = getenv(var);
  149. if (!var)
  150. return false;
  151. unsigned char c = *var;
  152. unsigned char cl = c | 0x20;
  153. if (!c || c == '0' || cl == 'f' || cl == 'n' ||
  154. cl == 'o' && (var[1] | 0x20) == 'f')
  155. return false;
  156. else
  157. return true;
  158. }
  159. void setenv_bool(const char *var, bool val)
  160. {
  161. return setenv_ul(var, val);
  162. }