tools: drop unused upslug2 and wrt350nv2-builder
[openwrt/staging/rmilecki.git] / tools / wrt350nv2-builder / src / wrt350nv2-builder.c
diff --git a/tools/wrt350nv2-builder/src/wrt350nv2-builder.c b/tools/wrt350nv2-builder/src/wrt350nv2-builder.c
deleted file mode 100644 (file)
index 36f0587..0000000
+++ /dev/null
@@ -1,1127 +0,0 @@
-/*
-
-       WRT350Nv2-Builder 2.4 (previously called buildimg)
-       Copyright (C) 2008-2009 Dirk Teurlings <info@upexia.nl>
-       Copyright (C) 2009-2011 Matthias Buecher (http://www.maddes.net/)
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; either version 2 of the License, or
-       (at your option) any later version.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-       A lot of thanks to Kaloz and juhosg from OpenWRT and Lennert Buytenhek from
-       marvell for helping me figure this one out. This code is based on bash
-       scripts wrote by Peter van Valderen so the real credit should go to him.
-
-       This program reads the provided parameter file and creates an image which can
-       be used to flash a Linksys WRT350N v2 from stock firmware.
-       The trick is to fill unused space in the bin file with random, so that the
-       resulting zip file passes the size check of the stock firmware.
-
-       The parameter file layout for an original Linksys firmware:
-               :kernel 0x001A0000      /path/to/uImage
-               :rootfs 0       /path/to/root.squashfs
-               :u-boot 0       /path/to/u-boot.bin
-               #version        0x2020
-
-       Additionally since v2.4 an already complete image can be used:
-               :image          0       /path/to/openwrt-wrt350nv2-[squashfs|jffs2-64k].img
-
-       args:
-               1       wrt350nv2.par           parameter file describing the image layout
-               2       wrt350nv2.img           output file for linksys style image
-
-       A u-boot image inside the bin file is not necessary.
-       The version is not important.
-       The name of the bin file is not important, but still "wrt350n.bin" is used to
-       keep as close as possible to the stock firmware.
-
-       Linksys assumes that no mtd will be used to its maximum, so the last 16 bytes
-       of the mtd are abused to define the length of the next mtd content (4 bytes for
-       size + 12 pad bytes).
-
-       At the end of "rootfs" additional 16 bytes are abused for some data and a
-       highly important eRcOmM identifier, so the last 32 bytes of "rootfs" are abused.
-
-       At the end of "u-boot" 128 bytes are abused for some data, a checksum and a
-       highly important sErCoMm identifier.
-
-
-       This program uses a special GNU scanf modifier to allocate
-       sufficient memory for a strings with unknown length.
-       See http://www.kernel.org/doc/man-pages/online/pages/man3/scanf.3.html#NOTES
-
-
-       To extract everything from a Linksys style firmware image see
-       https://forum.openwrt.org/viewtopic.php?pid=92928#p92928
-
-       Changelog:
-       v2.4 - added ":image" definition for parameter file, this allows
-              to use a complete sysupgrade image without any kernel size check
-       v2.3 - allow jffs by adding its magic number (0x8519)
-              added parameter option -i to ignore unknown magic numbers
-       v2.2 - fixed checksum byte calculation for other versions than 0x2019
-              fixed rare problem with padsize
-              updated info to stock firmware 2.00.20
-              fixed typos
-       v2.1 - used "wrt350n.bin" for the created image (closer to stock)
-               added option to create the image in two separate steps (-b / -z)
-       v2.0 - complete re-write
-
-*/
-
-// includes
-#define _GNU_SOURCE    // for GNU's basename()
-#include <assert.h>
-#include <errno.h>     // errno
-#include <stdarg.h>
-#include <stdio.h>     // fopen(), fread(), fclose(), etc.
-#include <stdlib.h>    // system(), etc.
-#include <string.h>    // basename(), strerror(), strdup(), etc.
-#include <unistd.h>    // optopt(), access(), etc.
-#include <libgen.h>
-#include <sys/wait.h>  // WEXITSTATUS, etc.
-
-// custom includes
-#include "md5.h"       // MD5 routines
-#include "upgrade.h"   // Linksys definitions from firmware 2.0.19 (unchanged up to 2.0.20)
-
-
-// version info
-#define VERSION "2.4"
-char program_info[] = "WRT350Nv2-Builder v%s by Dirk Teurlings <info@upexia.nl> and Matthias Buecher (http://www.maddes.net/)\n";
-
-// verbosity
-#define DEBUG 1
-#define DEBUG_LVL2 2
-int verbosity = 0;
-
-// mtd info
-typedef struct {
-       char *name;
-       int offset;
-       int size;
-       char *filename;
-       long int filesize;
-       unsigned char magic[2];
-} mtd_info;
-
-mtd_info mtd_kernel = { "kernel", 0, 0, NULL, 0L, { 0, 0 } };
-mtd_info mtd_rootfs = { "rootfs", 0, 0, NULL, 0L, { 0, 0 } };
-mtd_info mtd_image = { "image", 0, 0, NULL, 0L, { 0, 0 } };
-mtd_info mtd_uboot = { "u-boot", 0, 0, NULL, 0L, { 0, 0 } };
-
-#define ROOTFS_END_OFFSET      0x00760000
-#define ROOTFS_MIN_OFFSET      0x00640000      // should be filled up to here, to make sure that the zip file is big enough to pass the size check of the stock firmware
-                                               // 2.0.17: filled up to 0x00640000
-                                               // 2.0.19: filled up to 0x00670000
-                                               // 2.0.20: filled up to 0x00670000
-
-// rootfs statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0x0075FFE0 -n 16 "wrt350n.bin" ; echo -en "\n"
-unsigned char product_id[] = { 0x00, 0x03 };   // seems to be a fixed value
-unsigned char protocol_id[] = { 0x00, 0x00 };  // seems to be a fixed value
-unsigned char fw_version[] = { 0x20, 0x20 };
-unsigned char rootfs_unknown[] = { 0x90, 0xF7 };       // seems to be a fixed value
-unsigned char sign[] = { 0x65, 0x52, 0x63, 0x4F, 0x6D, 0x4D, 0x00, 0x00 };     // eRcOmM
-
-// u-boot statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0x007FFF80 -n 128 "wrt350n.bin" ; echo -en "\n"
-//unsigned char sn[]   = {     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };       // (12) seems to be an unused value
-//unsigned char pin[]  = {     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };       // (8) seems to be an unused value
-//unsigned char node[] = {     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // (25) seems to be an unused value
-//                             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-//unsigned char checksum[] = { 0xE9 }; // (1) is calculated, does it belong to node?
-unsigned char pid[] = {        0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x01, 0x00, 0x00, 0x59, 0x42, 0x50, 0x00, 0x01, // (70) seems to be a fixed value, except for fw version
-                               0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // protocol id?
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,   // protocol id?
-                               0x12, 0x34,     // firmware version, same as in rootfs
-                               0x00, 0x00, 0x00, 0x04,
-                               0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D };     // sErCoMm
-
-// img statics via: hexdump -v -e '1/1 "0x%02X, "' -s 0 -n 512 "WRT350N-EU-ETSI-2.00.19.img" ; echo -en "\n" (unchanged up to 2.0.20)
-unsigned char img_hdr[] = {    0x00, 0x01, 0x00, 0x00, 0x59, 0x42, 0x50, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-                               0x00, 0x00,
-                               0x12, 0x34,     // firmware version, same as in rootfs
-                               0x00, 0x00, 0x00, 0x04, 0x61, 0x44, 0x6D, 0x42, 0x6C, 0x4B, 0x3D, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-                               0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, // md5 checksum
-                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-unsigned char img_eof[] = {    0xFF };
-
-
-void lprintf(int outputlevel, char *fmt, ...) {
-       va_list argp;
-       if (outputlevel <= verbosity) {
-               va_start(argp, fmt);
-               vprintf(fmt, argp);
-               va_end(argp);
-       }
-}
-
-
-int parse_par_file(FILE *f_par) {
-       int exitcode = 0;
-
-       char *buffer;
-       size_t buffer_size;
-       char *line;
-
-       int lineno;
-       int count;
-
-       char string1[256];
-       char string2[256];
-       int value;
-
-       mtd_info *mtd;
-       FILE *f_in;
-       int f_exitcode = 0;
-
-       // read all lines
-       buffer_size = 1000;
-       buffer = NULL;
-       lineno = 0;
-       while (!feof(f_par)) {
-               // read next line into memory
-               do {
-                       // allocate memory for input line
-                       if (!buffer) {
-                               buffer = malloc(buffer_size);
-                       }
-                       if (!buffer) {
-                               exitcode = 1;
-                               printf("parse_par_file: can not allocate %i bytes\n", (int) buffer_size);
-                               break;
-                       }
-
-                       line = fgets(buffer, buffer_size, f_par);
-                       if (!line) {
-                               exitcode = ferror(f_par);
-                               if (exitcode) {
-                                       printf("parse_par_file: %s\n", strerror(exitcode));
-                               }
-                               break;
-                       }
-
-                       // if buffer was not completely filled, then assume that line is complete
-                       count = strlen(buffer) + 1;
-                       if (count-- < buffer_size) {
-                               break;
-                       }
-
-                       // otherwise....
-
-                       // reset file position to line start
-                       value = fseek(f_par, -count, SEEK_CUR);
-                       if (value == -1) {
-                               exitcode = errno;
-                               printf("parse_par_file: %s\n", strerror(exitcode));
-                               break;
-                       }
-
-                       // double buffer size
-                       free(buffer);
-                       buffer = NULL;
-                       buffer_size *= 2;
-                       lprintf(DEBUG_LVL2, " extending buffer to %i bytes\n", buffer_size);
-               } while (1);
-               if ((!line) || (exitcode)) {
-                       break;
-               }
-
-               lineno++;       // increase line number
-
-               lprintf(DEBUG_LVL2, " line %i (%i) %s", lineno, count, line);
-
-               value = 0;
-               mtd = NULL;
-
-               // split line if starting with a colon
-               switch (line[0]) {
-                       case ':':
-                               count = sscanf(line, ":%255s %i %255s", string1, &value, string2);
-                               if (count != 3) {
-                                       printf("line %i does not meet defined format (:<mtdname> <mtdsize> <file>)\n", lineno);
-                               } else {
-                                       // populate mtd_info if supported mtd names
-                                       if (!strcmp(string1, mtd_kernel.name)) {
-                                               mtd = &mtd_kernel;
-                                       } else if (!strcmp(string1, mtd_rootfs.name)) {
-                                               mtd = &mtd_rootfs;
-                                       } else if (!strcmp(string1, mtd_uboot.name)) {
-                                               mtd = &mtd_uboot;
-                                       } else if (!strcmp(string1, mtd_image.name)) {
-                                               mtd = &mtd_image;
-                                       }
-
-                                       if (!mtd) {
-                                               printf("unknown mtd %s in line %i\n", string1, lineno);
-                                       } else if (mtd->filename) {
-                                               f_exitcode = 1;
-                                               printf("mtd %s in line %i multiple definitions\n", string1, lineno);
-                                       } else {
-                                               mtd->size = value;
-                                               mtd->filename = strdup(string2);
-
-                                               // Get file size
-                                               f_in = fopen(mtd->filename, "rb");
-                                               if (!f_in) {
-                                                       f_exitcode = errno;
-                                                       printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode));
-                                               } else {
-                                                       value = fread(&mtd->magic, 1, 2, f_in);
-                                                       if (value < 2) {
-                                                               if (ferror(f_in)) {
-                                                                       f_exitcode = ferror(f_in);
-                                                                       printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode));
-                                                               } else {
-                                                                       f_exitcode = 1;
-                                                                       printf("input file %s: smaller than two bytes, no magic code\n", mtd->filename);
-                                                               }
-                                                       }
-
-                                                       value = fseek(f_in, 0, SEEK_END);
-                                                       if (value == -1) {
-                                                               f_exitcode = errno;
-                                                               printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode));
-                                                       } else {
-                                                               mtd->filesize = ftell(f_in);
-                                                               if (mtd->filesize == -1) {
-                                                                       f_exitcode = errno;
-                                                                       printf("input file %s: %s\n", mtd->filename, strerror(f_exitcode));
-                                                               }
-                                                       }
-
-                                                       fclose(f_in);
-                                               }
-
-                                               lprintf(DEBUG, "mtd %s in line %i: size=0x%08X, filesize=0x%08lX, magic=0x%02X%02X, file=%s\n", mtd->name, lineno, mtd->size, mtd->filesize, mtd->magic[0], mtd->magic[1], mtd->filename);
-                                       }
-                               }
-                               break;
-                       case '#':       // integer values
-                               count = sscanf(line, "#%255s %i", string1, &value);
-                               if (count != 2) {
-                                       printf("line %i does not meet defined format (#<variable name> <integer>\n", lineno);
-                               } else {
-                                       if (!strcmp(string1, "version")) {
-                                               // changing version
-                                               fw_version[0] = 0x000000FF & ( value >> 8 );
-                                               fw_version[1] = 0x000000FF &   value;
-                                       } else {
-                                               printf("unknown integer variable %s in line %i\n", string1, lineno);
-                                       }
-
-                                       lprintf(DEBUG, "integer variable %s in line %i: 0x%08X\n", string1, lineno, value);
-                               }
-                               break;
-                       case '$':       // strings
-                               count = sscanf(line, "$%255s %255s", string1, string2);
-                               if (count != 2) {
-                                       printf("line %i does not meet defined format (:<mtdname> <mtdsize> <file>)\n", lineno);
-                               } else {
-/*
-                                       if (!strcmp(string1, "something")) {
-                                               something = strdup(string2);
-                                       } else {
-*/
-                                               printf("unknown string variable %s in line %i\n", string1, lineno);
-//                                     }
-                                       lprintf(DEBUG, "string variable %s in line %i: %s\n", string1, lineno, string2);
-                               }
-                               break;
-                       default:
-                               break;
-               }
-       }
-       free(buffer);
-
-       if (!exitcode) {
-               exitcode = f_exitcode;
-       }
-
-       return exitcode;
-}
-
-
-int create_bin_file(char *bin_filename) {
-       int exitcode = 0;
-
-       unsigned char *buffer;
-
-       int i;
-       mtd_info *mtd;
-       int addsize;
-       int padsize;
-
-       char *rand_filename = "/dev/urandom";
-       FILE *f_in;
-       int size;
-
-       unsigned long int csum;
-       unsigned char checksum;
-
-       FILE *f_out;
-
-       // allocate memory for bin file
-       buffer = malloc(KERNEL_CODE_OFFSET + FLASH_SIZE);
-       if (!buffer) {
-               exitcode = 1;
-               printf("create_bin_file: can not allocate %i bytes\n", FLASH_SIZE);
-       } else {
-               // initialize with zero
-               memset(buffer, 0, KERNEL_CODE_OFFSET + FLASH_SIZE);
-       }
-
-       // add files
-       if (!exitcode) {
-               for (i = 1; i <= 4; i++) {
-                       addsize = 0;
-                       padsize = 0;
-
-                       switch (i) {
-                               case 1:
-                                       mtd = &mtd_image;
-                                       padsize = ROOTFS_MIN_OFFSET - mtd->filesize;
-                                       break;
-                               case 2:
-                                       mtd = &mtd_kernel;
-                                       break;
-                               case 3:
-                                       mtd = &mtd_rootfs;
-                                       addsize = mtd->filesize;
-                                       padsize = ROOTFS_MIN_OFFSET - mtd_kernel.size - mtd->filesize;
-                                       break;
-                               case 4:
-                                       mtd = &mtd_uboot;
-                                       addsize = mtd->filesize;
-                                       break;
-                               default:
-                                       mtd = NULL;
-                                       exitcode = 1;
-                                       printf("create_bin_file: unknown mtd %i\n", i);
-                                       break;
-                       }
-                       if (!mtd) {
-                               break;
-                       }
-                       if (!mtd->filename) {
-                               continue;
-                       }
-
-                       lprintf(DEBUG, "adding mtd %s file %s\n", mtd->name, mtd->filename);
-
-                       // adding file size
-                       if (addsize) {
-                               buffer[KERNEL_CODE_OFFSET + mtd->offset - 16] = 0x000000FFL & ( addsize >> 24 );
-                               buffer[KERNEL_CODE_OFFSET + mtd->offset - 15] = 0x000000FFL & ( addsize >> 16 );
-                               buffer[KERNEL_CODE_OFFSET + mtd->offset - 14] = 0x000000FFL & ( addsize >> 8  );
-                               buffer[KERNEL_CODE_OFFSET + mtd->offset - 13] = 0x000000FFL &   addsize;
-                       }
-
-                       // adding file content
-                       f_in = fopen(mtd->filename, "rb");
-                       if (!f_in) {
-                               exitcode = errno;
-                               printf("input file %s: %s\n", mtd->filename, strerror(exitcode));
-                       } else {
-                               size = fread(&buffer[KERNEL_CODE_OFFSET + mtd->offset], mtd->filesize, 1, f_in);
-                               if (size < 1) {
-                                       if (ferror(f_in)) {
-                                               exitcode = ferror(f_in);
-                                               printf("input file %s: %s\n", mtd->filename, strerror(exitcode));
-                                       } else {
-                                               exitcode = 1;
-                                               printf("input file %s: smaller than before *doh*\n", mtd->filename);
-                                       }
-                               }
-                               fclose(f_in);
-                       }
-
-                       // padding
-                       if (padsize > 0) {
-                               addsize = padsize & 0x0000FFFF; // start on next 64KB border
-                               padsize -= addsize;
-                       }
-                       if (padsize > 0) {
-                               printf("mtd %s input file %s is too small (0x%08lX), adding 0x%08X random bytes\n", mtd->name, mtd->filename, mtd->filesize, padsize);
-
-                               addsize += KERNEL_CODE_OFFSET + mtd->offset + mtd->filesize;    // get offset
-                               lprintf(DEBUG, " padding offset 0x%08X length 0x%08X\n", addsize, padsize);
-
-                               f_in = fopen(rand_filename, "rb");
-                               if (!f_in) {
-                                       exitcode = errno;
-                                       printf("input file %s: %s\n", rand_filename, strerror(exitcode));
-                               } else {
-                                       size = fread(&buffer[addsize], padsize, 1, f_in);
-                                       if (size < 1) {
-                                               if (ferror(f_in)) {
-                                                       exitcode = ferror(f_in);
-                                                       printf("input file %s: %s\n", rand_filename, strerror(exitcode));
-                                               } else {
-                                                       exitcode = 1;
-                                                       printf("input file %s: smaller than before *doh*\n", rand_filename);
-                                               }
-                                       }
-                               }
-                               fclose(f_in);
-                       }
-               }
-       }
-
-       // add special contents
-       if (!exitcode) {
-               lprintf(DEBUG, "adding rootfs special data\n");
-               memcpy(&buffer[KERNEL_CODE_OFFSET + PRODUCT_ID_OFFSET], product_id, 2);
-               memcpy(&buffer[KERNEL_CODE_OFFSET + PROTOCOL_ID_OFFSET], protocol_id, 2);
-               memcpy(&buffer[KERNEL_CODE_OFFSET + FW_VERSION_OFFSET], fw_version, 2);
-               memcpy(&buffer[KERNEL_CODE_OFFSET + FW_VERSION_OFFSET + 2], rootfs_unknown, 2);
-               memcpy(&buffer[KERNEL_CODE_OFFSET + SIGN_OFFSET], sign, 8);     // eRcOmM
-
-               lprintf(DEBUG, "adding u-boot special data\n");
-//             memcpy(&buffer[KERNEL_CODE_OFFSET + SN_OFF], sn, 12);   // ToDo: currently zero, find out what's this for?
-//             memcpy(&buffer[KERNEL_CODE_OFFSET + PIN_OFF], pin, 8);  // ToDo: currently zero, find out what's this for?
-//             memcpy(&buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF], node, 25);  // ToDo: currently zero, find out what's this for?
-               memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET], pid, 70); // sErCoMm
-               memcpy(&buffer[KERNEL_CODE_OFFSET + BOOT_ADDR_BASE_OFF + PID_OFFSET + 57], fw_version, 2);
-
-               lprintf(DEBUG, "adding checksum byte\n");
-               csum = 0;
-               for (i = 0; i < KERNEL_CODE_OFFSET + FLASH_SIZE; i++) {
-                       csum += buffer[i];
-               }
-               lprintf(DEBUG_LVL2, " checksum 0x%016lX (%li)\n", csum, csum);
-
-               buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25] = ~csum + 1;
-               lprintf(DEBUG, " byte 0x%02X\n", buffer[KERNEL_CODE_OFFSET + NODE_BASE_OFF + 25]);
-       }
-
-       // write bin file
-       if (!exitcode) {
-               lprintf(DEBUG, "writing file %s\n", bin_filename);
-               f_out = fopen(bin_filename, "wb");
-               if (!f_out) {
-                       exitcode = errno;
-                       printf("output file %s: %s\n", bin_filename, strerror(exitcode));
-               } else {
-                       size = fwrite(buffer, KERNEL_CODE_OFFSET + FLASH_SIZE, 1, f_out);
-                       if (size < 1) {
-                               if (ferror(f_out)) {
-                                       exitcode = ferror(f_out);
-                                       printf("output file %s: %s\n", bin_filename, strerror(exitcode));
-                               } else {
-                                       exitcode = 1;
-                                       printf("output file %s: unspecified write error\n", bin_filename);
-                               }
-                       }
-                       fclose(f_out);
-               }
-       }
-
-       free(buffer);
-       return exitcode;
-}
-
-
-int create_zip_file(char *zip_filename, char *bin_filename) {
-       int exitcode = 0;
-
-       char *buffer;
-       size_t buffer_size;
-       int count;
-
-       buffer_size = 1000;
-       buffer = NULL;
-       do {
-               // allocate memory for command line
-               if (!buffer) {
-                       buffer = malloc(buffer_size);
-               }
-               if (!buffer) {
-                       exitcode = 1;
-                       printf("create_zip_file: can not allocate %i bytes\n", (int) buffer_size);
-                       break;
-               }
-
-               // if buffer was not completely filled, then line fit in completely
-               count = snprintf(buffer, buffer_size, "zip \"%s\" \"%s\"", zip_filename, bin_filename);
-               if ((count > -1) && (count < buffer_size)) {
-                       break;
-               }
-
-               // otherwise try again with more space
-               if (count > -1) {       // glibc 2.1
-                       buffer_size = count + 1;        // precisely what is needed
-               } else {        // glibc 2.0
-                       buffer_size *= 2;       // twice the old size
-               }
-               free(buffer);
-               buffer = NULL;
-               lprintf(DEBUG_LVL2, " extending buffer to %i bytes\n", buffer_size);
-       } while (1);
-
-       if (!exitcode) {
-               // zipping binfile
-               lprintf(DEBUG, "%s\n", buffer);
-               count = system(buffer);
-               if ((count < 0) || (WEXITSTATUS(count))) {
-                       exitcode = 1;
-                       printf("create_zip_file: can not execute %s bytes\n", buffer);
-               }
-       }
-
-       return exitcode;
-}
-
-
-int create_img_file(FILE *f_out, char *out_filename, char *zip_filename) {
-       int exitcode = 0;
-
-       md5_state_t state;
-       md5_byte_t digest[16];
-
-       int i;
-       int size;
-
-       FILE *f_in;
-       unsigned char buffer[1];
-
-       // copy firmware version
-       memcpy(&img_hdr[50], fw_version, 2);
-
-       // clear md5 checksum
-       memset(&img_hdr[480], 0, 16);
-
-       // prepare md5 checksum calculation
-       md5_init(&state);
-
-       // add img header
-       lprintf(DEBUG_LVL2, " adding img header\n");
-       for (i = 0; i < 512; i++) {
-               size = fputc(img_hdr[i], f_out);
-               if (size == EOF) {
-                       exitcode = ferror(f_out);
-                       printf("output file %s: %s\n", out_filename, strerror(exitcode));
-                       break;
-               }
-               md5_append(&state, (const md5_byte_t *)&img_hdr[i], 1);
-       }
-
-       // adding zip file
-       if (!exitcode) {
-               lprintf(DEBUG_LVL2, " adding zip file\n");
-               f_in = fopen(zip_filename, "rb");
-               if (!f_in) {
-                       exitcode = errno;
-                       printf("input file %s: %s\n", zip_filename, strerror(exitcode));
-               } else {
-                       while ((size = fgetc(f_in)) != EOF) {
-                               buffer[0] = size;
-
-                               size = fputc(buffer[0], f_out);
-                               if (size == EOF) {
-                                       exitcode = ferror(f_out);
-                                       printf("output file %s: %s\n", out_filename, strerror(exitcode));
-                                       break;
-                               }
-                               md5_append(&state, (const md5_byte_t *)buffer, 1);
-                       }
-                       if (ferror(f_in)) {
-                               exitcode = ferror(f_in);
-                               printf("input file %s: %s\n", zip_filename, strerror(exitcode));
-                       }
-               }
-
-       }
-
-       // add end byte
-       if (!exitcode) {
-               lprintf(DEBUG_LVL2, " adding img eof byte\n");
-               size = fputc(img_eof[0], f_out);
-               if (size == EOF) {
-                       exitcode = ferror(f_out);
-                       printf("output file %s: %s\n", out_filename, strerror(exitcode));
-               }
-               md5_append(&state, (const md5_byte_t *)img_eof, 1);
-       }
-
-       // append salt to md5 checksum
-       md5_append(&state, (const md5_byte_t *)"A^gU*<>?RFY@#DR&Z", 17);
-
-       // finish md5 checksum calculation
-       md5_finish(&state, digest);
-
-       // write md5 checksum into img header
-       if (!exitcode) {
-               lprintf(DEBUG_LVL2, " writing md5 checksum into img header of file\n");
-
-               size = fseek(f_out, 480, SEEK_SET);
-               if (size == -1) {
-                       exitcode = errno;
-                       printf("output file %s: %s\n", out_filename, strerror(exitcode));
-               } else {
-                       size = fwrite(digest, 16, 1, f_out);
-                       if (size < 1) {
-                               if (ferror(f_out)) {
-                                       exitcode = ferror(f_out);
-                                       printf("output file %s: %s\n", out_filename, strerror(exitcode));
-                               } else {
-                                       exitcode = 1;
-                                       printf("output file %s: unspecified write error\n", out_filename);
-                               }
-                       }
-               }
-
-               fclose(f_in);
-       }
-
-       return exitcode;
-}
-
-
-int main(int argc, char *argv[]) {
-       int exitcode = 0;
-
-       int help;
-       int onlybin;
-       int havezip;
-       int ignoremagic;
-       char option;
-       char *par_filename = NULL;
-       char *img_filename = NULL;
-       char *base_filename = NULL;
-       char *bin_filename = NULL;
-       char *zip_filename = NULL;
-
-       FILE *f_par = NULL;
-       FILE *f_img = NULL;
-
-       int i;
-       mtd_info *mtd;
-       int noupdate;
-       int sizecheck;
-       int magiccheck;
-       int magicerror;
-
-
-// display program header
-       printf(program_info, VERSION);
-
-
-// command line processing
-       // options
-       help = 0;
-       onlybin = 0;
-       havezip = 0;
-       ignoremagic = 0;
-       while ((option = getopt(argc, argv, "hbzif:v")) != -1) {
-               switch(option) {
-                       case 'h':
-                               help = 1;
-                               break;
-                       case 'b':
-                               onlybin = 1;
-                               break;
-                       case 'z':
-                               havezip = 1;
-                               break;
-                       case 'i':
-                               ignoremagic = 1;
-                               break;
-                       case 'f':
-                               sizecheck = sscanf(optarg, "%i", &i);
-                               if (sizecheck != 1) {
-                                       printf("Firmware version of -f option not a valid integer\n");
-                                       exitcode = 1;
-                               } else {
-                                       fw_version[0] = 0x000000FF & ( i >> 8 );
-                                       fw_version[1] = 0x000000FF &   i;
-                               }
-                               break;
-                       case 'v':
-                               verbosity++;
-                               break;
-                       case ':':       // option with missing operand
-                               printf("Option -%c requires an operand\n", optopt);
-                               exitcode = 1;
-                               break;
-                       case '?':
-                               printf("Unrecognized option: -%c\n", optopt);
-                               exitcode = 1;
-                               break;
-               }
-       }
-
-       // files
-       for ( ; optind < argc; optind++) {
-               if (!par_filename) {
-                       par_filename = argv[optind];
-
-                       if (access(par_filename, R_OK)) {
-                               if (havezip) {
-                                       printf("No read access to zip file %s\n", par_filename);
-                               } else {
-                                       printf("No read access to parameter or zip file %s\n", par_filename);
-                               }
-                               exitcode = 1;
-                       }
-
-                       continue;
-               }
-
-               if ((!onlybin) && (!img_filename)) {
-                       img_filename = argv[optind];
-
-                       if (!access(img_filename, F_OK)) {      // if file already exists then check write access
-                               if (access(img_filename, W_OK)) {
-                                       printf("No write access to image file %s\n", img_filename);
-                                       exitcode = 1;
-                               }
-                       }
-
-                       continue;
-               }
-
-               printf("Too many files stated\n");
-               exitcode = 1;
-               break;
-       }
-
-       // file name checks
-       if (!par_filename) {
-               if (havezip) {
-                       printf("Zip file not stated\n");
-               } else {
-                       printf("Parameter file not stated\n");
-               }
-               exitcode = 1;
-       } else {
-               base_filename = basename(par_filename);
-               if (!base_filename) {
-                       if (havezip) {
-                               printf("Zip file is a directory\n");
-                       } else {
-                               printf("Parameter file is a directory\n");
-                       }
-                       exitcode = 1;
-               }
-       }
-
-       if (!onlybin) {
-               if (!img_filename) {
-                       printf("Image file not stated\n");
-                       exitcode = 1;
-               } else {
-                       base_filename = basename(img_filename);
-                       if (!base_filename) {
-                               printf("Image file is a directory\n");
-                               exitcode = 1;
-                       }
-               }
-       }
-
-       // check for mutually exclusive options
-       if ((onlybin) && (havezip)) {
-               printf("Option -b and -z are mutually exclusive\n");
-               exitcode = 1;
-       }
-
-       // react on option problems or help request, then exit
-       if ((exitcode) || (help)) {
-               if (help) {
-                       printf("This program creates Linksys style images for the WRT350Nv2 router.\n");
-               }
-               printf("  Usage:\n\
-  %s [-h] [-b] [-z] [-i] [-f <version>] [-v] <parameter or zip file> [<image file>]\n\n\
-  Options:\n\
-  -h            -  Show this help\n\
-  -b            -  Create only bin file, no img or zip file is created\n\
-  -z            -  Have zip file, the img file will be directly created from it\n\
-  -i            -  Ignore unknown magic numbers\n\
-  -f <version>  -  Wanted firmware version to use with -z\n\
-                   Default firmware version is 0x2020 = 2.00.20.\n\
-                   Note: version from parameter file will supersede this\n\
-  -v            -  Increase debug verbosity level\n\n\
-  Example:\n\
-  %s wrt350nv2.par wrt350nv2.img\n\n", argv[0], argv[0]);
-               return exitcode;
-       }
-
-       // handle special case when zipfile is stated
-       if (havezip) {
-               zip_filename = par_filename;
-               par_filename = NULL;
-       }
-
-       lprintf(DEBUG_LVL2, " Verbosity: %i\n", verbosity);
-       lprintf(DEBUG_LVL2, " Program: %s\n", argv[0]);
-
-       if (par_filename) {
-               lprintf(DEBUG, "Parameter file: %s\n", par_filename);
-       }
-       if (zip_filename) {
-               lprintf(DEBUG, "Zip file: %s\n", zip_filename);
-       }
-       if (img_filename) {
-               lprintf(DEBUG, "Image file: %s\n", img_filename);
-       }
-
-
-// open files from command line
-       // parameter/zip file
-       if (par_filename) {
-               f_par = fopen(par_filename, "rt");
-               if (!f_par) {
-                       exitcode = errno;
-                       printf("Input file %s: %s\n", par_filename, strerror(exitcode));
-               }
-       }
-
-       // image file
-       if (img_filename) {
-               f_img = fopen(img_filename, "wb");
-               if (!f_img) {
-                       exitcode = errno;
-                       printf("Output file %s: %s\n", img_filename, strerror(exitcode));
-               }
-       }
-
-       if (exitcode) {
-               return exitcode;
-       }
-
-
-// parameter file processing
-       if ((!exitcode) && (f_par)) {
-               lprintf(DEBUG, "parsing parameter file...\n");
-
-               exitcode = parse_par_file(f_par);
-
-               lprintf(DEBUG, "...done parsing file\n");
-       }
-       if (f_par) {
-               fclose(f_par);
-       }
-
-
-// check all input data
-       if ((!exitcode) && (par_filename)) {
-               lprintf(DEBUG, "checking mtd data...\n");
-
-               for (i = 1; i <= 4; i++) {
-                       noupdate = 0;
-                       sizecheck = 0;
-                       magiccheck = 0;
-
-                       switch (i) {
-                               case 1:
-                                       mtd = &mtd_image;
-                                       sizecheck = ROOTFS_END_OFFSET;
-                                       magiccheck = 1;
-                                       break;
-                               case 2:
-                                       mtd = &mtd_kernel;
-                                       sizecheck = mtd_kernel.size - 16;
-                                       magiccheck = 1;
-                                       break;
-                               case 3:
-                                       mtd = &mtd_rootfs;
-                                       mtd->offset = mtd_kernel.size;
-                                       mtd->size = ROOTFS_END_OFFSET - mtd_kernel.size;
-                                       sizecheck = PRODUCT_ID_OFFSET - mtd_kernel.size;
-                                       magiccheck = 1;
-                                       break;
-                               case 4:
-                                       mtd = &mtd_uboot;
-                                       mtd->offset = BOOT_ADDR_BASE_OFF;
-                                       noupdate = 1;
-                                       sizecheck = SN_OFF - BOOT_ADDR_BASE_OFF;
-                                       break;
-                               default:
-                                       mtd = NULL;
-                                       exitcode = 1;
-                                       printf("unknown mtd check %i\n", i);
-                                       break;
-                       }
-                       if (!mtd) {
-                               break;
-                       }
-
-                       lprintf(DEBUG_LVL2, " checking mtd %s\n", mtd->name);
-
-                       // general checks
-
-                       // no further checks if no file data present
-                       if (!mtd->filename) {
-                               continue;
-                       }
-
-                       // not updated by stock firmware
-                       if (noupdate) {
-                               printf("mtd %s is specified, but will not be updated as of Linksys firmware 2.0.19\n", mtd->name);
-                       }
-
-                       // general magic number check
-                       magicerror = 0;
-                       if (magiccheck) {
-                               switch (i) {
-                                       case 1: // image
-                                       case 2: // kernel
-                                               if (!( 
-                                                      ((mtd->magic[0] == 0x27) && (mtd->magic[1] == 0x05))     // uImage
-                                               )) {
-                                                       magicerror = 1;
-                                               }
-                                               break;
-                                       case 3: // rootfs
-                                               if (!( 
-                                                      ((mtd->magic[0] == 0x68) && (mtd->magic[1] == 0x73))     // squashfs
-                                                   || ((mtd->magic[0] == 0x85) && (mtd->magic[1] == 0x19))     // jffs
-                                               )) {
-                                                       magicerror = 1;
-                                               }
-                                               break;
-                                       default:
-                                               magicerror = 1;
-                                               break;
-                               }
-                               if (magicerror) {
-                                       printf("mtd %s input file %s has unknown magic number (0x%02X%02X)", mtd->name, mtd->filename, mtd->magic[0], mtd->magic[1]);
-                                       if (ignoremagic) {
-                                               printf("...ignoring");
-                                       } else {
-                                               exitcode = 1;
-                                       }
-                                       printf("\n");
-                               }
-                       }
-
-                       // mtd specific size check
-                       if (mtd == &mtd_image) {
-                               if (mtd->filesize < 0x00200000) {
-                                       exitcode = 1;
-                                       printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
-                               }
-                       }
-
-                       if (mtd == &mtd_kernel) {
-                               if (mtd->filesize < 0x00080000) {
-                                       exitcode = 1;
-                                       printf("mtd %s input file %s too unrealistic small (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
-                               }
-                       }
-
-                       // general size check
-                       if (sizecheck) {
-                               if (sizecheck <= 0) {
-                                       exitcode = 1;
-                                       printf("mtd %s bad file size check (%i) due to input data\n", mtd->name, sizecheck);
-                               } else {
-                                       if (mtd->filesize > sizecheck) {
-                                               exitcode = 1;
-                                               printf("mtd %s input file %s too big (0x%08lX)\n", mtd->name, mtd->filename, mtd->filesize);
-                                       }
-                               }
-                       }
-               }
-
-               // Check for mandatory parts
-               if ((!mtd_image.filename) && (!mtd_kernel.filename || !mtd_rootfs.filename)) {
-                       exitcode = 1;
-                       if (mtd_kernel.filename && !mtd_rootfs.filename) {
-                               printf("Kernel without rootfs, either incorrectly specified or not at all in parameter file\n");
-                       } else if (!mtd_kernel.filename && mtd_rootfs.filename) {
-                               printf("Rootfs without kernel, either incorrectly specified or not at all in parameter file\n");
-                       } else {
-                               printf("Neither an image nor kernel with rootfs was/were correctly specified or at all in parameter file\n");
-                       }
-               }
-
-               // Check for duplicate parts
-               if ((mtd_image.filename) && (mtd_kernel.filename || mtd_rootfs.filename)) {
-                       exitcode = 1;
-                       printf("Image and kernel/rootfs specified in parameter file\n");
-               }
-
-               lprintf(DEBUG, "...done checking mtd data\n");
-       }
-
-
-// bin creation in memory
-       if ((!exitcode) && (par_filename)) {
-               bin_filename = "wrt350n.bin";
-
-               lprintf(DEBUG, "creating bin file %s...\n", bin_filename);
-
-               exitcode = create_bin_file(bin_filename);
-
-               lprintf(DEBUG, "...done creating bin file\n");
-       }
-
-// zip file creation
-       if ((!exitcode) && (!onlybin) && (!zip_filename)) {
-               zip_filename = "wrt350n.zip";
-
-               lprintf(DEBUG, "creating zip file %s...\n", zip_filename);
-
-               exitcode = create_zip_file(zip_filename, bin_filename);
-
-               lprintf(DEBUG, "...done creating zip file\n");
-       }
-
-
-// img file creation
-       if ((!exitcode) && (f_img)) {
-               lprintf(DEBUG, "creating img file...\n");
-
-               exitcode = create_img_file(f_img, img_filename, zip_filename);
-
-               lprintf(DEBUG, "...done creating img file\n");
-       }
-
-// clean up
-       if (f_img) {
-               fclose(f_img);
-       }
-
-// end program
-       return exitcode;
-}