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 <unistd.h> /* for unlink() */ 11 #include <libgen.h> 12 #include <getopt.h> /* for getopt() */ 13 #include <stdarg.h> 14 #include <errno.h> 15 #include <sys/stat.h> 16 17 #define DNI_HDR_LEN 128 18 19 /* 20 * Globals 21 */ 22 static char *ifname; 23 static char *progname; 24 static char *ofname; 25 static char *version = "1.00.00"; 26 static char *region = ""; 27 static char *hd_id; 28 29 static char *board_id; 30 /* 31 * Message macros 32 */ 33 #define ERR(fmt, ...) do { \ 34 fflush(0); \ 35 fprintf(stderr, "[%s] *** error: " fmt "\n", \ 36 progname, ## __VA_ARGS__ ); \ 37 } while (0) 38 39 #define ERRS(fmt, ...) do { \ 40 int save = errno; \ 41 fflush(0); \ 42 fprintf(stderr, "[%s] *** error: " fmt ": %s\n", \ 43 progname, ## __VA_ARGS__, strerror(save)); \ 44 } while (0) 45 46 void usage(int status) 47 { 48 FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout; 49 50 fprintf(stream, "Usage: %s [OPTIONS...]\n", progname); 51 fprintf(stream, 52 "\n" 53 "Options:\n" 54 " -B <board> create image for the board specified with <board>\n" 55 " -i <file> read input from the file <file>\n" 56 " -o <file> write output to the file <file>\n" 57 " -v <version> set image version to <version>\n" 58 " -r <region> set image region to <region>\n" 59 " -H <hd_id> set image hardware id to <hd_id>\n" 60 " -h show this screen\n" 61 ); 62 63 exit(status); 64 } 65 66 int main(int argc, char *argv[]) 67 { 68 int res = EXIT_FAILURE; 69 int buflen; 70 int err; 71 struct stat st; 72 char *buf; 73 int pos, rem, i; 74 uint8_t csum; 75 76 FILE *outfile, *infile; 77 78 progname = basename(argv[0]); 79 80 while ( 1 ) { 81 int c; 82 83 c = getopt(argc, argv, "B:i:o:v:r:H:h"); 84 if (c == -1) 85 break; 86 87 switch (c) { 88 case 'B': 89 board_id = optarg; 90 break; 91 case 'i': 92 ifname = optarg; 93 break; 94 case 'o': 95 ofname = optarg; 96 break; 97 case 'v': 98 version = optarg; 99 break; 100 case 'r': 101 region = optarg; 102 break; 103 case 'H': 104 hd_id = optarg; 105 break; 106 case 'h': 107 usage(EXIT_SUCCESS); 108 break; 109 default: 110 usage(EXIT_FAILURE); 111 break; 112 } 113 } 114 115 if (board_id == NULL) { 116 ERR("no board specified"); 117 goto err; 118 } 119 120 if (ifname == NULL) { 121 ERR("no input file specified"); 122 goto err; 123 } 124 125 if (ofname == NULL) { 126 ERR("no output file specified"); 127 goto err; 128 } 129 130 err = stat(ifname, &st); 131 if (err){ 132 ERRS("stat failed on %s", ifname); 133 goto err; 134 } 135 136 buflen = st.st_size + DNI_HDR_LEN + 1; 137 buf = malloc(buflen); 138 if (!buf) { 139 ERR("no memory for buffer\n"); 140 goto err; 141 } 142 143 memset(buf, 0, DNI_HDR_LEN); 144 pos = snprintf(buf, DNI_HDR_LEN, "device:%s\nversion:V%s\nregion:%s\n", 145 board_id, version, region); 146 rem = DNI_HDR_LEN - pos; 147 if (pos >= 0 && rem > 1 && hd_id) { 148 snprintf(buf + pos, rem, "hd_id:%s\n", hd_id); 149 } 150 151 infile = fopen(ifname, "r"); 152 if (infile == NULL) { 153 ERRS("could not open \"%s\" for reading", ifname); 154 goto err_free; 155 } 156 157 errno = 0; 158 fread(buf + DNI_HDR_LEN, st.st_size, 1, infile); 159 if (errno != 0) { 160 ERRS("unable to read from file %s", ifname); 161 goto err_close_in; 162 } 163 164 csum = 0; 165 for (i = 0; i < (st.st_size + DNI_HDR_LEN); i++) 166 csum += buf[i]; 167 168 csum = 0xff - csum; 169 buf[st.st_size + DNI_HDR_LEN] = csum; 170 171 outfile = fopen(ofname, "w"); 172 if (outfile == NULL) { 173 ERRS("could not open \"%s\" for writing", ofname); 174 goto err_close_in; 175 } 176 177 errno = 0; 178 fwrite(buf, buflen, 1, outfile); 179 if (errno) { 180 ERRS("unable to write to file %s", ofname); 181 goto err_close_out; 182 } 183 184 res = EXIT_SUCCESS; 185 186 fflush(outfile); 187 188 err_close_out: 189 fclose(outfile); 190 if (res != EXIT_SUCCESS) { 191 unlink(ofname); 192 } 193 194 err_close_in: 195 fclose(infile); 196 197 err_free: 198 free(buf); 199 200 err: 201 return res; 202 } 203
This page was automatically generated by LXR 0.3.1. • OpenWrt