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 #include <malloc.h> 22 23 /* Size of the blocks written to the compressed file */ 24 #define BLOCK_SIZE 8 25 26 int main(int argc, char *argv[]) 27 { 28 FILE *file; 29 int ret; 30 unsigned char *buf; 31 size_t count, i, j; 32 33 /* Provide usage help */ 34 if (argc != 2) { 35 printf("Usage:\n%s FILENAME\n", argv[0]); 36 return EXIT_FAILURE; 37 } 38 /* Open file */ 39 file = fopen(argv[1], "r"); 40 if (!file) { 41 perror("fopen"); 42 return EXIT_FAILURE; 43 } 44 /* Get file length */ 45 ret = fseek(file, 0, SEEK_END); 46 if (ret < 0) { 47 perror("fseek"); 48 return EXIT_FAILURE; 49 } 50 count = ftell(file); 51 if (!count) { 52 fprintf(stderr, "File %s has length 0\n", argv[1]); 53 return EXIT_FAILURE; 54 } 55 rewind(file); 56 /* Read file */ 57 buf = malloc(count); 58 if (!buf) { 59 perror("calloc"); 60 return EXIT_FAILURE; 61 } 62 count = fread(buf, 1, count, file); 63 64 /* Generate output */ 65 printf("/* SPDX-License-Identifier: GPL-2.0+ */\n"); 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\n"); 71 printf("#define EFI_ST_DISK_IMG { 0x%08zx, { \\\n", count); 72 73 for (i = 0; i < count; i += BLOCK_SIZE) { 74 int c = 0; 75 76 for (j = i; j < i + BLOCK_SIZE && j < count; ++j) { 77 if (buf[j]) 78 c = 1; 79 } 80 if (!c) 81 continue; 82 printf("\t{0x%08zx, \"", i); 83 for (j = i; j < i + BLOCK_SIZE && j < count; ++j) 84 printf("\\x%02x", buf[j]); 85 printf("\"}, /* "); 86 for (j = i; j < i + BLOCK_SIZE && j < count; ++j) { 87 if (buf[j] != '*' && buf[j] >= 0x20 && buf[j] <= 0x7e) 88 printf("%c", buf[j]); 89 else 90 printf("."); 91 } 92 printf(" */ \\\n"); 93 } 94 printf("\t{0, NULL} } }\n"); 95 96 /* Release resources */ 97 free(buf); 98 ret = fclose(file); 99 if (ret) { 100 perror("fclose"); 101 return EXIT_FAILURE; 102 } 103 return EXIT_SUCCESS; 104 } 105