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

Last change on this file since 32568 was 32568, checked in by brainslayer, 2 weeks ago

remove obsolete query argument. informations can be obtained from path/url field. in addition fix some bugs

File size: 21.0 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[6];
405                                write_argv_buf[0] = "mtd";
406                                write_argv_buf[1] = "-f";
407                                write_argv_buf[2] = "write";
408                                write_argv_buf[3] = upload_fifo;
409                                write_argv_buf[4] = "linux";
410                                write_argv_buf[5] = NULL;
411                                char *bootpart_argv_buf[5];
412                                bootpart_argv_buf[0] = "ubootenv";
413                                bootpart_argv_buf[1] = "set";
414                                bootpart_argv_buf[2] = "boot_part";
415                                bootpart_argv_buf[3] = "1";
416                                bootpart_argv_buf[4] = NULL;
417
418                                char *part = getUEnv("boot_part");
419                                if (part) {
420                                        fprintf(stderr, "boot partiton is %s\n", part);
421                                        if (!strcmp(part, "2")) {
422                                        } else {
423                                                write_argv_buf[4] = "linux2";
424                                                bootpart_argv_buf[3] = "2";
425                                        }
426                                        fprintf(stderr, "flash to partition %s\n", write_argv_buf[4]);
427                                } else {
428                                        fprintf(stderr, "no boot partition info found\n");
429                                        ret = EINVAL;
430                                        goto err;
431                                }
432
433                                _evalpid(bootpart_argv_buf, NULL, 0, &pid);
434
435                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
436                                    || !(fifo = fopen(upload_fifo, "w"))) {
437                                        if (!ret)
438                                                ret = errno;
439                                        goto err;
440                                }
441                                goto write_data;
442                        }
443#endif
444#if defined(HAVE_DAP2230) || defined(HAVE_DAP2330) || defined(HAVE_DAP2660) || defined(HAVE_DAP3662) || defined(HAVE_DAP3320)
445#ifdef HAVE_DAP2660
446#define MAGIC "wapac09_dkbs_dap2660"
447#elif HAVE_DAP2330
448#define MAGIC "wapn24_dkbs_dap2330"
449#elif HAVE_DAP3662
450#define MAGIC "wapac11_dkbs_dap3662"
451#elif HAVE_DAP3320
452#define MAGIC "wapn29_dkbs_dap3320"
453#elif HAVE_DAP2230
454#define MAGIC "wapn31_dkbs_dap2230"
455#endif
456                        if (!strncmp(buf, MAGIC, strlen(MAGIC))) {
457                                char *write_argv_buf[8];
458                                write_argv_buf[0] = "mtd";
459                                write_argv_buf[1] = "-f";
460                                write_argv_buf[2] = "write";
461                                write_argv_buf[3] = upload_fifo;
462                                write_argv_buf[4] = "linux";
463                                write_argv_buf[5] = NULL;
464                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
465                                    || !(fifo = fopen(upload_fifo, "w"))) {
466                                        if (!ret)
467                                                ret = errno;
468                                        goto err;
469                                }
470                                goto write_data;
471                        }
472#endif
473#if defined(HAVE_BUFFALO) || defined(HAVE_IDEXX)
474                        ralink_firmware_header fh;
475                        memcpy(&fh, buf, sizeof(fh));
476                        char *str;
477                        str = (char *)&fh;
478                        unsigned char ch, temp;
479                        int idx, index;
480                        ch = 0xff;
481                        index = sizeof(fh) - 1;
482                        for (idx = 0; idx < sizeof(fh) / 2; idx++) {
483                                temp = str[idx];
484                                str[idx] = str[index - idx];
485                                str[index - idx] = temp;
486                        }
487                        for (idx = 0; idx < sizeof(fh); idx++)
488                                str[idx] ^= ch;
489                        if (!strncmp(buf, "bgn", 3) || !strncmp(buf, "WZR", 3)
490                            || !strncmp(buf, "WHR", 3)
491                            || !strncmp(buf, "WLA", 3)
492                            ) {
493                                char *write_argv_buf[4];
494                                write_argv_buf[0] = "buffalo_flash";
495                                write_argv_buf[1] = upload_fifo;
496#if defined(HAVE_IDEXX) || defined(HAVE_IDEXX_SIGNATUR)
497                                write_argv_buf[2] = "verify";
498                                write_argv_buf[3] = NULL;
499#else
500                                write_argv_buf[2] = NULL;
501#endif
502                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
503                                    || !(fifo = fopen(upload_fifo, "w"))) {
504                                        if (!ret)
505                                                ret = errno;
506                                        goto err;
507                                }
508                                goto write_data;
509                        } else if (!strncmp(fh.magic, "FIRMWARE", 8)) { // check for "FIRMWARE"
510                                char *write_argv_buf[4];
511                                write_argv_buf[0] = "buffalo_flash";
512                                write_argv_buf[1] = upload_fifo;
513                                write_argv_buf[2] = "ralink";
514#if defined(HAVE_IDEXX) || defined(HAVE_IDEXX_SIGNATUR)
515                                write_argv_buf[3] = "verify";
516                                write_argv_buf[4] = NULL;
517#else
518                                write_argv_buf[3] = NULL;
519#endif
520                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv_buf, NULL, 0, &pid))
521                                    || !(fifo = fopen(upload_fifo, "w"))) {
522                                        if (!ret)
523                                                ret = errno;
524                                        goto err;
525                                }
526                                goto write_data;
527                        } else {
528#ifdef HAVE_IDEXX_SIGNATUR
529                                goto err;
530#endif
531                                if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv, NULL, 0, &pid))
532                                    || !(fifo = fopen(upload_fifo, "w"))) {
533                                        if (!ret)
534                                                ret = errno;
535                                        goto err;
536                                }
537
538                        }
539
540#else
541                        /*
542                         * Feed write from a temporary FIFO
543                         */
544                        if (!mktemp(upload_fifo) || mkfifo(upload_fifo, S_IRWXU) < 0 || (ret = _evalpid(write_argv, NULL, 0, &pid)) || !(fifo = fopen(upload_fifo, "w"))) {
545                                if (!ret)
546                                        ret = errno;
547                                goto err;
548                        }
549#endif
550                        // have code pattern
551                        char ver[40];
552                        long ver1, ver2, ver3;
553                        snprintf(ver, sizeof(ver), "v%d.%d.%d", buf[11], buf[12], buf[13]);
554                        ver1 = convert_ver(ver);
555                        ver2 = convert_ver(INTEL_FLASH_SUPPORT_VERSION_FROM);
556                        ver3 = convert_ver(BCM4712_CHIP_SUPPORT_VERSION_FROM);
557                        fprintf(stderr, "upgrade_ver[%s] upgrade_ver[%ld] intel_ver[%ld] 4712_ver[%ld]\n", ver, ver1, ver2, ver3);
558#if defined(HAVE_WIKINGS) || defined(HAVE_ESPOD)
559#ifdef HAVE_WIKINGS
560#ifdef HAVE_SUB3
561#define V "XMED"
562#elif HAVE_SUB6
563#define V "XMIN"
564#else
565#define V "XMAX"
566#endif
567#endif
568#ifdef HAVE_ESPOD
569#ifdef HAVE_SUB3
570#define V "EPMN"
571#elif HAVE_SUB6
572#define V "EPMD"
573#else
574#define V "EPMX"
575#endif
576#endif
577                        if (memcmp(&buf[0], V, 4)) {
578                                fprintf(stderr, "code pattern error!\n");
579                                goto write_data;        // must be there, otherwise fail here
580                                //goto err;     // must be there, otherwise fail here
581                        }
582#undef V
583#endif
584
585#if defined(HAVE_WIKINGS) || defined(HAVE_ESPOD)
586#else
587#ifdef HAVE_WRT160NL
588                        if (memcmp(&buf[0], &CODE_PATTERN_WRT160NL, 4)
589                            && memcmp(&buf[0], &CODE_PATTERN_E2100L, 4)) {
590                                cprintf("code pattern error!\n");
591                                goto err;       // must be there, otherwise fail here
592                        }
593#else
594
595#ifndef HAVE_80211AC
596                        if (brand == ROUTER_LINKSYS_E1550 || (brand == ROUTER_WRT320N && nvram_match("boardrev", "0x1307"))     //E2000
597                            || brand == ROUTER_LINKSYS_E2500 || (brand == ROUTER_WRT610NV2 && nvram_match("boot_hw_model", "E300"))     //E3000
598                            || brand == ROUTER_LINKSYS_E3200 || brand == ROUTER_LINKSYS_E4200) {
599                                if (checkmagic(&buf[0], nv60k)) {
600                                        cprintf("image not compatible with nv60k router!\n");
601                                        goto err;       // must be there, otherwise fail here
602                                }
603                        } else if (brand == ROUTER_NETGEAR_WNDR4000 || brand == ROUTER_NETGEAR_WNDR3400 || brand == ROUTER_LINKSYS_E900 || brand == ROUTER_LINKSYS_E800 || brand == ROUTER_LINKSYS_E1500) {
604                                if (checkmagic(&buf[0], nv64k)) {
605                                        cprintf("image not compatible with nv64k router!\n");
606                                        goto err;       // must be there, otherwise fail here
607                                }
608                        } else {
609                                if (memcmp(&buf[0], &CODE_PATTERN_NV60K, 4) == 0 || memcmp(&buf[0], &CODE_PATTERN_NV64K, 4) == 0) {
610                                        cprintf("image not compatible with your router!\n");
611                                        goto err;       // fail here                           
612                                }
613                        }
614#endif
615                        if (checkmagic(&buf[0], allmagics)) {
616                                cprintf("code pattern error!\n");
617                                goto write_data;
618                        }
619#endif
620#endif
621
622                        if (check_hw_type() == BCM4712_CHIP && ver1 < ver3) {
623                                fprintf(stderr, "The old firmware version can't support bcm4712 chipset\n");
624                                fprintf(stderr, "Can't downgrade to this old firmware version (%s), must be above %s(included)\n", ver, BCM4712_CHIP_SUPPORT_VERSION_FROM);
625                                goto write_data;
626                        }
627
628                        fprintf(stderr, "code pattern correct!\n");
629                        *total -= count;
630#ifdef HAVE_WRT160NL
631                        safe_fwrite(buf, 1, count, fifo);       // we have to write the whole header to flash too
632#else
633                        safe_fwrite(&buf[sizeof(struct code_header)], 1, count - sizeof(struct code_header), fifo);
634                        if (fifo2)
635                                safe_fwrite(&buf[sizeof(struct code_header)], 1, count - sizeof(struct code_header), fifo2);
636#endif
637                        i++;
638                        continue;
639                }
640
641              write_data:
642                *total -= count;
643                safe_fwrite(buf, 1, count, fifo);
644                if (fifo2)
645                        safe_fwrite(buf, 1, count, fifo2);
646                uploadcount += count;
647                fprintf(stderr, "uploading [%d]\r", uploadcount);
648                if (lastblock)
649                        break;
650                i++;
651        }
652
653        fprintf(stderr, "uploading [%d]\n", uploadcount);
654        fclose(fifo);
655        if (fifo2)
656                fclose(fifo2);
657        fifo = NULL;
658        fifo2 = NULL;
659        /*
660         * Wait for write to terminate
661         */
662        waitpid(pid, &ret, 0);
663        cprintf("done\n");
664#ifdef HAVE_HTTPS
665        if (!stream->do_ssl) {
666#endif
667                /*
668                 * Reset nonblock on the socket
669                 */
670                if (fcntl(fileno(stream->fp), F_SETFL, flags) < 0) {
671                        ret = errno;
672                        goto err;
673                }
674#ifdef HAVE_HTTPS
675        }
676#endif
677
678err:
679        if (buf)
680                free(buf);
681        if (fifo)
682                fclose(fifo);
683        if (fifo2)
684                fclose(fifo2);
685        unlink(upload_fifo);
686        if (brand == ROUTER_ASROCK_G10) {
687                fprintf(stderr, "write secondary partition for asrock-g10\n");
688                eval("mtd", "-e", "linux2", "-f", "write", "/tmp/parttemp", "linux2");
689        }
690        // diag_led(DIAG, STOP_LED);
691        C_led(0);
692        ACTION("ACT_IDLE");
693        return ret;
694#else
695        return 0;
696#endif
697}
698
699void
700// do_upgrade_post(char *url, FILE *stream, int len, char *boundary)
701do_upgrade_post(char *url, webs_t stream, int len, char *boundary)      // jimmy,
702                                                                        // https,
703                                                                        // 8/6/2003
704{
705        killall("udhcpc", SIGKILL);
706
707#ifndef ANTI_FLASH
708        int type = 0;
709        char *buf = malloc(1024);
710        stream->upgrade_ret = EINVAL;
711
712        /*
713         * Look for our part
714         */
715        while (len > 0) {
716                if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
717                        free(buf);
718                        return;
719                }
720
721                len -= strlen(buf);
722                if (!strncasecmp(buf, "Content-Disposition:", 20)) {
723                        if (strstr(buf, "name=\"erase\"")) {
724                                while (len > 0 && strcmp(buf, "\n")
725                                       && strcmp(buf, "\r\n")) {
726                                        if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
727                                                free(buf);
728                                                return;
729                                        }
730
731                                        len -= strlen(buf);
732                                }
733                                if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
734                                        free(buf);
735                                        return;
736                                }
737                                len -= strlen(buf);
738                                buf[1] = '\0';  // we only want the 1st digit
739                                nvram_set("sv_restore_defaults", buf);
740                                nvram_commit();
741                        } else if (strstr(buf, "name=\"file\"")) {      // upgrade image
742                                type = 0;
743                                break;
744                        }
745                }
746        }
747
748        /*
749         * Skip boundary and headers
750         */
751        while (len > 0) {
752                if (!wfgets(buf, MIN(len + 1, 1024), stream)) {
753                        free(buf);
754                        return;
755                }
756
757                len -= strlen(buf);
758                if (!strcmp(buf, "\n") || !strcmp(buf, "\r\n"))
759                        break;
760        }
761        stream->upgrade_ret = sys_upgrade(NULL, stream, &len, type);
762
763        /*
764         * Restore factory original settings if told to. This will also cause a
765         * restore defaults on reboot of a Sveasoft firmware.
766         */
767#ifdef HAVE_BUFFALO_SA
768        int region_sa = 0;
769        if (nvram_default_match("region", "SA", ""))
770                region_sa = 1;
771#endif
772        if (nvram_matchi("sv_restore_defaults", 1)) {
773                eval("erase", "nvram");
774#ifdef HAVE_BUFFALO_SA
775                nvram_seti("sv_restore_defaults", 1);
776                if (region_sa)
777                        nvram_set("region", "SA");
778#endif
779        }
780        sys_commit();
781
782        /*
783         * Slurp anything remaining in the request
784         */
785
786        wfgets(buf, len, stream);
787        free(buf);
788#endif
789}
Note: See TracBrowser for help on using the repository browser.