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

Last change on this file since 32650 was 32650, checked in by brainslayer, 11 days ago

partition must be fully erased before flashing new firmware. otherwise ubifs will fail

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