/* Serialize image contents and fill in checksum */ static size_t pack_image(struct bladerf_image *img, uint8_t *buf) { size_t i = 0; uint16_t ver_field; uint32_t type, len, addr; uint64_t timestamp; char checksum[BLADERF_IMAGE_CHECKSUM_LEN]; memcpy(&buf[i], img->magic, BLADERF_IMAGE_MAGIC_LEN); i += BLADERF_IMAGE_MAGIC_LEN; memset(&buf[i], 0, BLADERF_IMAGE_CHECKSUM_LEN); i += BLADERF_IMAGE_CHECKSUM_LEN; ver_field = HOST_TO_BE16(img->version.major); memcpy(&buf[i], &ver_field, sizeof(ver_field)); i += sizeof(ver_field); ver_field = HOST_TO_BE16(img->version.minor); memcpy(&buf[i], &ver_field, sizeof(ver_field)); i += sizeof(ver_field); ver_field = HOST_TO_BE16(img->version.patch); memcpy(&buf[i], &ver_field, sizeof(ver_field)); i += sizeof(ver_field); timestamp = HOST_TO_BE64(img->timestamp); memcpy(&buf[i], ×tamp, sizeof(timestamp)); i += sizeof(timestamp); memcpy(&buf[i], &img->serial, BLADERF_SERIAL_LENGTH); i += BLADERF_SERIAL_LENGTH; memset(&buf[i], 0, BLADERF_IMAGE_RESERVED_LEN); i += BLADERF_IMAGE_RESERVED_LEN; type = HOST_TO_BE32((uint32_t)img->type); memcpy(&buf[i], &type, sizeof(type)); i += sizeof(type); addr = HOST_TO_BE32(img->address); memcpy(&buf[i], &addr, sizeof(addr)); i += sizeof(addr); len = HOST_TO_BE32(img->length); memcpy(&buf[i], &len, sizeof(len)); i += sizeof(len); memcpy(&buf[i], img->data, img->length); i += img->length; sha256_buffer((const char *)buf, i, checksum); memcpy(&buf[BLADERF_IMAGE_MAGIC_LEN], checksum, BLADERF_IMAGE_CHECKSUM_LEN); return i; }
int main(int argc, char *argv[]) { int res = EXIT_FAILURE; int buflen; int err; struct stat st; char *buf; struct planex_hdr *hdr; sha1_context ctx; uint32_t t = HOST_TO_BE32(2); FILE *outfile, *infile; progname = basename(argv[0]); while ( 1 ) { int c; c = getopt(argc, argv, "i:o:v:h"); if (c == -1) break; switch (c) { case 'i': ifname = optarg; break; case 'o': ofname = optarg; break; case 'v': version = optarg; break; case 'h': usage(EXIT_SUCCESS); break; default: usage(EXIT_FAILURE); break; } } if (ifname == NULL) { ERR("no input file specified"); goto err; } if (ofname == NULL) { ERR("no output file specified"); goto err; } err = stat(ifname, &st); if (err) { ERRS("stat failed on %s", ifname); goto err; } buflen = (st.st_size + 3) & ~3; buflen += sizeof(*hdr); buf = malloc(buflen); if (!buf) { ERR("no memory for buffer\n"); goto err; } memset(buf, 0xff, buflen); hdr = (struct planex_hdr *)buf; hdr->datalen = HOST_TO_BE32(buflen - sizeof(*hdr)); hdr->unk1[0] = 0x04; hdr->unk1[1] = 0x08; snprintf(hdr->version, sizeof(hdr->version), "%s", version); infile = fopen(ifname, "r"); if (infile == NULL) { ERRS("could not open \"%s\" for reading", ifname); goto err_free; } errno = 0; fread(buf + sizeof(*hdr), st.st_size, 1, infile); if (errno != 0) { ERRS("unable to read from file %s", ifname); goto err_close_in; } sha1_starts(&ctx); sha1_update(&ctx, (uchar *) &t, sizeof(t)); sha1_update(&ctx, buf + sizeof(*hdr), buflen - sizeof(*hdr)); sha1_finish(&ctx, hdr->sha1sum); outfile = fopen(ofname, "w"); if (outfile == NULL) { ERRS("could not open \"%s\" for writing", ofname); goto err_close_in; } errno = 0; fwrite(buf, buflen, 1, outfile); if (errno) { ERRS("unable to write to file %s", ofname); goto err_close_out; } res = EXIT_SUCCESS; out_flush: fflush(outfile); err_close_out: fclose(outfile); if (res != EXIT_SUCCESS) { unlink(ofname); } err_close_in: fclose(infile); err_free: free(buf); err: return res; }