1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
19 #define ERR(fmt, ...) do { \
21 fprintf(stderr, "[%s] *** error: " fmt "\n", \
22 progname, ## __VA_ARGS__ ); \
25 #define ERRS(fmt, ...) do { \
28 fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \
29 progname, ## __VA_ARGS__, strerror(save)); \
32 #define WRG_MAGIC 0x20040220
42 } __attribute__ ((packed
));
44 static char *progname
;
47 static char *signature
;
48 static char *dev_name
;
49 static uint32_t offset
;
50 static int big_endian
;
52 void usage(int status
)
54 FILE *stream
= (status
!= EXIT_SUCCESS
) ? stderr
: stdout
;
56 fprintf(stream
, "Usage: %s [OPTIONS...]\n", progname
);
60 " -b create image in big endian format\n"
61 " -i <file> read input from the file <file>\n"
62 " -d <name> set device name to <name>\n"
63 " -o <file> write output to the file <file>\n"
64 " -O <offset> set offset to <offset>\n"
65 " -s <sig> set image signature to <sig>\n"
66 " -h show this screen\n"
72 static void put_u32(void *data
, uint32_t val
)
74 unsigned char *p
= data
;
77 p
[0] = (val
>> 24) & 0xff;
78 p
[1] = (val
>> 16) & 0xff;
79 p
[2] = (val
>> 8) & 0xff;
82 p
[3] = (val
>> 24) & 0xff;
83 p
[2] = (val
>> 16) & 0xff;
84 p
[1] = (val
>> 8) & 0xff;
89 static void get_digest(struct wrg_header
*header
, char *data
, int size
)
95 MD5_Update(&ctx
, (char *)&header
->offset
, sizeof(header
->offset
));
96 MD5_Update(&ctx
, (char *)&header
->devname
, sizeof(header
->devname
));
97 MD5_Update(&ctx
, data
, size
);
99 MD5_Final((unsigned char *)header
->digest
, &ctx
);
102 int main(int argc
, char *argv
[])
104 struct wrg_header
*header
;
109 int res
= EXIT_FAILURE
;
111 FILE *outfile
, *infile
;
113 progname
= basename(argv
[0]);
118 c
= getopt(argc
, argv
, "bd:i:o:s:O:h");
139 offset
= strtoul(optarg
, NULL
, 0);
151 if (signature
== NULL
) {
152 ERR("no signature specified");
156 if (ifname
== NULL
) {
157 ERR("no input file specified");
161 if (ofname
== NULL
) {
162 ERR("no output file specified");
166 if (dev_name
== NULL
) {
167 ERR("no device name specified");
171 err
= stat(ifname
, &st
);
173 ERRS("stat failed on %s", ifname
);
177 buflen
= st
.st_size
+ sizeof(struct wrg_header
);
178 buf
= malloc(buflen
);
180 ERR("no memory for buffer\n");
184 infile
= fopen(ifname
, "r");
185 if (infile
== NULL
) {
186 ERRS("could not open \"%s\" for reading", ifname
);
191 fread(buf
+ sizeof(struct wrg_header
), st
.st_size
, 1, infile
);
193 ERRS("unable to read from file %s", ifname
);
197 header
= (struct wrg_header
*) buf
;
198 memset(header
, '\0', sizeof(struct wrg_header
));
200 strncpy(header
->signature
, signature
, sizeof(header
->signature
));
201 strncpy(header
->devname
, dev_name
, sizeof(header
->signature
));
202 put_u32(&header
->magic1
, WRG_MAGIC
);
203 put_u32(&header
->magic2
, WRG_MAGIC
);
204 put_u32(&header
->size
, st
.st_size
);
205 put_u32(&header
->offset
, offset
);
207 get_digest(header
, buf
+ sizeof(struct wrg_header
), st
.st_size
);
209 outfile
= fopen(ofname
, "w");
210 if (outfile
== NULL
) {
211 ERRS("could not open \"%s\" for writing", ofname
);
216 fwrite(buf
, buflen
, 1, outfile
);
218 ERRS("unable to write to file %s", ofname
);
228 if (res
!= EXIT_SUCCESS
)