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