source: src/router/httpd/modules/upgrade_x86.c @ 15245

Last change on this file since 15245 was 15245, checked in by BrainSlayer, 3 years ago

remove temp debug code

File size: 7.6 KB
Line 
1
2/*
3 * Broadcom Home Gateway Reference Design
4 * Web Page Configuration Support Routines
5 *
6 * Copyright 2001-2003, Broadcom Corporation
7 * All Rights Reserved.
8 *
9 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
10 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
11 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
12 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13 * $Id: upgrade.c,v 1.4 2005/11/30 11:53:42 seg Exp $
14 */
15
16#include <stdio.h>
17#include <string.h>
18#include <fcntl.h>
19#include <errno.h>
20#include <signal.h>
21#include <sys/stat.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <sys/wait.h>
25
26#include <broadcom.h>
27#include <cyutils.h>
28
29#define MIN_BUF_SIZE    4096
30#define CODE_PATTERN_ERROR 9999
31static int upgrade_ret;
32
33static int getdiscindex(void)   // works only for squashfs
34{
35        int i;
36
37        for (i = 0; i < 10; i++) {
38                char dev[64];
39
40                sprintf(dev, "/dev/discs/disc%d/part2", i);
41                FILE *in = fopen(dev, "rb");
42
43                if (in == NULL)
44                        continue;       // no second partition or disc does not
45                // exist, skipping
46                char buf[4];
47
48                fread(buf, 4, 1, in);
49                if (buf[0] == 'h' && buf[1] == 's' && buf[2] == 'q'
50                    && buf[3] == 't') {
51                        fclose(in);
52                        // filesystem detected
53                        return i;
54                }
55                fclose(in);
56        }
57        return -1;
58}
59
60void
61// do_upgrade_cgi(char *url, FILE *stream)
62do_upgrade_cgi(struct mime_handler *handler, char *url, webs_t stream, char *query)     // jimmy, https,
63                                                        // 8/6/2003
64{
65#ifndef ANTI_FLASH
66        fprintf(stderr, "do post\n");
67        if (upgrade_ret)
68                do_ej(handler, "Fail_u_s.asp", stream, NULL);
69        else
70                do_ej(handler, "Success_u_s.asp", stream, NULL);
71        fprintf(stderr, "websdone\n");
72
73        websDone(stream, 200);
74        fprintf(stderr, "reboot\n");
75
76        /*
77         * Reboot if successful
78         */
79        if (upgrade_ret == 0) {
80                sleep(4);
81                eval("umount", "/usr/local");
82                sys_reboot();
83        }
84#else
85        do_ej(handler, "Fail_u_s.asp", stream, NULL);
86        websDone(stream, 200);
87#endif
88}
89
90int
91// sys_upgrade(char *url, FILE *stream, int *total)
92sys_upgrade(char *url, webs_t stream, int *total, int type)     // jimmy,
93                                                                // https,
94                                                                // 8/6/2003
95{
96        lcdmessage("System Upgrade");
97#ifndef ANTI_FLASH
98        char upload_fifo[] = "/tmp/uploadXXXXXX";
99        FILE *fifo = NULL;
100        char *write_argv[4];
101        pid_t pid;
102        char *buf = NULL;
103        int count, ret = 0;
104        long flags = -1;
105        int size = BUFSIZ;
106        int i = 0;
107
108        {
109                write_argv[0] = "write";
110                write_argv[1] = upload_fifo;
111                write_argv[2] = "linux";
112                write_argv[3] = NULL;
113        }
114
115        // diag_led(DIAG, START_LED); // blink the diag led
116        C_led(1);
117#ifdef HAVE_HTTPS
118        if (do_ssl)
119                ACTION("ACT_WEBS_UPGRADE");
120        else
121#endif
122                ACTION("ACT_WEB_UPGRADE");
123
124        /*
125         * Feed write from a temporary FIFO
126         */
127        if (!mktemp(upload_fifo) || !(fifo = fopen(upload_fifo, "w"))) {
128                if (!ret)
129                        ret = errno;
130                goto err;
131        }
132
133        /*
134         * Set nonblock on the socket so we can timeout
135         */
136
137        /*
138         ** The buffer must be at least as big as what the stream file is
139         ** using so that it can read all the data that has been buffered
140         ** in the stream file. Otherwise it would be out of sync with fn
141         ** select specially at the end of the data stream in which case
142         ** the select tells there is no more data available but there in
143         ** fact is data buffered in the stream file's buffer. Since no
144         ** one has changed the default stream file's buffer size, let's
145         ** use the constant BUFSIZ until someone changes it.
146         **/
147
148        if (size < MIN_BUF_SIZE)
149                size = MIN_BUF_SIZE;
150        if ((buf = safe_malloc(size)) == NULL) {
151                ret = ENOMEM;
152                goto err;
153        }
154
155        /*
156         * Pipe the rest to the FIFO
157         */
158        cprintf("Upgrading\n");
159        // while (total && *total)
160        {
161                wfread(&buf[0], 1, 5, stream);
162                *total -= 5;
163                if (buf[0] != 'W' || buf[1] != 'R' || buf[2] != 'A'
164                    || buf[3] != 'P' || buf[4] != '1') {
165                        ret = -1;
166                        goto err;
167                }
168                int linuxsize;
169
170                wfread(&linuxsize, 1, 4, stream);
171                *total -= 4;
172                safe_fwrite(&linuxsize, 1, 4, fifo);
173                for (i = 0; i < linuxsize / MIN_BUF_SIZE; i++) {
174                        wfread(&buf[0], 1, MIN_BUF_SIZE, stream);
175                        fwrite(&buf[0], 1, MIN_BUF_SIZE, fifo);
176                }
177
178                wfread(&buf[0], 1, linuxsize % MIN_BUF_SIZE, stream);
179                fwrite(&buf[0], 1, linuxsize % MIN_BUF_SIZE, fifo);
180                *total -= linuxsize;
181
182        }
183        fclose(fifo);
184        fifo = NULL;
185        fifo = fopen(upload_fifo, "rb");
186        unsigned long linuxsize;
187
188        linuxsize = 0;
189        linuxsize += getc(fifo);
190        linuxsize += getc(fifo) * 256;
191        linuxsize += getc(fifo) * 256 * 256;
192        linuxsize += getc(fifo) * 256 * 256 * 256;
193        char dev[128];
194
195        // fprintf (stderr, "Write Linux %d to %s\n", linuxsize,dev);
196        char drive[64];
197        sprintf(drive, "/dev/discs/disc%d/disc", getdiscindex());
198        //backup nvram
199        fprintf(stderr, "backup nvram\n");
200        FILE *in = fopen("/usr/local/nvram/nvram.bin", "rb");
201        if (in) {
202                char *mem = malloc(65536);
203                fread(mem, 65536, 1, in);
204                fclose(in);
205                in = fopen(drive, "r+b");
206                fseek(in, 0, SEEK_END);
207                long mtdlen = ftell(in);
208                fseek(in, mtdlen-(65536*2), SEEK_SET);
209                fwrite(mem, 65536, 1, in);
210                fclose(in);
211                eval("sync");
212                in = fopen(drive, "rb");
213                fseek(in, mtdlen-(65536*2), SEEK_SET);
214                fread(mem, 65536, 1, in);
215                fclose(in);
216                free(mem);
217        }
218        fprintf(stderr, "write system\n");
219        FILE *out = fopen(drive, "r+b");
220        for (i = 0; i < linuxsize; i++)
221                putc(getc(fifo), out);
222        fclose(out);
223        fprintf(stderr, "sync system\n");
224
225        sysprintf("sync");
226        sysprintf("sync");
227        //reread for validation
228        fprintf(stderr, "check system for validation\n");
229        in = fopen(drive, "rb");
230        for (i = 0; i < linuxsize; i++)
231                getc(in);
232        fclose(in);
233        sysprintf("sync");
234        /*
235         * Wait for write to terminate
236         */
237        // waitpid (pid, &ret, 0);
238        cprintf("done\n");
239        ret = 0;
240err:
241        if (buf)
242                free(buf);
243        if (fifo)
244                fclose(fifo);
245        unlink(upload_fifo);
246
247        // diag_led(DIAG, STOP_LED);
248        // C_led (0);
249        fprintf(stderr, "Idle\n");
250        ACTION("ACT_IDLE");
251
252        return ret;
253#else
254        return 0;
255#endif
256}
257
258void
259// do_upgrade_post(char *url, FILE *stream, int len, char *boundary)
260do_upgrade_post(char *url, webs_t stream, int len, char *boundary)      // jimmy,
261                                                                        // https,
262                                                                        // 8/6/2003
263{
264
265        killall("udhcpc", SIGKILL);
266#ifndef ANTI_FLASH
267        char buf[1024];
268        int type = 0;
269
270        upgrade_ret = EINVAL;
271
272        // Let below files loaded to memory
273        // To avoid the successful screen is blank after web upgrade.
274
275        /*
276         * Look for our part
277         */
278        while (len > 0) {
279                if (!wfgets(buf, MIN(len + 1, sizeof(buf)), stream))
280                        return;
281                len -= strlen(buf);
282                if (!strncasecmp(buf, "Content-Disposition:", 20)) {
283                        if (strstr(buf, "name=\"erase\"")) {
284                                while (len > 0 && strcmp(buf, "\n")
285                                       && strcmp(buf, "\r\n")) {
286                                        if (!wfgets
287                                            (buf, MIN(len + 1, sizeof(buf)),
288                                             stream))
289                                                return;
290                                        len -= strlen(buf);
291                                }
292                                if (!wfgets
293                                    (buf, MIN(len + 1, sizeof(buf)), stream))
294                                        return;
295                                len -= strlen(buf);
296                                buf[1] = '\0';  // we only want the 1st digit
297                                nvram_set("sv_restore_defaults", buf);
298                                nvram_commit();
299                        } else if (strstr(buf, "name=\"file\""))        // upgrade image
300                        {
301                                type = 0;
302                                break;
303                        }
304                }
305        }
306
307        /*
308         * Skip boundary and headers
309         */
310        while (len > 0) {
311                if (!wfgets(buf, MIN(len + 1, sizeof(buf)), stream))
312                        return;
313                len -= strlen(buf);
314                if (!strcmp(buf, "\n") || !strcmp(buf, "\r\n"))
315                        break;
316        }
317        upgrade_ret = sys_upgrade(NULL, stream, &len, type);
318        fprintf(stderr, "core upgrade done() %d\n", len);
319        /*
320         * Restore factory original settings if told to. This will also cause a
321         * restore defaults on reboot of a Sveasoft firmware.
322         */
323        if (nvram_match("sv_restore_defaults", "1")) {
324                system2("rm -f /usr/local/nvram/nvram.bin");
325        }
326        /*
327         * Slurp anything remaining in the request
328         */
329        while (len--) {
330#ifdef HAVE_HTTPS
331                if (do_ssl) {
332                        wfgets(buf, 1, stream);
333                } else {
334                        (void)fgetc(stream);
335                }
336#else
337                (void)fgetc(stream);
338#endif
339
340        }
341#endif
342        fprintf(stderr, "upgrade done()\n");
343
344}
Note: See TracBrowser for help on using the repository browser.