1 #include <inttypes.h>
2 #include "gpt.h"
3 
4 static struct _guid guid_hfsplus = GPT_ENT_TYPE_HFSPLUS;
5 
6 #define EQGUID(a,b) (memcmp(a, b, sizeof(struct _guid)) == 0)
7 
read_gpt_header(FILE * F,struct _gpt_header * h)8 void read_gpt_header(FILE * F, struct _gpt_header *h)
9 {
10 	memset(h, 0, sizeof(struct _gpt_header));
11 	fread(h, sizeof(struct _gpt_header), 1, F);
12 }
13 
read_gpt_entry(FILE * F,struct _gpt_entry * e)14 void read_gpt_entry(FILE * F, struct _gpt_entry *e)
15 {
16 	memset(e, 0, sizeof(struct _gpt_entry));
17 	fread(e, sizeof(struct _gpt_entry), 1, F);
18 }
19 
print_mountcmd(char * filename)20 int print_mountcmd(char *filename)
21 {
22 	if (!filename)
23 		return (-1);
24 
25 	unsigned int i, pn = 0;
26 	char tmp[128];
27 	struct _gpt_header gpt_header;
28 	struct _gpt_entry gpt_entry;
29 	struct _gpt_entry *gpt_ent_array;
30 
31 	FILE *F = fopen(filename, "rb");
32 	fseeko(F, 0x200, SEEK_SET);
33 	read_gpt_header(F, &gpt_header);
34 
35 	if (memcmp(gpt_header.hdr_sig, GPT_HDR_SIG, sizeof(gpt_header.hdr_sig)) == 0) {
36 		gpt_ent_array = (struct _gpt_entry *)malloc(gpt_header.hdr_entries * sizeof(struct _gpt_entry));
37 		if (!gpt_ent_array) {
38 			return (-1);
39 		}
40 		fseeko(F, 0x400, SEEK_SET);
41 		for (i = 0; i < gpt_header.hdr_entries; i++) {
42 			fseeko(F, 0x400 + i * gpt_header.hdr_entsz, SEEK_SET);
43 			read_gpt_entry(F, &gpt_entry);
44 
45 			if (!EQGUID(&guid_hfsplus, &gpt_entry.ent_type))
46 				break;
47 			++pn;
48 			memcpy(&gpt_ent_array[i], &gpt_entry, sizeof(struct _gpt_entry));
49 		}
50 
51 		printf("\nImage appears to have GUID Partition Table with %d HFS+ partition%s.\n", pn, pn == 1 ? "" : "s");
52 		if (pn > 0) {
53 			printf("You should be able to mount %s [as root] by:\n\n", pn == 1 ? "it" : "them");
54 			printf("modprobe hfsplus\n");
55 			for (i = 0; i < pn; i++) {
56 				sprintf(tmp, " (for partition %d)", i + 1);
57 				printf("mount -t hfsplus -o loop,offset=%" PRIu64 " %s /mnt%s\n", gpt_ent_array[i].ent_lba_start * 0x200, filename, pn > 1 ? tmp : "");
58 			}
59 		} else {
60 			printf("\
61 But you might be able to mount the image [as root] by:\n\n\
62 modprobe hfsplus\n\
63 mount -t hfsplus -o loop %s /mnt\n\n", filename);
64 		}
65 		if (F != NULL)
66 			fclose(F);
67 
68 		free(gpt_ent_array);
69 	} else {
70 		printf("\n\
71 You should be able to mount the image [as root] by:\n\n\
72 modprobe hfsplus\n\
73 mount -t hfsplus -o loop %s /mnt\n\n", filename);
74 	}
75 	return (pn);
76 }
77