Home | History | Annotate | Download | only in tools
      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 (at) 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