| // SPDX-License-Identifier: GPL-2.0+ |
| /* |
| * Convert a file image to a C define |
| * |
| * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> |
| * |
| * For testing EFI disk management we need an in memory image of |
| * a disk. |
| * |
| * The tool file2include converts a file to a C include. The file |
| * is separated into strings of 8 bytes. Only the non-zero strings |
| * are written to the include. The output format has been designed |
| * to maintain readability. |
| * |
| * As the disk image needed for testing contains mostly zeroes a high |
| * compression ratio can be attained. |
| */ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdint.h> |
| #include <malloc.h> |
| |
| /* Size of the blocks written to the compressed file */ |
| #define BLOCK_SIZE 8 |
| |
| int main(int argc, char *argv[]) |
| { |
| FILE *file; |
| int ret; |
| unsigned char *buf; |
| size_t count, i, j; |
| |
| /* Provide usage help */ |
| if (argc != 2) { |
| printf("Usage:\n%s FILENAME\n", argv[0]); |
| return EXIT_FAILURE; |
| } |
| /* Open file */ |
| file = fopen(argv[1], "r"); |
| if (!file) { |
| perror("fopen"); |
| return EXIT_FAILURE; |
| } |
| /* Get file length */ |
| ret = fseek(file, 0, SEEK_END); |
| if (ret < 0) { |
| perror("fseek"); |
| return EXIT_FAILURE; |
| } |
| count = ftell(file); |
| if (!count) { |
| fprintf(stderr, "File %s has length 0\n", argv[1]); |
| return EXIT_FAILURE; |
| } |
| rewind(file); |
| /* Read file */ |
| buf = malloc(count); |
| if (!buf) { |
| perror("calloc"); |
| return EXIT_FAILURE; |
| } |
| count = fread(buf, 1, count, file); |
| |
| /* Generate output */ |
| printf("/* SPDX-License-Identifier: GPL-2.0+ */\n"); |
| printf("/*\n"); |
| printf(" * Non-zero %u byte strings of a disk image\n", BLOCK_SIZE); |
| printf(" *\n"); |
| printf(" * Generated with tools/file2include\n"); |
| printf(" */\n\n"); |
| printf("#define EFI_ST_DISK_IMG { 0x%08zx, { \\\n", count); |
| |
| for (i = 0; i < count; i += BLOCK_SIZE) { |
| int c = 0; |
| |
| for (j = i; j < i + BLOCK_SIZE && j < count; ++j) { |
| if (buf[j]) |
| c = 1; |
| } |
| if (!c) |
| continue; |
| printf("\t{0x%08zx, \"", i); |
| for (j = i; j < i + BLOCK_SIZE && j < count; ++j) |
| printf("\\x%02x", buf[j]); |
| printf("\"}, /* "); |
| for (j = i; j < i + BLOCK_SIZE && j < count; ++j) { |
| if (buf[j] != '*' && buf[j] >= 0x20 && buf[j] <= 0x7e) |
| printf("%c", buf[j]); |
| else |
| printf("."); |
| } |
| printf(" */ \\\n"); |
| } |
| printf("\t{0, NULL} } }\n"); |
| |
| /* Release resources */ |
| free(buf); |
| ret = fclose(file); |
| if (ret) { |
| perror("fclose"); |
| return EXIT_FAILURE; |
| } |
| return EXIT_SUCCESS; |
| } |