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 
main(int argc,char * argv[])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