2 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
3 * Copyright (C) 2016 Stijn Tintel <stijn@linux-ipv6.be>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation.
25 #define ERR(fmt, ...) do { \
27 fprintf(stderr, "[%s] *** error: " fmt "\n", \
28 progname, ## __VA_ARGS__ ); \
31 #define ERRS(fmt, ...) do { \
34 fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \
35 progname, ## __VA_ARGS__, strerror(save)); \
38 #define WRGG03_MAGIC 0x20080321
40 struct wrgg03_header
{
53 } __attribute__ ((packed
));
55 static char *progname
;
58 static char *signature
;
61 static uint32_t flag
= 0;
62 static uint32_t reserve
= 0;
64 static uint32_t offset
;
66 static int big_endian
;
68 void usage(int status
)
70 FILE *stream
= (status
!= EXIT_SUCCESS
) ? stderr
: stdout
;
72 fprintf(stream
, "Usage: %s [OPTIONS...]\n", progname
);
76 " -b create image in big endian format\n"
77 " -B <buildno> build number\n"
78 " -i <file> read input from the file <file>\n"
79 " -d <name> set device name to <name>\n"
80 " -m <model> model name\n"
81 " -o <file> write output to the file <file>\n"
82 " -O <offset> set offset to <offset>\n"
83 " -s <sig> set image signature to <sig>\n"
84 " -h show this screen\n"
90 static void put_u32(void *data
, uint32_t val
, int swap
)
92 unsigned char *p
= data
;
95 p
[0] = (val
>> 24) & 0xff;
96 p
[1] = (val
>> 16) & 0xff;
97 p
[2] = (val
>> 8) & 0xff;
100 p
[3] = (val
>> 24) & 0xff;
101 p
[2] = (val
>> 16) & 0xff;
102 p
[1] = (val
>> 8) & 0xff;
107 static void get_digest(struct wrgg03_header
*header
, char *data
, int size
)
113 MD5_Update(&ctx
, (char *)&header
->offset
, sizeof(header
->offset
));
114 MD5_Update(&ctx
, (char *)&header
->devname
, sizeof(header
->devname
));
115 MD5_Update(&ctx
, data
, size
);
117 MD5_Final(header
->digest
, &ctx
);
120 int main(int argc
, char *argv
[])
122 struct wrgg03_header
*header
;
127 int res
= EXIT_FAILURE
;
129 FILE *outfile
, *infile
;
131 progname
= basename(argv
[0]);
136 c
= getopt(argc
, argv
, "bd:i:m:o:s:v:B:O:h");
166 offset
= strtoul(optarg
, NULL
, 0);
178 if (signature
== NULL
) {
179 ERR("no signature specified");
183 if (ifname
== NULL
) {
184 ERR("no input file specified");
188 if (ofname
== NULL
) {
189 ERR("no output file specified");
193 if (devname
== NULL
) {
194 ERR("no device name specified");
199 ERR("no model name specified");
203 if (buildno
== NULL
) {
204 ERR("no build number specified");
208 if (version
== NULL
) {
209 ERR("no version specified");
213 err
= stat(ifname
, &st
);
215 ERRS("stat failed on %s", ifname
);
219 buflen
= st
.st_size
+ sizeof(struct wrgg03_header
);
220 buf
= malloc(buflen
);
222 ERR("no memory for buffer\n");
226 infile
= fopen(ifname
, "r");
227 if (infile
== NULL
) {
228 ERRS("could not open \"%s\" for reading", ifname
);
233 fread(buf
+ sizeof(struct wrgg03_header
), st
.st_size
, 1, infile
);
235 ERRS("unable to read from file %s", ifname
);
239 header
= (struct wrgg03_header
*) buf
;
240 memset(header
, '\0', sizeof(struct wrgg03_header
));
242 strncpy(header
->signature
, signature
, sizeof(header
->signature
));
243 put_u32(&header
->magic1
, WRGG03_MAGIC
, 0);
244 put_u32(&header
->magic2
, WRGG03_MAGIC
, 0);
245 strncpy(header
->version
, version
, sizeof(header
->version
));
246 strncpy(header
->model
, model
, sizeof(header
->model
));
247 put_u32(&header
->flag
, flag
, 0);
248 put_u32(&header
->reserve
, reserve
, 0);
249 strncpy(header
->buildno
, buildno
, sizeof(header
->buildno
));
250 put_u32(&header
->size
, st
.st_size
, big_endian
);
251 put_u32(&header
->offset
, offset
, big_endian
);
252 strncpy(header
->devname
, devname
, sizeof(header
->devname
));
254 get_digest(header
, buf
+ sizeof(struct wrgg03_header
), st
.st_size
);
256 outfile
= fopen(ofname
, "w");
257 if (outfile
== NULL
) {
258 ERRS("could not open \"%s\" for writing", ofname
);
263 fwrite(buf
, buflen
, 1, outfile
);
265 ERRS("unable to write to file %s", ofname
);
275 if (res
!= EXIT_SUCCESS
)