diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 28 | ||||
-rw-r--r-- | README.md | 1 | ||||
-rw-r--r-- | crc32.c | 93 | ||||
-rw-r--r-- | crc32.h | 12 | ||||
-rw-r--r-- | fstypes.c | 4 | ||||
-rw-r--r-- | fstypes.h | 2 | ||||
-rw-r--r-- | guid.c | 149 | ||||
-rw-r--r-- | guid.h | 13 | ||||
-rw-r--r-- | mkgpt.c | 143 | ||||
-rw-r--r-- | part.h | 4 | ||||
-rwxr-xr-x | test-mkgpt.sh | 25 |
12 files changed, 237 insertions, 238 deletions
diff --git a/.gitignore b/.gitignore index 5761abc..d8ac7ef 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.o +compile_commands.json diff --git a/Makefile b/Makefile index 8a8d04d..731570a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -CFLAGS:=-Wall -Wextra -Wpedantic -std=c11 +CFLAGS+=-Wall -Wextra -Wpedantic -std=c11 -D_DEFAULT_SOURCE ALL:=mkgpt +PREFIX:=/usr/local dev: CFLAGS+=-g3 -Og -fsanitize=address -fsanitize=undefined dev: LDFLAGS+=-fsanitize=address -fsanitize=undefined @@ -9,22 +10,29 @@ prod: CFLAGS+=-g0 -Os prod: LDFLAGS+=-s prod: $(ALL) -static: CC:=musl-gcc -static: CFLAGS+=-g0 -Os -static: LDFLAGS+=-static -s -static: $(ALL) +static: LDFLAGS+=-static +static: prod + +musl-static: CC:=musl-gcc +musl-static: static mkgpt: mkgpt.o crc32.o fstypes.o guid.o -mkgpt.o: mkgpt.c guid.h fstypes.h part.h +mkgpt.o: mkgpt.c guid.h fstypes.h part.h crc32.h fstypes.o: fstypes.c fstypes.h guid.h guid.o: guid.c guid.h -crc32.o: crc32.c +crc32.o: crc32.c crc32.h -.PHONY: check clean format +.PHONY: check clean format install uninstall check: - cppcheck --enable=all --inconclusive --std=c11 . + -cppcheck --enable=all --inconclusive --std=c11 . + -shellcheck *.sh clean: $(RM) *.o $(ALL) format: - clang-format -verbose -i *.[ch] + -clang-format -verbose -i *.[ch] +install: prod + mkdir -pv $(DESTDIR)$(PREFIX)/bin + cp -fv mkgpt $(DESTDIR)$(PREFIX)/bin +uninstall: + rm -fv $(DESTDIR)$(PREFIX)/bin/mkgpt diff --git a/README.md b/README.md index 28e5ef6..09837d1 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,4 @@ Optionally, the string `random` can be used to generate a random GUID. - no way to make room for larger boot loaders or to create swap partitions - some overly specific code (Linux, Windoze) without a strong need for it - some strange code (static info in oversized, dynamically populated array?) +- some rather broken code (required calls in asserts, misaligned pointers) diff --git a/crc32.c b/crc32.c index 6c268ef..d232b38 100644 --- a/crc32.c +++ b/crc32.c @@ -18,55 +18,56 @@ Abstract: CalcuateCrc32 routine. Modified to avoid EFI dependencies for mkgpt + Modified to include a proper header file --*/ -#include <stdlib.h> -#include <stdint.h> - -uint32_t mCrcTable[256] = {0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, - 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, - 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, - 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, - 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, - 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, - 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, - 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, - 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, - 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, - 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, - 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, - 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, - 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, - 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, - 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, - 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, - 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, - 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, - 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, - 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, - 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; +#include "crc32.h" + +static uint32_t mCrcTable[256] = {0x00000000, 0x77073096, 0xEE0E612C, + 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, + 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, + 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, + 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, + 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, + 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, + 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, + 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180, + 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, + 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, + 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, + 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, + 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, + 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, + 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, + 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, + 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, + 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, + 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, + 0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, + 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, + 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, + 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, + 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, + 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, + 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, + 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, + 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, + 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, + 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, + 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, + 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, + 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, + 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, + 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, + 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, + 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, + 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, + 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, + 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, + 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, + 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, + 0x2D02EF8D}; int CalculateCrc32(uint8_t *Data, size_t DataSize, uint32_t *CrcOut) diff --git a/crc32.h b/crc32.h new file mode 100644 index 0000000..2158681 --- /dev/null +++ b/crc32.h @@ -0,0 +1,12 @@ +#pragma once + +#ifndef CRC32_H +#define CRC32_H + +#include <stddef.h> +#include <stdint.h> + +int +CalculateCrc32(uint8_t *Data, size_t DataSize, uint32_t *CrcOut); + +#endif diff --git a/fstypes.c b/fstypes.c index 094db3e..383f8c5 100644 --- a/fstypes.c +++ b/fstypes.c @@ -19,14 +19,12 @@ * THE SOFTWARE. */ -#include "guid.h" +#include "fstypes.h" #include <stddef.h> GUID fstypes[512]; char *fsnames[512]; -#include "fstypes.h" - void init_fstypes() { diff --git a/fstypes.h b/fstypes.h index f1b81c7..4c63e64 100644 --- a/fstypes.h +++ b/fstypes.h @@ -1,3 +1,5 @@ +#pragma once + /* Copyright (C) 2014 by John Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/guid.c b/guid.c index b4ee887..12247fc 100644 --- a/guid.c +++ b/guid.c @@ -19,32 +19,22 @@ * THE SOFTWARE. */ -#include <stddef.h> +#include "guid.h" + #include <stdio.h> #include <stdlib.h> #include <time.h> -#ifdef WINDOWS -#include <windows.h> -#include <wincrypt.h> -#endif - -#include "guid.h" - #define GUID_FMT \ "%08X-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX" -static int rnd_init = 0; - int -guid_to_string(char *str, GUID *guid) +guid_to_string(char *str, const GUID *guid) { if (guid == NULL) { - fprintf(stderr, "guid_to_string: guid is null\n"); return -1; } if (str == NULL) { - fprintf(stderr, "guid_to_string: str is null\n"); return -1; } @@ -56,14 +46,12 @@ guid_to_string(char *str, GUID *guid) } int -string_to_guid(GUID *guid, char *str) +string_to_guid(GUID *guid, const char *str) { if (guid == NULL) { - fprintf(stderr, "string_to_guid: guid is null\n"); return -1; } if (str == NULL) { - fprintf(stderr, "string_to_guid: str is null\n"); return -1; } @@ -76,134 +64,71 @@ string_to_guid(GUID *guid, char *str) } int -guid_to_bytestring(uint8_t *bytes, GUID *guid) +guid_to_bytestring(uint8_t *bytes, const GUID *guid) { - int i; - if (guid == NULL) { - fprintf(stderr, "guid_to_bytestring: guid is null\n"); return -1; } if (bytes == NULL) { - fprintf(stderr, "guid_to_bytestring: bytes is null\n"); return -1; } + /* TODO potential alignment problem? */ *(uint32_t *)&bytes[0] = guid->data1; *(uint16_t *)&bytes[4] = guid->data2; *(uint16_t *)&bytes[6] = guid->data3; - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { bytes[8 + i] = guid->data4[i]; + } return 0; } int -guid_is_zero(GUID *guid) +guid_is_zero(const GUID *guid) { - int i; - - if (guid->data1 != 0) + if (guid->data1 != 0) { return 0; - if (guid->data2 != 0) - return 0; - if (guid->data3 != 0) + } + if (guid->data2 != 0) { return 0; - for (i = 0; i < 8; i++) { - if (guid->data4[i] != 0) - return 0; } - return 1; -} - -void -init_rnd() -{ - /* Attempt to initialise the random number generator */ - FILE *rnd = fopen("/dev/random", "r"); - if (rnd != NULL) { - unsigned int seed; - if (fread(&seed, 1, sizeof(unsigned int), rnd) == - sizeof(unsigned int)) { - srand(seed); - fclose(rnd); - rnd_init = 1; - return; - } - - fclose(rnd); + if (guid->data3 != 0) { + return 0; } - -#ifdef WINDOWS - { - HCRYPTPROV prov = 0; - if (!CryptAcquireContext(&prov, NULL, NULL, PROV_INTEL_SEC, - CRYPT_VERIFYCONTEXT)) { - if (!CryptAcquireContext(&prov, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) - prov = 0; - } - - if (prov != 0) { - unsigned int seed; - CryptGenRandom( - prov, sizeof(unsigned int), (BYTE *)&seed); - srand(seed); - rnd_init = 1; - return; + for (int i = 0; i < 8; i++) { + if (guid->data4[i] != 0) { + return 0; } } -#endif - - { - time_t t = time(NULL); - struct tm *tmptr = gmtime(&t); - int seed = tmptr->tm_hour; - seed <<= 3; - seed ^= tmptr->tm_isdst; - seed <<= 3; - seed ^= tmptr->tm_mday; - seed <<= 3; - seed ^= tmptr->tm_min; - seed <<= 3; - seed ^= tmptr->tm_mon; - seed <<= 3; - seed ^= tmptr->tm_sec; - seed <<= 3; - seed ^= tmptr->tm_wday; - seed <<= 3; - seed ^= tmptr->tm_yday; - seed <<= 3; - seed ^= tmptr->tm_year; - - srand((unsigned int)seed); - rnd_init = 1; - return; - } + return 1; } -uint8_t -rnd_byte() +static uint32_t +rnd() { - if (rnd_init == 0) - init_rnd(); - - return (uint8_t)(rand() & 0xff); + return random() & 0xff; /* just a byte please */ } int random_guid(GUID *guid) { - int i; - - guid->data1 = (uint32_t)rnd_byte() | (((uint32_t)rnd_byte()) << 8) | - (((uint32_t)rnd_byte()) << 16) | - (((uint32_t)rnd_byte()) << 24); - guid->data2 = (uint16_t)rnd_byte() | (((uint16_t)rnd_byte()) << 8); - guid->data3 = (uint16_t)rnd_byte() | - (((uint16_t)((rnd_byte() & 0x0f) | 0x40)) << 8); - for (i = 0; i < 8; i++) - guid->data4[i] = rnd_byte(); + if (guid == NULL) { + return -1; + } + + static int initialized = 0; + if (!initialized) { + srandom(time(NULL)); + initialized = 1; + } + + guid->data1 = rnd() | rnd() << 8 | rnd() << 16 | rnd() << 24; + guid->data2 = rnd() | rnd() << 8; + guid->data3 = rnd() | ((rnd() & 0x0f) | 0x40) << 8; + for (int i = 0; i < 8; i++) { + guid->data4[i] = rnd(); + } return 0; } diff --git a/guid.h b/guid.h index 1a73cf9..c9e0509 100644 --- a/guid.h +++ b/guid.h @@ -1,3 +1,5 @@ +#pragma once + /* Copyright (C) 2014 by John Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -24,6 +26,7 @@ #include <stdint.h> +/* TODO is this abstraction really needed? (see fstype.c mess) */ typedef struct _guid { uint32_t data1; uint16_t data2; @@ -34,15 +37,17 @@ typedef struct _guid { #define GUID_STRING_LENGTH 36 #define GUID_BYTESTRING_LENGTH 16 +/* TODO never actually used? */ int -guid_to_string(char *str, GUID *guid); +guid_to_string(char *str, const GUID *guid); + int -string_to_guid(GUID *guid, char *str); +string_to_guid(GUID *guid, const char *str); int -guid_to_bytestring(uint8_t *bytes, GUID *guid); +guid_to_bytestring(uint8_t *bytes, const GUID *guid); int random_guid(GUID *guid); int -guid_is_zero(GUID *guid); +guid_is_zero(const GUID *guid); #endif diff --git a/mkgpt.c b/mkgpt.c index 382f774..29ac72b 100644 --- a/mkgpt.c +++ b/mkgpt.c @@ -19,43 +19,41 @@ * THE SOFTWARE. */ +#include "crc32.h" +#include "fstypes.h" #include "guid.h" #include "part.h" -#include "fstypes.h" + +#include <errno.h> +#include <limits.h> #include <stddef.h> #include <stdio.h> -#include <string.h> #include <stdlib.h> -#include <assert.h> -#include <errno.h> -#include <limits.h> +#include <string.h> -void +static void dump_help(char *fname); -int +static int check_parts(); -int +static int parse_opts(int argc, char **argv); -int +static int parse_guid(char *str, GUID *guid); -void +static void write_output(); -int -CalculateCrc32(uint8_t *Data, size_t DataSize, uint32_t *CrcOut); - -size_t sect_size = 512; -long image_sects = 0; -long min_image_sects = 2048; -PART *first_part = NULL; -PART *last_part = NULL; -FILE *output = NULL; -GUID disk_guid; -int part_count; -int header_sectors; -int first_usable_sector; -int secondary_headers_sect; -int secondary_gpt_sect; +static size_t sect_size = 512; +static long image_sects = 0; +static long min_image_sects = 2048; +static PART *first_part = NULL; +static PART *last_part = NULL; +static FILE *output = NULL; +static GUID disk_guid; +static int part_count; +static int header_sectors; +static int first_usable_sector; +static int secondary_headers_sect; +static int secondary_gpt_sect; int main(int argc, char **argv) @@ -86,7 +84,7 @@ main(int argc, char **argv) return 0; } -int +static int parse_opts(int argc, char **argv) { int i = 1; @@ -201,13 +199,12 @@ parse_opts(int argc, char **argv) } /* Allocate a new partition structure */ - cur_part = (PART *)malloc(sizeof(PART)); + cur_part = calloc(1, sizeof(*cur_part)); if (cur_part == NULL) { fprintf(stderr, "out of memory allocating " "partition structure\n"); return -1; } - memset(cur_part, 0, sizeof(PART)); cur_part_id++; cur_part->id = cur_part_id; @@ -320,23 +317,22 @@ parse_opts(int argc, char **argv) return 0; } -void +static void dump_help(char *fname) { - printf("Usage: %s -o <output_file> [-h] [--sector-size sect_size] [-s " - "min_image_size] [partition def 0] [part def 1] ... [part def " - "n]\n" + printf("Usage: %s -o <output_file> [-h] [--disk-guid GUID] " + "[--sector-size sect_size] [-s min_image_size] " + "[partition def 0] [part def 1] ... [part def n]\n" " Partition definition: --part <image_file> --type <type> " "[--uuid uuid] [--name name]\n" " Please see the README file for further information\n", fname); } -int +static int parse_guid(char *str, GUID *guid) { long mbr_id = -1; - int i; /* detect request for random uuid */ if (!strcmp(str, "random") || !strcmp(str, "rnd")) @@ -348,7 +344,7 @@ parse_guid(char *str, GUID *guid) mbr_id = -1; /* detect by name */ - for (i = 0; i < 512; i++) { + for (int i = 0; i < 512; i++) { if (fsnames[i] == NULL) continue; if (!strcmp(fsnames[i], str)) { @@ -360,7 +356,7 @@ parse_guid(char *str, GUID *guid) if (mbr_id >= 0 && mbr_id <= 511) { if (guid_is_zero(&fstypes[mbr_id])) return -1; - memcpy(guid, &fstypes[mbr_id], sizeof(GUID)); + *guid = fstypes[mbr_id]; return 0; } @@ -368,7 +364,7 @@ parse_guid(char *str, GUID *guid) return string_to_guid(guid, str); } -int +static int check_parts() { /* Iterate through the partitions, checking validity */ @@ -431,7 +427,7 @@ check_parts() } if (cur_part->name == NULL) { - cur_part->name = (char *)malloc(128); + cur_part->name = malloc(128); sprintf(cur_part->name, "part%i", cur_part_id); } @@ -459,7 +455,7 @@ check_parts() image_sects = min_image_sects; } else if (image_sects < needed_file_length) { fprintf(stderr, - "requested image size (%lu) is too small to hold the " + "requested image size (%zu) is too small to hold the " "partitions\n", image_sects * sect_size); return -1; @@ -471,7 +467,14 @@ check_parts() return 0; } -void +static void +panic(const char *msg) +{ + fprintf(stderr, "panic: %s", msg); + exit(EXIT_FAILURE); +} + +static void write_output() { int i; @@ -479,8 +482,10 @@ write_output() PART *cur_part; /* Write MBR */ - mbr = (uint8_t *)malloc(sect_size); - memset(mbr, 0, sect_size); + mbr = calloc(1, sect_size); + if (mbr == NULL) { + panic("calloc failed"); + } *(uint32_t *)&mbr[446] = 0x00020000; /* boot indicator = 0, start CHS = 0x000200 */ @@ -498,16 +503,19 @@ write_output() mbr[510] = 0x55; mbr[511] = 0xaa; /* Signature */ - assert(fwrite(mbr, 1, sect_size, output) == sect_size); + if (fwrite(mbr, 1, sect_size, output) != sect_size) { + panic("fwrite failed"); + } /* Define GPT headers */ - gpt = (uint8_t *)malloc(sect_size); - assert(gpt); - gpt2 = (uint8_t *)malloc(sect_size); - assert(gpt2); - - memset(gpt, 0, sect_size); - memset(gpt2, 0, sect_size); + gpt = calloc(1, sect_size); + if (gpt == NULL) { + panic("calloc failed"); + } + gpt2 = calloc(1, sect_size); + if (gpt2 == NULL) { + panic("calloc failed"); + } *(uint64_t *)&gpt[0] = 0x5452415020494645ULL; /* Signature */ *(uint32_t *)&gpt[8] = 0x00010000UL; /* Revision */ @@ -525,9 +533,10 @@ write_output() *(uint32_t *)&gpt[88] = 0; /* PartitionEntryArrayCRC32 */ /* Define GPT partition entries */ - parts = (uint8_t *)malloc(header_sectors * sect_size); - assert(parts); - memset(parts, 0, header_sectors * sect_size); + parts = calloc(header_sectors, sect_size); + if (parts == NULL) { + panic("calloc failed"); + } cur_part = first_part; i = 0; @@ -568,13 +577,17 @@ write_output() CalculateCrc32(gpt2, 96, (uint32_t *)&gpt2[16]); /* Write primary GPT and headers */ - assert(fwrite(gpt, 1, sect_size, output) == sect_size); - assert(fwrite(parts, 1, header_sectors * sect_size, output) == - header_sectors * sect_size); + if (fwrite(gpt, 1, sect_size, output) != sect_size) { + panic("fwrite failed"); + } + if (fwrite(parts, 1, header_sectors * sect_size, output) != + header_sectors * sect_size) { + panic("fwrite failed"); + } /* Write partitions */ cur_part = first_part; - image_buf = (uint8_t *)malloc(sect_size); + image_buf = malloc(sect_size); while (cur_part) { size_t bytes_read; size_t bytes_written = 0; @@ -591,8 +604,10 @@ write_output() cur_part->sect_length * sect_size - bytes_written; - assert(fwrite(image_buf, 1, bytes_to_write, output) == - bytes_to_write); + if (fwrite(image_buf, 1, bytes_to_write, output) != + bytes_to_write) { + panic("fwrite failed"); + } bytes_written += bytes_to_write; } @@ -602,8 +617,12 @@ write_output() /* Write secondary GPT partition headers and header */ fseek(output, secondary_headers_sect * sect_size, SEEK_SET); - assert(fwrite(parts, 1, header_sectors * sect_size, output) == - header_sectors * sect_size); + if (fwrite(parts, 1, header_sectors * sect_size, output) != + header_sectors * sect_size) { + panic("fwrite failed"); + } fseek(output, secondary_gpt_sect * sect_size, SEEK_SET); - assert(fwrite(gpt2, 1, sect_size, output) == sect_size); + if (fwrite(gpt2, 1, sect_size, output) != sect_size) { + panic("fwrite failed"); + } } diff --git a/part.h b/part.h index 0d4b7c3..80504c8 100644 --- a/part.h +++ b/part.h @@ -1,3 +1,5 @@ +#pragma once + /* Copyright (C) 2014 by John Cronin * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -37,7 +39,7 @@ typedef struct _part { char *name; FILE *src; - struct _part *next; + struct _part *next; /* TODO why build a list? */ } PART; #endif diff --git a/test-mkgpt.sh b/test-mkgpt.sh new file mode 100755 index 0000000..43bee6e --- /dev/null +++ b/test-mkgpt.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Simplistic test case, but better than none. + +tmpdir="/tmp/test-mkgpt" + +if [ ! -x ./mkgpt ]; then + echo "No ./mkgpt to run, no fun!" + exit 1 +fi + +mkdir -pv ${tmpdir} +for name in a.img b.img c.img; do + truncate --size=16M ${tmpdir}/${name} +done + +# TODO something goes wrong with --sector-size 1024 or 4096 +./mkgpt -o ${tmpdir}/bla.img \ + --part ${tmpdir}/a.img --type system \ + --part ${tmpdir}/b.img --type fat32 \ + --part ${tmpdir}/c.img --type linux + +fdisk -l ${tmpdir}/bla.img + +rm -rfv ${tmpdir} |