be smarter about detecting changes in loaded ini

work
Ondřej Hruška 7 years ago
parent 3e4181f18e
commit 0e6c297fe4
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      front-end
  2. 119
      user/cgi_persist.c
  3. 13
      user/config_xmacros.h

@ -1 +1 @@
Subproject commit a96b522ca899c687d70b9ad92f708cd416b8d460 Subproject commit c8305dea1a9ab38a13de442152c1fb9819bf68b1

@ -227,8 +227,12 @@ struct IniUpload {
bool term_ok; bool term_ok;
bool wifi_ok; bool wifi_ok;
bool sys_ok; bool sys_ok;
bool term_any;
bool wifi_any;
bool sys_any;
}; };
static void ICACHE_FLASH_ATTR iniCb(const char *section, const char *key, const char *value, void *userData) static void ICACHE_FLASH_ATTR iniCb(const char *section, const char *key, const char *value, void *userData)
{ {
HttpdConnData *connData = (HttpdConnData *)userData; HttpdConnData *connData = (HttpdConnData *)userData;
@ -241,31 +245,59 @@ static void ICACHE_FLASH_ATTR iniCb(const char *section, const char *key, const
// cgi_dbg("%s.%s = %s", section, key, value); // cgi_dbg("%s.%s = %s", section, key, value);
#define X XSET_ASSIGN /** used for INI */
#define X(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
bool suc = true; if (streq(#name, key)) { \
bool found = false; found = true; \
type *_p = (type *) &XSTRUCT->name; \
enum xset_result res = xset(#name, _p, value, (const void*) (xsarg)); \
if (res == XSET_SET) { changed = true; xnotify; } \
else if (res == XSET_FAIL) { ok = false; } \
break; \
}
// notify flag, unused here // notify flag, unused here
bool uart_changed = false; bool uart_changed = false;
bool found = false;
bool ok = true;
bool changed = false;
if (streq(section, "terminal")) { if (streq(section, "terminal")) {
do {
#define XSTRUCT termconf #define XSTRUCT termconf
XTABLE_TERMCONF XTABLE_TERMCONF
#undef XSTRUCT #undef XSTRUCT
if (!suc) state->term_ok = false; } while (0);
if (found) {
if (!ok) state->term_ok = false;
state->term_any |= changed;
}
} }
else if (streq(section, "wifi")) { else if (streq(section, "wifi")) {
do {
#define XSTRUCT wificonf #define XSTRUCT wificonf
XTABLE_WIFICONF XTABLE_WIFICONF
#undef XSTRUCT #undef XSTRUCT
if (!suc) state->wifi_ok = false; } while (0);
if (found) {
if (!ok) state->wifi_ok = false;
state->wifi_any |= changed;
}
} }
else if (streq(section, "system")) { else if (streq(section, "system")) {
do {
#define XSTRUCT sysconf #define XSTRUCT sysconf
XTABLE_SYSCONF XTABLE_SYSCONF
#undef XSTRUCT #undef XSTRUCT
if (!suc) state->sys_ok = false; } while (0);
if (found) {
if (!ok) state->sys_ok = false;
state->sys_any |= changed;
}
} }
if (!found) cgi_warn("Unknown key %s.%s!", section, key); if (!found) cgi_warn("Unknown key %s.%s!", section, key);
@ -294,16 +326,18 @@ postRecvHdl(HttpdConnData *connData, char *data, int len)
struct IniUpload *state = connData->cgiData; struct IniUpload *state = connData->cgiData;
if (!state) return HTTPD_CGI_DONE; if (!state) return HTTPD_CGI_DONE;
// Discard the boundary marker (there is only one)
char *bdr = connData->post->multipartBoundary;
char *foundat = strstr(data, bdr);
if (foundat != NULL) {
*foundat = '#'; // make it a comment
}
cgi_dbg("INI parse - postRecvHdl"); cgi_dbg("INI parse - postRecvHdl");
ini_parse(data, (size_t) len); if (len>0) {
// Discard the boundary marker (there is only one)
char *bdr = connData->post->multipartBoundary;
char *foundat = strstr(data, bdr);
if (foundat != NULL) {
*foundat = '#'; // make it a comment
}
ini_parse(data, (size_t) len);
}
cgi_dbg("Closing parser"); cgi_dbg("Closing parser");
ini_parse_end(); ini_parse_end();
@ -316,6 +350,7 @@ postRecvHdl(HttpdConnData *connData, char *data, int len)
if (tooLarge) cgi_warn("Bad term screen size!"); if (tooLarge) cgi_warn("Bad term screen size!");
bool suc = state->term_ok && state->wifi_ok && state->sys_ok; bool suc = state->term_ok && state->wifi_ok && state->sys_ok;
bool any = state->term_any || state->wifi_any || state->sys_any;
cgi_dbg("Evaluating results..."); cgi_dbg("Evaluating results...");
@ -330,22 +365,38 @@ postRecvHdl(HttpdConnData *connData, char *data, int len)
memcpy(sysconf, state->sys_backup, sizeof(SystemConfigBundle)); memcpy(sysconf, state->sys_backup, sizeof(SystemConfigBundle));
} }
else { else {
cgi_dbg("Applying terminal settings"); if (state->term_any) {
terminal_apply_settings(); cgi_dbg("Applying terminal settings");
cgi_dbg("Applying system settings"); terminal_apply_settings();
sysconf_apply_settings(); }
cgi_dbg("Applying WiFi settings (scheduling...)");
wifimgr_apply_settings_later(1000); if (state->sys_any) {
cgi_dbg("Applying system settings");
cgi_dbg("Persisting results"); sysconf_apply_settings();
persist_store(); }
if (state->wifi_any) {
cgi_dbg("Applying WiFi settings (scheduling...)");
wifimgr_apply_settings_later(2000);
}
if (any) {
cgi_dbg("Persisting results");
persist_store();
} else {
cgi_warn("Nothing written.");
}
} }
cgi_dbg("Redirect"); cgi_dbg("Redirect");
char buff[100]; char buff[100];
char *b = buff; char *b = buff;
if (suc) { if (suc) {
httpdRedirect(connData, SET_REDIR_SUC"?msg=Settings%20loaded%20and%20applied."); if (any) {
httpdRedirect(connData, SET_REDIR_SUC"?msg=Settings%20loaded%20and%20applied.");
} else {
httpdRedirect(connData, SET_REDIR_SUC"?msg=No%20settings%20changed.");
}
} else { } else {
b += sprintf(b, SET_REDIR_SUC"?errmsg=Errors%%20in:%%20"); b += sprintf(b, SET_REDIR_SUC"?errmsg=Errors%%20in:%%20");
bool comma = false; bool comma = false;
@ -423,6 +474,10 @@ cgiPersistImport(HttpdConnData *connData)
state->wifi_ok = true; state->wifi_ok = true;
state->term_ok = true; state->term_ok = true;
state->sys_any = false;
state->wifi_any = false;
state->term_any = false;
cgi_dbg("Parser starts!"); cgi_dbg("Parser starts!");
ini_parse_begin(iniCb, connData); ini_parse_begin(iniCb, connData);
@ -431,6 +486,14 @@ cgiPersistImport(HttpdConnData *connData)
connData->recvHdl = postRecvHdl; connData->recvHdl = postRecvHdl;
// special case for too short ini
int bytes_remain = connData->post->len;
bytes_remain -= connData->post->buffLen;
if (bytes_remain <= 0) {
return connData->recvHdl(connData, NULL, 0);
}
// continues in recvHdl // continues in recvHdl
return HTTPD_CGI_MORE; return HTTPD_CGI_MORE;
} }

@ -50,7 +50,8 @@ void xget_dhcp(char *buff, const struct dhcps_lease *value);
enum xset_result { enum xset_result {
XSET_FAIL = 0, XSET_FAIL = 0,
XSET_SET = 1, XSET_SET = 1,
XSET_UNCHANGED = 2 XSET_UNCHANGED = 2,
XSET_NONE = 3,
}; };
// Dummy for unimplemented setters // Dummy for unimplemented setters
@ -84,16 +85,6 @@ enum xset_result xset_ustring(const char *name, u8 *field, const char *buff, con
else if (res == XSET_FAIL) { redir_url += sprintf(redir_url, #name","); } \ else if (res == XSET_FAIL) { redir_url += sprintf(redir_url, #name","); } \
} }
/** used for INI */
#define XSET_ASSIGN(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
if (streq(#name, key)) { \
found = true; \
type *_p = (type *) &XSTRUCT->name; \
enum xset_result res = xset(#name, _p, value, (const void*) (xsarg)); \
if (res == XSET_SET) { xnotify; } \
else if (res == XSET_FAIL) { suc = false; } \
}
#define XGET_CGI_FUNC(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \ #define XGET_CGI_FUNC(type, name, suffix, deref, xget, xset, xsarg, xnotify, allow) \
if ((allow) && streq(token, #name)) xget(buff, deref XSTRUCT->name); if ((allow) && streq(token, #name)) xget(buff, deref XSTRUCT->name);

Loading…
Cancel
Save