• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/mkplanexfw.c

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  *  Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  4  */
  5 
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <stdint.h>
  9 #include <string.h>
 10 #include <byteswap.h>
 11 #include <unistd.h>     /* for unlink() */
 12 #include <libgen.h>
 13 #include <getopt.h>     /* for getopt() */
 14 #include <stdarg.h>
 15 #include <errno.h>
 16 #include <sys/stat.h>
 17 
 18 #include "sha1.h"
 19 
 20 #if (__BYTE_ORDER == __BIG_ENDIAN)
 21 #  define HOST_TO_BE32(x)       (x)
 22 #  define BE32_TO_HOST(x)       (x)
 23 #else
 24 #  define HOST_TO_BE32(x)       bswap_32(x)
 25 #  define BE32_TO_HOST(x)       bswap_32(x)
 26 #endif
 27 
 28 
 29 struct planex_hdr {
 30         uint8_t         sha1sum[20];
 31         char            version[8];
 32         uint8_t         unk1[2];
 33         uint32_t        datalen;
 34 } __attribute__ ((packed));
 35 
 36 struct board_info {
 37         char            *id;
 38         uint32_t        seed;
 39         uint8_t         unk[2];
 40         uint32_t        datalen;
 41 };
 42 
 43 /*
 44  * Globals
 45  */
 46 static char *ifname;
 47 static char *progname;
 48 static char *ofname;
 49 static char *version = "1.00.00";
 50 
 51 static char *board_id;
 52 static struct board_info *board;
 53 
 54 static struct board_info boards[] = {
 55         {
 56                 .id             = "MZK-W04NU",
 57                 .seed           = 2,
 58                 .unk            = {0x04, 0x08},
 59                 .datalen        = 0x770000,
 60         }, {
 61                 .id             = "MZK-W300NH",
 62                 .seed           = 4,
 63                 .unk            = {0x00, 0x00},
 64                 .datalen        = 0x770000,
 65         }, {
 66                 /* terminating entry */
 67         }
 68 };
 69 
 70 /*
 71  * Message macros
 72  */
 73 #define ERR(fmt, ...) do { \
 74         fflush(0); \
 75         fprintf(stderr, "[%s] *** error: " fmt "\n", \
 76                         progname, ## __VA_ARGS__ ); \
 77 } while (0)
 78 
 79 #define ERRS(fmt, ...) do { \
 80         int save = errno; \
 81         fflush(0); \
 82         fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \
 83                         progname, ## __VA_ARGS__, strerror(save)); \
 84 } while (0)
 85 
 86 static struct board_info *find_board(char *id)
 87 {
 88         struct board_info *ret;
 89         struct board_info *board;
 90 
 91         ret = NULL;
 92         for (board = boards; board->id != NULL; board++){
 93                 if (strcasecmp(id, board->id) == 0) {
 94                         ret = board;
 95                         break;
 96                 }
 97         };
 98 
 99         return ret;
100 }
101 
102 void usage(int status)
103 {
104         FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
105 
106         fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
107         fprintf(stream,
108 "\n"
109 "Options:\n"
110 "  -B <board>      create image for the board specified with <board>\n"
111 "  -i <file>       read input from the file <file>\n"
112 "  -o <file>       write output to the file <file>\n"
113 "  -v <version>    set image version to <version>\n"
114 "  -h              show this screen\n"
115         );
116 
117         exit(status);
118 }
119 
120 int main(int argc, char *argv[])
121 {
122         int res = EXIT_FAILURE;
123         int buflen;
124         int err;
125         struct stat st;
126         char *buf;
127         struct planex_hdr *hdr;
128         sha1_context ctx;
129         uint32_t seed;
130 
131         FILE *outfile, *infile;
132 
133         progname = basename(argv[0]);
134 
135         while ( 1 ) {
136                 int c;
137 
138                 c = getopt(argc, argv, "B:i:o:v:h");
139                 if (c == -1)
140                         break;
141 
142                 switch (c) {
143                 case 'B':
144                         board_id = optarg;
145                         break;
146                 case 'i':
147                         ifname = optarg;
148                         break;
149                 case 'o':
150                         ofname = optarg;
151                         break;
152                 case 'v':
153                         version = optarg;
154                         break;
155                 case 'h':
156                         usage(EXIT_SUCCESS);
157                         break;
158                 default:
159                         usage(EXIT_FAILURE);
160                         break;
161                 }
162         }
163 
164         if (board_id == NULL) {
165                 ERR("no board specified");
166                 goto err;
167         }
168 
169         board = find_board(board_id);
170         if (board == NULL) {
171                 ERR("unknown board '%s'", board_id);
172                 goto err;
173         };
174 
175         if (ifname == NULL) {
176                 ERR("no input file specified");
177                 goto err;
178         }
179 
180         if (ofname == NULL) {
181                 ERR("no output file specified");
182                 goto err;
183         }
184 
185         err = stat(ifname, &st);
186         if (err){
187                 ERRS("stat failed on %s", ifname);
188                 goto err;
189         }
190 
191         if (st.st_size > board->datalen) {
192                 ERR("file '%s' is too big - max size: 0x%08X (exceeds %lu bytes)\n",
193                     ifname, board->datalen, st.st_size - board->datalen);
194                 goto err;
195         }
196 
197         buflen = board->datalen + 0x10000;
198         buf = malloc(buflen);
199         if (!buf) {
200                 ERR("no memory for buffer\n");
201                 goto err;
202         }
203 
204         memset(buf, 0xff, buflen);
205         hdr = (struct planex_hdr *)buf;
206 
207         hdr->datalen = HOST_TO_BE32(board->datalen);
208         hdr->unk1[0] = board->unk[0];
209         hdr->unk1[1] = board->unk[1];
210 
211         snprintf(hdr->version, sizeof(hdr->version), "%s", version);
212 
213         infile = fopen(ifname, "r");
214         if (infile == NULL) {
215                 ERRS("could not open \"%s\" for reading", ifname);
216                 goto err_free;
217         }
218 
219         errno = 0;
220         fread(buf +  sizeof(*hdr), st.st_size, 1, infile);
221         if (errno != 0) {
222                 ERRS("unable to read from file %s", ifname);
223                 goto err_close_in;
224         }
225 
226         seed = HOST_TO_BE32(board->seed);
227         sha1_starts(&ctx);
228         sha1_update(&ctx, (uchar *) &seed, sizeof(seed));
229         sha1_update(&ctx, buf + sizeof(*hdr), board->datalen);
230         sha1_finish(&ctx, hdr->sha1sum);
231 
232         outfile = fopen(ofname, "w");
233         if (outfile == NULL) {
234                 ERRS("could not open \"%s\" for writing", ofname);
235                 goto err_close_in;
236         }
237 
238         errno = 0;
239         fwrite(buf, buflen, 1, outfile);
240         if (errno) {
241                 ERRS("unable to write to file %s", ofname);
242                 goto err_close_out;
243         }
244 
245         res = EXIT_SUCCESS;
246 
247         fflush(outfile);
248 
249  err_close_out:
250         fclose(outfile);
251         if (res != EXIT_SUCCESS) {
252                 unlink(ofname);
253         }
254 
255  err_close_in:
256         fclose(infile);
257 
258  err_free:
259         free(buf);
260 
261  err:
262         return res;
263 }
264 
265 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt