source: src/router/httpd/modules/upgrade.c @ 31713

Last change on this file since 31713 was 31713, checked in by brainslayer, 6 weeks ago

take care about partition layout

File size: 19.3 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#include <shutils.h>
29#include <byteswap.h>
30#include <endian.h>             /* for __BYTE_ORDER */
31
32#if (__BYTE_ORDER == __LITTLE_ENDIAN)
33#  define HOST_TO_BE32(x)       bswap_32(x)
34#  define HOST_TO_BE16(x)       bswap_16(x)
35#else
36#  define HOST_TO_BE32(x)       (x)
37#  define HOST_TO_BE16(x)       (x)
38#endif
39
40#ifndef HAVE_MICRO
41#define MIN_BUF_SIZE    65536
42#else
43#define MIN_BUF_SIZE    4096
44#endif
45#define CODE_PATTERN_ERROR 9999
46static int upgrade_ret;
47
48void set_upgrade_ret(int result)
49{
50        if (result != 0) {
51                upgrade_ret = result;
52        } else {
53                upgrade_ret = NULL;
54        }
55}
56
57void
58// do_upgrade_cgi(char *url, FILE *stream)
59do_upgrade_cgi(struct mime_handler *handler, char *url, webs_t stream, char *query)     // jimmy, https,
60                                                        // 8/6/2003
61{
62#ifndef ANTI_FLASH
63
64        fprintf(stderr, "[UPGRADE] ret: %d\n", upgrade_ret);
65        if (upgrade_ret) {
66                do_ej(handler, "Fail_u_s.asp", stream, NULL);
67                killall("ledtool", SIGTERM);
68                led_control(LED_DIAG, LED_OFF);
69        } else {
70                do_ej(handler, "Success_u_s.asp", stream, NULL);
71        }
72        websDone(stream, 200);
73
74        /*
75         * Reboot if successful
76         */
77        if (upgrade_ret == 0) {
78                // sleep (10);
79                sys_reboot();
80        }
81#else
82
83        do_ej(handler, "Fail_u_s.asp", stream, NULL);
84        websDone(stream, 200);
85
86#endif
87}
88
89typedef struct {
90        char magic[8];          // "FIRMWARE"
91        char ver_inter[4];
92        char ver_outer[4];
93        char model[24];
94        unsigned int len;
95        unsigned int crc32;
96} ralink_firmware_header;
97
98static char *allmagics[] = {
99        CODE_PATTERN_WRT54G,
100        CODE_PATTERN_WRT54GS,
101        CODE_PATTERN_WRH54G,
102        CODE_PATTERN_WRT150N,
103        CODE_PATTERN_WRT160N,
104        CODE_PATTERN_WRT300N,
105        CODE_PATTERN_WRT300NV11,
106        CODE_PATTERN_WRT310N,
107        CODE_PATTERN_WRT350N,
108        CODE_PATTERN_WRTSL54GS,
109        CODE_PATTERN_WRT54G3G,
110        CODE_PATTERN_WRT54G3GV,
111        CODE_PATTERN_WRT610N,
112        CODE_PATTERN_WRT54GSV4,
113        CODE_PATTERN_WRT320N,
114        CODE_PATTERN_VALET_M10,
115        CODE_PATTERN_VALET_M20,
116        CODE_PATTERN_E900,
117        CODE_PATTERN_E800,
118        CODE_PATTERN_E1000,
119        CODE_PATTERN_E1200V1,
120        CODE_PATTERN_E1200V2,
121        CODE_PATTERN_E1500,
122        CODE_PATTERN_E1550,
123        CODE_PATTERN_E2000,
124        CODE_PATTERN_E2500,
125        CODE_PATTERN_E3000,
126        CODE_PATTERN_E3200,
127        CODE_PATTERN_E4200,
128        CODE_PATTERN_NV60K,
129        CODE_PATTERN_NV64K,
130        NULL
131};
132
133static char *nv60k[] = {
134        CODE_PATTERN_E1550,
135        CODE_PATTERN_E2000,
136        CODE_PATTERN_E2500,
137        CODE_PATTERN_E3000,
138        CODE_PATTERN_E3200,
139        CODE_PATTERN_E4200,
140        CODE_PATTERN_NV60K,
141        NULL
142};
143
144static char *nv64k[] = {
145        CODE_PATTERN_E900,
146        CODE_PATTERN_E800,
147        CODE_PATTERN_E1200V1,
148        CODE_PATTERN_E1200V2,
149        CODE_PATTERN_E1500,
150        CODE_PATTERN_NV64K,
151        NULL
152};
153
154static int checkmagic(char *magic, char *check[])
155{
156        int cnt = 0;
157        while (check[cnt]) {
158                if (!memcmp(magic, check[cnt], 4))
159                        return 0;
160                cnt++;
161        }
162        return -1;
163}
164
165int
166// sys_upgrade(char *url, FILE *stream, int *total)
167sys_upgrade(char *url, webs_t stream, int *total, int type)     // jimmy,
168                                                                // https,
169                                                                // 8/6/2003
170{
171
172        int brand = getRouterBrand();
173
174#ifndef ANTI_FLASH
175        char upload_fifo[] = "/tmp/uploadXXXXXX";
176        FILE *fifo = NULL;
177        char *write_argv[4];
178        pid_t pid;
179        char *buf = NULL;
180        int count, ret = 0;
181        long flags = -1;
182        int size = BUFSIZ;
183        int i = 0;
184#if (defined(HAVE_FONERA) || defined(HAVE_WHRAG108) || defined(HAVE_MERAKI) || defined(HAVE_TW6600) || defined(HAVE_PB42) || defined(HAVE_LS5) || defined(HAVE_USR5453)) && \
185(!defined(HAVE_DIR400) && !defined(HAVE_WRT54G2) && !defined(HAVE_GWMF54G2) && !defined(HAVE_FONERA2200) && !defined(HAVE_MR3202A) && !defined(HAVE_CA8PRO) &&  \
186!defined(HAVE_CA8) && !defined(HAVE_RT2880) && !defined(HAVE_LS2) && !defined(HAVE_WRK54G) && !defined(HAVE_ADM5120) && !defined(HAVE_DIR300) && !defined(HAVE_DLM101) && \
187!defined(HAVE_MERAKI) && !defined(HAVE_SOLO51) && !defined(HAVE_RTG32) && !defined(HAVE_EOC5610) && !defined(HAVE_NP25G))
188#define WRITEPART "rootfs"
189#else
190#define WRITEPART "linux"
191#endif
192
193        write_argv[0] = "write";
194        write_argv[1] = upload_fifo;
195        write_argv[2] = WRITEPART;
196        write_argv[3] = NULL;
197        eval("fischecksum");
198        if (url)
199                return eval("write", url, WRITEPART);
200        // diag_led(DIAG, START_LED); // blink the diag led
201        C_led(1);
202#ifdef HAVE_HTTPS
203        if (do_ssl)
204                ACTION("ACT_WEBS_UPGRADE");
205        else
206#endif
207                ACTION("ACT_WEB_UPGRADE");
208        int uploadcount = 0;
209
210        /*
211         * Set nonblock on the socket so we can timeout
212         */
213#ifdef HAVE_HTTPS
214        if (!do_ssl) {
215#endif
216                if ((flags = fcntl(fileno(stream->fp), F_GETFL)) < 0 || fcntl(fileno(stream->fp), F_SETFL, flags | O_NONBLOCK) < 0) {
217                        ret = errno;
218                        goto err;
219                }
220#ifdef HAVE_HTTPS
221        }
222#endif
223
224        /*
225         ** The buffer must be at least as big as what the stream file is
226         ** using so that it can read all the data that has been buffered
227         ** in the stream file. Otherwise it would be out of sync with fn
228         ** select specially at the end of the data stream in which case
229         ** the select tells there is no more data available but there in
230         ** fact is data buffered in the stream file's buffer. Since no
231         ** one has changed the default stream file's buffer size, let's
232         ** use the constant BUFSIZ until someone changes it.
233         **/
234
235        if (size < MIN_BUF_SIZE)
236                size = MIN_BUF_SIZE;
237        fprintf(stderr, "use buffer size %d\n", size);
238        if ((buf = safe_malloc(size)) == NULL) {
239                ret = ENOMEM;
240                goto err;
241        }
242        eval("ledtool", "500");
243        /*
244         * Pipe the rest to the FIFO
245         */
246        cprintf("Upgrading\n");
247        int lastblock = 0;
248        while (total && *total) {
249#ifdef HAVE_HTTPS
250                if (do_ssl) {
251                        if (size > *total)
252                                size = *total;
253                        count = wfread(buf, 1, size, stream);
254                } else
255#endif
256                {
257                        if (waitfor(fileno(stream->fp), 5) <= 0) {
258                                lastblock = 1;
259                        }
260                        count = safe_fread(buf, 1, size, stream->fp);
261                        if (!count && (ferror(stream->fp) || feof(stream->fp))) {
262                                break;
263                        }
264                }
265
266                if (i == 0) {   // check code pattern, the first data must
267#ifdef HAVE_VENTANA
268                        if (!strncmp(buf, "UBI#", 4)) { // check for "UBI#"
269                                eval("mount", "-o", "remount,ro", "/");
270                                char *write_argv_buf[8];
271                                fprintf(stderr, "erase nandflash\n");
272                                eval("mtd", "erase", "rootfs");
273                                sleep(10);
274                                write_argv_buf[0] = "mtd";
275                                write_argv_buf[1] = "-f";
276                                write_argv_buf[2] = "write";
277                                write_argv_buf[3] = upload_fifo;
278                                write_argv_buf[4] = "rootfs";
279                                write_argv_buf[5] = NULL;
280                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
281                                    || !(fifo = fopen(upload_fifo, "w"))) {
282                                        if (!ret)
283                                                ret = errno;
284                                        goto err;
285                                }
286                                goto write_data;
287                        }
288#endif
289//0x1200000 0x70000 RN67
290#ifdef HAVE_IPQ806X
291
292#define _WEB_HEADER_ "RN67"
293#define FW_HEADER                       ((char *)"CSYS")
294#define DWORD_SWAP(v)   ((((v&0xff)<<24)&0xff000000) | \
295                                                ((((v>>8)&0xff)<<16)&0xff0000) | \
296                                                ((((v>>16)&0xff)<<8)&0xff00) | \
297                                                (((v>>24)&0xff)&0xff) )
298
299                        typedef struct img_header {
300                                unsigned char signature[4];
301                                unsigned int startAddr __attribute__((packed));
302                                unsigned int burnAddr __attribute__((packed));
303                                unsigned char modTag[4];
304                                unsigned int len __attribute__((packed));
305                        } __attribute__((packed)) img_header_t;
306                        if (brand == ROUTER_ASROCK_G10) {
307                                img_header_t *header = (img_header_t *) buf;
308                                if (!memcmp(header->signature, FW_HEADER, 4) && !memcmp(header->modTag, _WEB_HEADER_, 4)) {
309                                        char *mtd = "linux";
310                                        fprintf(stderr, "found valid ASROCK-G10 Image\n");
311                                        if (nvram_matchi("bootpartition", 0)) {
312                                                mtd = "linux2";
313                                                eval("startservice", "bootsecondary");
314                                        } else {
315                                                eval("startservice", "bootprimary");
316                                        }
317
318                                        sysprintf("startservice finishupgrade");
319                                        count -= sizeof(struct img_header);
320                                        memcpy(buf, buf + sizeof(struct img_header), count);
321                                        char *write_argv_buf[8];
322                                        write_argv_buf[0] = "mtd";
323                                        write_argv_buf[1] = "-e";
324                                        write_argv_buf[2] = mtd;
325                                        write_argv_buf[3] = "-f";
326                                        write_argv_buf[4] = "write";
327                                        write_argv_buf[5] = upload_fifo;
328                                        write_argv_buf[6] = mtd;
329                                        write_argv_buf[7] = NULL;
330                                        if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
331                                            || !(fifo = fopen(upload_fifo, "w"))) {
332                                                if (!ret)
333                                                        ret = errno;
334                                                goto err;
335                                        }
336                                        goto write_data;
337                                }
338                        }
339#endif
340#if defined(HAVE_DIR860) || defined(HAVE_DIR859)
341#define SEAMA_MAGIC             0x5EA3A417
342
343                        typedef struct seama_hdr seamahdr_t;
344                        struct seama_hdr {
345                                unsigned int magic;     /* should always be SEAMA_MAGIC. */
346                                unsigned short reserved;        /* reserved for  */
347                                unsigned short metasize;        /* size of the META data */
348                                unsigned int size;      /* size of the image */
349                        } __attribute__((packed));
350                        seamahdr_t *seama = (seamahdr_t *) buf;
351
352                        if (seama->magic == HOST_TO_BE32(SEAMA_MAGIC)) {
353                                unsigned int skip = HOST_TO_BE16(seama->metasize) + sizeof(seamahdr_t);
354                                fprintf(stderr, "found seama header, skip seal header of %d bytes\n", skip);
355                                if (skip > count)
356                                        goto err;
357#ifdef HAVE_DIR869
358#define signature "signature=wrgac54_dlink.2015_dir869"
359#elif HAVE_DIR859
360#define signature "signature=wrgac37_dlink.2013gui_dir859"
361#else
362#define signature "signature=wrgac13_dlink.2013gui_dir860lb"
363#endif
364                                if (memcmp(buf + sizeof(seamahdr_t), signature, sizeof(signature))) {
365                                        fprintf(stderr, "firmware signature must be %s\n", signature);
366                                        goto err;
367                                }
368
369                                count -= skip;
370                                memcpy(buf, buf + skip, count);
371                                char *write_argv_buf[8];
372                                write_argv_buf[0] = "mtd";
373                                write_argv_buf[1] = "-f";
374                                write_argv_buf[2] = "write";
375                                write_argv_buf[3] = upload_fifo;
376                                write_argv_buf[4] = "linux";
377                                write_argv_buf[5] = NULL;
378                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
379                                    || !(fifo = fopen(upload_fifo, "w"))) {
380                                        if (!ret)
381                                                ret = errno;
382                                        goto err;
383                                }
384                                goto write_data;
385
386                        }
387#endif
388#if defined(HAVE_DIR862)
389                        unsigned int *uboot_magic = (unsigned int *)buf;
390                        if (*uboot_magic == HOST_TO_BE32(0x27051956)) {
391                                char *write_argv_buf[8];
392                                write_argv_buf[0] = "mtd";
393                                write_argv_buf[1] = "-f";
394                                write_argv_buf[2] = "write";
395                                write_argv_buf[3] = upload_fifo;
396                                write_argv_buf[4] = "linux";
397                                write_argv_buf[5] = NULL;
398                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
399                                    || !(fifo = fopen(upload_fifo, "w"))) {
400                                        if (!ret)
401                                                ret = errno;
402                                        goto err;
403                                }
404                                goto write_data;
405                        }
406#endif
407#if defined(HAVE_DAP2230) || defined(HAVE_DAP2330) || defined(HAVE_DAP2660) || defined(HAVE_DAP3662) || defined(HAVE_DAP3320)
408#ifdef HAVE_DAP2660
409#define MAGIC "wapac09_dkbs_dap2660"
410#elif HAVE_DAP2330
411#define MAGIC "wapn24_dkbs_dap2330"
412#elif HAVE_DAP3662
413#define MAGIC "wapac11_dkbs_dap3662"
414#elif HAVE_DAP3320
415#define MAGIC "wapn29_dkbs_dap3320"
416#elif HAVE_DAP2230
417#define MAGIC "wapn31_dkbs_dap2230"
418#endif
419                        if (!strncmp(buf, MAGIC, strlen(MAGIC))) {
420                                char *write_argv_buf[8];
421                                write_argv_buf[0] = "mtd";
422                                write_argv_buf[1] = "-f";
423                                write_argv_buf[2] = "write";
424                                write_argv_buf[3] = upload_fifo;
425                                write_argv_buf[4] = "linux";
426                                write_argv_buf[5] = NULL;
427                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
428                                    || !(fifo = fopen(upload_fifo, "w"))) {
429                                        if (!ret)
430                                                ret = errno;
431                                        goto err;
432                                }
433                                goto write_data;
434                        }
435#endif
436#if defined(HAVE_BUFFALO) || defined(HAVE_IDEXX)
437                        ralink_firmware_header fh;
438                        memcpy(&fh, buf, sizeof(fh));
439                        char *str;
440                        str = (char *)&fh;
441                        unsigned char ch, temp;
442                        int idx, index;
443                        ch = 0xff;
444                        index = sizeof(fh) - 1;
445                        for (idx = 0; idx < sizeof(fh) / 2; idx++) {
446                                temp = str[idx];
447                                str[idx] = str[index - idx];
448                                str[index - idx] = temp;
449                        }
450                        for (idx = 0; idx < sizeof(fh); idx++)
451                                str[idx] ^= ch;
452                        if (!strncmp(buf, "bgn", 3) || !strncmp(buf, "WZR", 3)
453                            || !strncmp(buf, "WHR", 3)
454                            || !strncmp(buf, "WLA", 3)
455                            ) {
456                                char *write_argv_buf[4];
457                                write_argv_buf[0] = "buffalo_flash";
458                                write_argv_buf[1] = upload_fifo;
459#if defined(HAVE_IDEXX) || defined(HAVE_IDEXX_SIGNATUR)
460                                write_argv_buf[2] = "verify";
461                                write_argv_buf[3] = NULL;
462#else
463                                write_argv_buf[2] = NULL;
464#endif
465                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
466                                    || !(fifo = fopen(upload_fifo, "w"))) {
467                                        if (!ret)
468                                                ret = errno;
469                                        goto err;
470                                }
471                                goto write_data;
472                        } else if (!strncmp(fh.magic, "FIRMWARE", 8)) { // check for "FIRMWARE"
473                                char *write_argv_buf[4];
474                                write_argv_buf[0] = "buffalo_flash";
475                                write_argv_buf[1] = upload_fifo;
476                                write_argv_buf[2] = "ralink";
477#if defined(HAVE_IDEXX) || defined(HAVE_IDEXX_SIGNATUR)
478                                write_argv_buf[3] = "verify";
479                                write_argv_buf[4] = NULL;
480#else
481                                write_argv_buf[3] = NULL;
482#endif
483                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
484                                    || !(fifo = fopen(upload_fifo, "w"))) {
485                                        if (!ret)
486                                                ret = errno;
487                                        goto err;
488                                }
489                                goto write_data;
490                        } else {
491#ifdef HAVE_IDEXX_SIGNATUR
492                                goto err;
493#endif
494                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv, NULL, 0, &pid))
495                                    || !(fifo = fopen(upload_fifo, "w"))) {
496                                        if (!ret)
497                                                ret = errno;
498                                        goto err;
499                                }
500
501                        }
502
503#else
504                        /*
505                         * Feed write from a temporary FIFO
506                         */
507                        if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv, NULL, 0, &pid)) || !(fifo = fopen(upload_fifo, "w"))) {
508                                if (!ret)
509                                        ret = errno;
510                                goto err;
511                        }
512#endif
513                        // have code pattern
514                        char ver[40];
515                        long ver1, ver2, ver3;
516                        snprintf(ver, sizeof(ver), "v%d.%d.%d", buf[11], buf[12], buf[13]);
517                        ver1 = convert_ver(ver);
518                        ver2 = convert_ver(INTEL_FLASH_SUPPORT_VERSION_FROM);
519                        ver3 = convert_ver(BCM4712_CHIP_SUPPORT_VERSION_FROM);
520                        fprintf(stderr, "upgrade_ver[%s] upgrade_ver[%ld] intel_ver[%ld] 4712_ver[%ld]\n", ver, ver1, ver2, ver3);
521#if defined(HAVE_WIKINGS) || defined(HAVE_ESPOD)
522#ifdef HAVE_WIKINGS
523#ifdef HAVE_SUB3
524#define V "XMED"
525#elif HAVE_SUB6
526#define V "XMIN"
527#else
528#define V "XMAX"
529#endif
530#endif
531#ifdef HAVE_ESPOD
532#ifdef HAVE_SUB3
533#define V "EPMN"
534#elif HAVE_SUB6
535#define V "EPMD"
536#else
537#define V "EPMX"
538#endif
539#endif
540                        if (memcmp(&buf[0], V, 4)) {
541                                fprintf(stderr, "code pattern error!\n");
542                                goto write_data;        // must be there, otherwise fail here
543                                //goto err;     // must be there, otherwise fail here
544                        }
545#undef V
546#endif
547
548#if defined(HAVE_WIKINGS) || defined(HAVE_ESPOD)
549#else
550#ifdef HAVE_WRT160NL
551                        if (memcmp(&buf[0], &CODE_PATTERN_WRT160NL, 4)
552                            && memcmp(&buf[0], &CODE_PATTERN_E2100L, 4)) {
553                                cprintf("code pattern error!\n");
554                                goto err;       // must be there, otherwise fail here
555                        }
556#else
557
558#ifndef HAVE_80211AC
559                        if (brand == ROUTER_LINKSYS_E1550 || (brand == ROUTER_WRT320N && nvram_match("boardrev", "0x1307"))     //E2000
560                            || brand == ROUTER_LINKSYS_E2500 || (brand == ROUTER_WRT610NV2 && nvram_match("boot_hw_model", "E300"))     //E3000
561                            || brand == ROUTER_LINKSYS_E3200 || brand == ROUTER_LINKSYS_E4200) {
562                                if (checkmagic(&buf[0], nv60k)) {
563                                        cprintf("image not compatible with nv60k router!\n");
564                                        goto err;       // must be there, otherwise fail here
565                                }
566                        } else if (brand == ROUTER_NETGEAR_WNDR4000 || brand == ROUTER_NETGEAR_WNDR3400 || brand == ROUTER_LINKSYS_E900 || brand == ROUTER_LINKSYS_E800 || brand == ROUTER_LINKSYS_E1500) {
567                                if (checkmagic(&buf[0], nv64k)) {
568                                        cprintf("image not compatible with nv64k router!\n");
569                                        goto err;       // must be there, otherwise fail here
570                                }
571                        } else {
572                                if (memcmp(&buf[0], &CODE_PATTERN_NV60K, 4) == 0 || memcmp(&buf[0], &CODE_PATTERN_NV64K, 4) == 0) {
573                                        cprintf("image not compatible with your router!\n");
574                                        goto err;       // fail here                           
575                                }
576                        }
577#endif
578                        if (checkmagic(&buf[0], allmagics)) {
579                                cprintf("code pattern error!\n");
580                                goto write_data;
581                        }
582#endif
583#endif
584
585                        if (check_hw_type() == BCM4712_CHIP && ver1 < ver3) {
586                                fprintf(stderr, "The old firmware version can't support bcm4712 chipset\n");
587                                fprintf(stderr, "Can't downgrade to this old firmware version (%s), must be above %s(included)\n", ver, BCM4712_CHIP_SUPPORT_VERSION_FROM);
588                                goto write_data;
589                        }
590
591                        fprintf(stderr, "code pattern correct!\n");
592                        *total -= count;
593#ifdef HAVE_WRT160NL
594                        safe_fwrite(buf, 1, count, fifo);       // we have to write the whole header to flash too
595#else
596                        safe_fwrite(&buf[sizeof(struct code_header)], 1, count - sizeof(struct code_header), fifo);
597#endif
598                        i++;
599                        continue;
600                }
601
602              write_data:
603                *total -= count;
604                safe_fwrite(buf, 1, count, fifo);
605                uploadcount += count;
606                fprintf(stderr, "uploading [%d]\r", uploadcount);
607                if (lastblock)
608                        break;
609                i++;
610        }
611
612        fprintf(stderr, "uploading [%d]\n", uploadcount);
613        fclose(fifo);
614        fifo = NULL;
615        /*
616         * Wait for write to terminate
617         */
618        waitpid(pid, &ret, 0);
619        cprintf("done\n");
620#ifdef HAVE_HTTPS
621        if (!do_ssl) {
622#endif
623                /*
624                 * Reset nonblock on the socket
625                 */
626                if (fcntl(fileno(stream->fp), F_SETFL, flags) < 0) {
627                        ret = errno;
628                        goto err;
629                }
630#ifdef HAVE_HTTPS
631        }
632#endif
633
634err:
635        if (buf)
636                free(buf);
637        if (fifo)
638                fclose(fifo);
639        unlink(upload_fifo);
640        // diag_led(DIAG, STOP_LED);
641        C_led(0);
642        ACTION("ACT_IDLE");
643        return ret;
644#else
645        return 0;
646#endif
647}
648
649void
650// do_upgrade_post(char *url, FILE *stream, int len, char *boundary)
651do_upgrade_post(char *url, webs_t stream, int len, char *boundary)      // jimmy,
652                                                                        // https,
653                                                                        // 8/6/2003
654{
655        killall("udhcpc", SIGKILL);
656
657#ifndef ANTI_FLASH
658        int type = 0;
659        char *buf = malloc(1024);
660        upgrade_ret = EINVAL;
661
662        /*
663         * Look for our part
664         */
665        while (len > 0) {
666                if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
667                        free(buf);
668                        return;
669                }
670
671                len -= strlen(buf);
672                if (!strncasecmp(buf, "Content-Disposition:", 20)) {
673                        if (strstr(buf, "name=\"erase\"")) {
674                                while (len > 0 && strcmp(buf, "\n")
675                                       && strcmp(buf, "\r\n")) {
676                                        if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
677                                                free(buf);
678                                                return;
679                                        }
680
681                                        len -= strlen(buf);
682                                }
683                                if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
684                                        free(buf);
685                                        return;
686                                }
687                                len -= strlen(buf);
688                                buf[1] = '\0';  // we only want the 1st digit
689                                nvram_set("sv_restore_defaults", buf);
690                                nvram_commit();
691                        } else if (strstr(buf, "name=\"file\"")) {      // upgrade image
692                                type = 0;
693                                break;
694                        }
695                }
696        }
697
698        /*
699         * Skip boundary and headers
700         */
701        while (len > 0) {
702                if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
703                        free(buf);
704                        return;
705                }
706
707                len -= strlen(buf);
708                if (!strcmp(buf, "\n") || !strcmp(buf, "\r\n"))
709                        break;
710        }
711
712        upgrade_ret = sys_upgrade(NULL, stream, &len, type);
713
714        /*
715         * Restore factory original settings if told to. This will also cause a
716         * restore defaults on reboot of a Sveasoft firmware.
717         */
718#ifdef HAVE_BUFFALO_SA
719        int region_sa = 0;
720        if (nvram_default_match("region", "SA", ""))
721                region_sa = 1;
722#endif
723        if (nvram_matchi("sv_restore_defaults", 1)) {
724                eval("erase", "nvram");
725#ifdef HAVE_BUFFALO_SA
726                nvram_seti("sv_restore_defaults", 1);
727                if (region_sa)
728                        nvram_set("region", "SA");
729#endif
730        }
731        sys_commit();
732
733        /*
734         * Slurp anything remaining in the request
735         */
736
737        wfgets(buf, len, stream);
738        free(buf);
739#endif
740}
Note: See TracBrowser for help on using the repository browser.