source: trunk/tools/firmware-utils/src/mkplanexfw.c @ 14410

Last change on this file since 14410 was 14410, checked in by juhosg, 8 years ago

[tools] firmware-utils/mkplanexfw: new firmware generation tool for the Planex MZK-W04NU device

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 3.7 KB
Line 
1/*
2 *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
3 *
4 *  This program is free software; you can redistribute it and/or modify it
5 *  under the terms of the GNU General Public License version 2 as published
6 *  by the Free Software Foundation.
7 *
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <stdint.h>
13#include <string.h>
14#include <unistd.h>     /* for unlink() */
15#include <libgen.h>
16#include <getopt.h>     /* for getopt() */
17#include <stdarg.h>
18#include <errno.h>
19#include <sys/stat.h>
20
21#include "sha1.h"
22
23#if (__BYTE_ORDER == __BIG_ENDIAN)
24#  define HOST_TO_BE32(x)       (x)
25#  define BE32_TO_HOST(x)       (x)
26#else
27#  define HOST_TO_BE32(x)       bswap_32(x)
28#  define BE32_TO_HOST(x)       bswap_32(x)
29#endif
30
31
32struct planex_hdr {
33        uint8_t         sha1sum[20];
34        char            version[8];
35        uint8_t         unk1[2];
36        uint32_t        datalen;
37} __attribute__ ((packed));
38
39/*
40 * Globals
41 */
42static char *ifname;
43static char *progname;
44static char *ofname;
45static char *version = "1.00.00";
46
47/*
48 * Message macros
49 */
50#define ERR(fmt, ...) do { \
51        fflush(0); \
52        fprintf(stderr, "[%s] *** error: " fmt "\n", \
53                        progname, ## __VA_ARGS__ ); \
54} while (0)
55
56#define ERRS(fmt, ...) do { \
57        int save = errno; \
58        fflush(0); \
59        fprintf(stderr, "[%s] *** error: " fmt "\n", \
60                        progname, ## __VA_ARGS__, strerror(save)); \
61} while (0)
62
63void usage(int status)
64{
65        FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
66        struct board_info *board;
67
68        fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
69        fprintf(stream,
70"\n"
71"Options:\n"
72"  -i <file>       read input from the file <file>\n"
73"  -o <file>       write output to the file <file>\n"
74"  -v <version>    set image version to <version>\n"
75"  -h              show this screen\n"
76        );
77
78        exit(status);
79}
80
81int main(int argc, char *argv[])
82{
83        int res = EXIT_FAILURE;
84        int buflen;
85        int err;
86        struct stat st;
87        char *buf;
88        struct planex_hdr *hdr;
89        sha1_context ctx;
90        uint32_t t = HOST_TO_BE32(2);
91
92        FILE *outfile, *infile;
93
94        progname = basename(argv[0]);
95
96        while ( 1 ) {
97                int c;
98
99                c = getopt(argc, argv, "i:o:v:h");
100                if (c == -1)
101                        break;
102
103                switch (c) {
104                case 'i':
105                        ifname = optarg;
106                        break;
107                case 'o':
108                        ofname = optarg;
109                        break;
110                case 'v':
111                        version = optarg;
112                        break;
113                case 'h':
114                        usage(EXIT_SUCCESS);
115                        break;
116                default:
117                        usage(EXIT_FAILURE);
118                        break;
119                }
120        }
121
122        if (ifname == NULL) {
123                ERR("no input file specified");
124                goto err;
125        }
126
127        if (ofname == NULL) {
128                ERR("no output file specified");
129                goto err;
130        }
131
132        err = stat(ifname, &st);
133        if (err){
134                ERRS("stat failed on %s", ifname);
135                goto err;
136        }
137
138        buflen = (st.st_size + 3) & ~3;
139        buflen += sizeof(*hdr);
140
141        buf = malloc(buflen);
142        if (!buf) {
143                ERR("no memory for buffer\n");
144                goto err;
145        }
146
147        memset(buf, 0xff, buflen);
148        hdr = (struct planex_hdr *)buf;
149
150        hdr->datalen = HOST_TO_BE32(buflen - sizeof(*hdr));
151        hdr->unk1[0] = 0x04;
152        hdr->unk1[1] = 0x08;
153
154        snprintf(hdr->version, sizeof(hdr->version), "%s", version);
155
156        infile = fopen(ifname, "r");
157        if (infile == NULL) {
158                ERRS("could not open \"%s\" for reading", ifname);
159                goto err_free;
160        }
161
162        errno = 0;
163        fread(buf +  sizeof(*hdr), st.st_size, 1, infile);
164        if (errno != 0) {
165                ERRS("unable to read from file %s", ifname);
166                goto err_close_in;
167        }
168
169        sha1_starts(&ctx);
170        sha1_update(&ctx, (uchar *) &t, sizeof(t));
171        sha1_update(&ctx, buf + sizeof(*hdr), buflen - sizeof(*hdr));
172        sha1_finish(&ctx, hdr->sha1sum);
173
174        outfile = fopen(ofname, "w");
175        if (outfile == NULL) {
176                ERRS("could not open \"%s\" for writing", ofname);
177                goto err_close_in;
178        }
179
180        errno = 0;
181        fwrite(buf, buflen, 1, outfile);
182        if (errno) {
183                ERRS("unable to write to file %s", ofname);
184                goto err_close_out;
185        }
186
187        res = EXIT_SUCCESS;
188
189 out_flush:
190        fflush(outfile);
191
192 err_close_out:
193        fclose(outfile);
194        if (res != EXIT_SUCCESS) {
195                unlink(ofname);
196        }
197
198 err_close_in:
199        fclose(infile);
200
201 err_free:
202        free(buf);
203
204 err:
205        return res;
206}
207
Note: See TracBrowser for help on using the repository browser.