diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 13:58:15 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 13:58:15 +0100 |
commit | 4aca87515a5083ae0e31ce3177189fd43b6d05ac (patch) | |
tree | 7b1d9a31393ca090757dc6f0d3859b4fcd93f271 /release/src/router/httpd/upgrade.c | |
parent | 008d0be72b2f160382c6e880765e96b64a050c65 (diff) | |
download | tomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.gz tomato-4aca87515a5083ae0e31ce3177189fd43b6d05ac.tar.bz2 |
patch to Vanilla Tomato 1.28
Diffstat (limited to 'release/src/router/httpd/upgrade.c')
-rw-r--r-- | release/src/router/httpd/upgrade.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/release/src/router/httpd/upgrade.c b/release/src/router/httpd/upgrade.c new file mode 100644 index 00000000..ce3e27c4 --- /dev/null +++ b/release/src/router/httpd/upgrade.c @@ -0,0 +1,153 @@ +/* + + Tomato Firmware + Copyright (C) 2006-2009 Jonathan Zarate + +*/ + +#include "tomato.h" + +#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/statfs.h> +#include <sys/wait.h> +#include <typedefs.h> +#include <sys/reboot.h> + +#if 1 +#define MTD_WRITE_CMD "mtd-write" +#else +#define DEBUG_TEST +#define MTD_WRITE_CMD "/tmp/mtd-write" +#endif + +void prepare_upgrade(void) +{ + int n; + + // stop non-essential stuff & free up some memory + exec_service("upgrade-start"); + for (n = 30; n > 0; --n) { + sleep(1); + if (nvram_match("action_service", "")) break; // this is cleared at the end + } + unlink("/var/log/messages"); + unlink("/var/log/messages.0"); + sync(); +} + +void wi_upgrade(char *url, int len, char *boundary) +{ + uint8 buf[1024]; + const char *error = "Error reading file"; + int ok = 0; + int n; + + check_id(url); + + // quickly check if JFFS2 is mounted by checking if /jffs/ is not squashfs + struct statfs sf; + if ((statfs("/jffs", &sf) != 0) || (sf.f_type != 0x73717368)) { + error = "JFFS2 is currently in use. Since an upgrade may overwrite the " + "JFFS2 partition, please backup the contents, disable JFFS2, then reboot the router"; + goto ERROR; + } + + // skip the rest of the header + if (!skip_header(&len)) goto ERROR; + + if (len < (1 * 1024 * 1024)) { + error = "Invalid file"; + goto ERROR; + } + + // -- anything after here ends in a reboot -- + + rboot = 1; + + led(LED_DIAG, 1); + + signal(SIGTERM, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + + prepare_upgrade(); + system("cp reboot.asp /tmp"); // copy to memory + + char fifo[] = "/tmp/flashXXXXXX"; + int pid = -1; + FILE *f = NULL; + + if ((mktemp(fifo) == NULL) || + (mkfifo(fifo, S_IRWXU) < 0)) { + error = "Unable to create a fifo"; + goto ERROR2; + } + + char *wargv[] = { MTD_WRITE_CMD, "-w", "-i", fifo, "-d", "linux", NULL }; + if (_eval(wargv, ">/tmp/.mtd-write", 0, &pid) != 0) { + error = "Unable to start flash program"; + goto ERROR2; + } + + if ((f = fopen(fifo, "w")) == NULL) { + error = "Unable to start pipe for mtd write"; + goto ERROR2; + } + + // !!! This will actually write the boundary. But since mtd-write + // uses trx length... -- zzz + + while (len > 0) { + if ((n = web_read(buf, MIN(len, sizeof(buf)))) <= 0) { + goto ERROR2; + } + len -= n; + if (safe_fwrite(buf, 1, n, f) != n) { + error = "Error writing to pipe"; + goto ERROR2; + } + } + + error = NULL; + ok = 1; + +ERROR2: + rboot = 1; + set_action(ACT_REBOOT); + + if (f) fclose(f); + if (pid != -1) waitpid(pid, &n, 0); + + resmsg_fread("/tmp/.mtd-write"); + + web_eat(len); + return; + +ERROR: + resmsg_set(error); + web_eat(len); +} + +void wo_flash(char *url) +{ + if (rboot) { + parse_asp("/tmp/reboot.asp"); + web_close(); + +#ifdef DEBUG_TEST + printf("\n\n -- reboot -- \n\n"); + set_action(ACT_IDLE); +#else + killall("pppoecd", SIGTERM); + sleep(2); + // kill(1, SIGTERM); + reboot(RB_AUTOBOOT); +#endif + exit(0); + } + + parse_asp("error.asp"); +} |