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