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