1 /* 2 * Convert a file image to a C define 3 * 4 * Copyright (c) 2017 Heinrich Schuchardt <xypron.glpk@gmx.de> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 * 8 * For testing EFI disk management we need an in memory image of 9 * a disk. 10 * 11 * The tool file2include converts a file to a C include. The file 12 * is separated into strings of 8 bytes. Only the non-zero strings 13 * are written to the include. The output format has been designed 14 * to maintain readability. 15 * 16 * As the disk image needed for testing contains mostly zeroes a high 17 * compression ratio can be attained. 18 */ 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <stdint.h> 22 #include <malloc.h> 23 24 /* Size of the blocks written to the compressed file */ 25 #define BLOCK_SIZE 8 26 27 int main(int argc, char *argv[]) 28 { 29 FILE *file; 30 int ret; 31 unsigned char *buf; 32 size_t count, i, j; 33 34 /* Provide usage help */ 35 if (argc != 2) { 36 printf("Usage:\n%s FILENAME\n", argv[0]); 37 return EXIT_FAILURE; 38 } 39 /* Open file */ 40 file = fopen(argv[1], "r"); 41 if (!file) { 42 perror("fopen"); 43 return EXIT_FAILURE; 44 } 45 /* Get file length */ 46 ret = fseek(file, 0, SEEK_END); 47 if (ret < 0) { 48 perror("fseek"); 49 return EXIT_FAILURE; 50 } 51 count = ftell(file); 52 if (!count) { 53 fprintf(stderr, "File %s has length 0\n", argv[1]); 54 return EXIT_FAILURE; 55 } 56 rewind(file); 57 /* Read file */ 58 buf = malloc(count); 59 if (!buf) { 60 perror("calloc"); 61 return EXIT_FAILURE; 62 } 63 count = fread(buf, 1, count, file); 64 65 /* Generate output */ 66 printf("/*\n"); 67 printf(" * Non-zero %u byte strings of a disk image\n", BLOCK_SIZE); 68 printf(" *\n"); 69 printf(" * Generated with tools/file2include\n"); 70 printf(" *\n"); 71 printf(" * SPDX-License-Identifier: GPL-2.0+\n"); 72 printf(" */\n\n"); 73 printf("#define EFI_ST_DISK_IMG { 0x%08zx, { \\\n", count); 74 75 for (i = 0; i < count; i += BLOCK_SIZE) { 76 int c = 0; 77 78 for (j = i; j < i + BLOCK_SIZE && j < count; ++j) { 79 if (buf[j]) 80 c = 1; 81 } 82 if (!c) 83 continue; 84 printf("\t{0x%08zx, \"", i); 85 for (j = i; j < i + BLOCK_SIZE && j < count; ++j) 86 printf("\\x%02x", buf[j]); 87 printf("\"}, /* "); 88 for (j = i; j < i + BLOCK_SIZE && j < count; ++j) { 89 if (buf[j] >= 0x20 && buf[j] <= 0x7e) 90 printf("%c", buf[j]); 91 else 92 printf("."); 93 } 94 printf(" */ \\\n"); 95 } 96 printf("\t{0, NULL} } }\n"); 97 98 /* Release resources */ 99 free(buf); 100 ret = fclose(file); 101 if (ret) { 102 perror("fclose"); 103 return EXIT_FAILURE; 104 } 105 return EXIT_SUCCESS; 106 } 107