patch genisoimage multi extent
[platform/upstream/cdrkit.git] / genisoimage / apple_driver.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)apple_driver.c   1.6 04/03/04 joerg */
14 /*
15  *      apple_driver.c: extract Mac partition label, maps and boot driver
16  *
17  *      Based on Apple_Driver.pl, part of "genisoimage 1.05 PLUS" by Andy Polyakov
18  *      <appro@fy.chalmers.se> (I don't know Perl, so I rewrote it C ...)
19  *      (see http://fy.chalmers.se/~appro/genisoimage_plus.html for details)
20  *
21  *      usage: apple_driver CDROM_device > HFS_driver_file
22  *
23  *      The format of the HFS driver file:
24  *
25  *      HFS CD Label Block                              512 bytes
26  *      Driver Partition Map (for 2048 byte blocks)     512 bytes
27  *      Driver Partition Map (for 512 byte blocks)      512 bytes
28  *      Empty                                           512 bytes
29  *      Driver Partition                                N x 2048 bytes
30  *      HFS Partition Boot Block                        1024 bytes
31  *
32  *      By extracting a driver from an Apple CD, you become liable to obey
33  *      Apple Computer, Inc. Software License Agreements.
34  *
35  *      James Pearson 17/5/98
36  */
37
38 #include <mconfig.h>
39 #include "genisoimage.h"
40 #include <mac_label.h>
41 #include <schily.h>
42
43 int     get_732(char *p);
44 int     get_722(char *p);
45
46 int
47 get_732(char *p)
48 {
49         return ((p[3] & 0xff)
50                 | ((p[2] & 0xff) << 8)
51                 | ((p[1] & 0xff) << 16)
52                 | ((p[0] & 0xff) << 24));
53 }
54
55 int
56 get_722(char *p)
57 {
58         return ((p[1] & 0xff)
59                 | ((p[0] & 0xff) << 8));
60 }
61
62 #if 0
63 EXPORT int
64 main(argc, argv)
65         int     argc;
66         char    **argv;
67 {
68         FILE            *fp;
69         MacLabel        *mac_label;
70         MacPart         *mac_part;
71         unsigned char   Block0[HFS_BLOCKSZ];
72         unsigned char   block[SECTOR_SIZE];
73         unsigned char   bootb[2*HFS_BLOCKSZ];
74         unsigned char   pmBlock512[HFS_BLOCKSZ];
75         unsigned int    sbBlkSize;
76         unsigned int    pmPyPartStart;
77         unsigned int    pmPartStatus;
78         unsigned int    pmMapBlkCnt;
79         int             have_boot = 0, have_hfs = 0;
80         int             hfs_start;
81         int             i, j;
82
83
84         save_args(argc, argv);
85
86         if (argc != 2)
87             comerrno(EX_BAD, "Usage: %s device-path", argv[0]);
88
89         if ((fp = fopen(argv[1], "rb")) == NULL)
90             comerr("Can't open '%s'.", argv[1]);
91
92         if (fread(Block0, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
93             comerr("Can't read '%s'.", argv[1]);
94
95         mac_label = (MacLabel *)Block0;
96         mac_part = (MacPart *)block;
97
98         sbBlkSize = get_722((char *)mac_label->sbBlkSize);
99
100         if (! IS_MAC_LABEL(mac_label) || sbBlkSize != SECTOR_SIZE)
101             comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]);
102
103         i = 1;
104         do {
105                 if (fseek(fp, i * HFS_BLOCKSZ, SEEK_SET) != 0)
106                         comerr("Ccan't seek %s", argv[1]);
107
108                 if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
109                         comerr("Can't read '%s'.", argv[1]);
110
111                 pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt);
112
113                 if (!have_boot && strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) {
114                         hfs_start = get_732((char *)mac_part->pmPyPartStart);
115
116                         fprintf(stderr, "%s: found 512 driver partition (at block %d)\n", argv[0], hfs_start);
117                         memcpy(pmBlock512, block, HFS_BLOCKSZ);
118                         have_boot = 1;
119                 }
120
121                 if (!have_hfs && strncmp((char *)mac_part->pmPartType, pmPartType_4, 9) == 0) {
122
123                         hfs_start = get_732((char *)mac_part->pmPyPartStart);
124
125                         if (fseek(fp, hfs_start*HFS_BLOCKSZ, SEEK_SET) != 0)
126                                 comerr("Can't seek '%s'.", argv[1]);
127
128                         if (fread(bootb, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
129                                 comerr("Can't read '%s'.", argv[1]);
130
131                         if (get_722((char *)bootb) == 0x4c4b) {
132
133                                 fprintf(stderr, "%s: found HFS partition (at blk %d)\n", argv[0], hfs_start);
134                                 have_hfs = 1;
135                         }
136                 }
137         } while (i++ < pmMapBlkCnt);
138
139         if (!have_hfs || !have_boot)
140                 comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]);
141
142         i = 1;
143
144         do {
145                 if (fseek(fp, i*sbBlkSize, SEEK_SET) != 0)
146                         comerr("Can't seek '%s'.", argv[1]);
147
148                 if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
149                         comerr("Can't read '%s'.", argv[1]);
150
151                 pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt);
152
153                 if (strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) {
154
155                         int     start, num;
156
157                         fprintf(stderr, "%s: extracting %s ", argv[0], mac_part->pmPartType);
158                         start = get_732((char *)mac_part->pmPyPartStart);
159                         num = get_732((char *)mac_part->pmPartBlkCnt);
160                         fwrite(Block0, 1, HFS_BLOCKSZ, stdout);
161                         fwrite(block, 1, HFS_BLOCKSZ, stdout);
162                         fwrite(pmBlock512, 1, HFS_BLOCKSZ, stdout);
163                         memset(block, 0, HFS_BLOCKSZ);
164                         fwrite(block, 1, HFS_BLOCKSZ, stdout);
165
166                         if (fseek(fp, start*sbBlkSize, SEEK_SET) != 0)
167                                 comerr("Can't seek '%s'.", argv[1]);
168
169                         for (j = 0; j < num; j++) {
170                                 if (fread(block, 1, sbBlkSize, fp) != sbBlkSize)
171                                         comerr("Can't read '%s'.", argv[1]);
172
173                                 fwrite(block, 1, sbBlkSize, stdout);
174                                 fprintf(stderr, ".");
175                         }
176                         fprintf(stderr, "\n");
177
178                         fwrite(bootb, 2, HFS_BLOCKSZ, stdout);
179                         fclose(fp);
180                         exit(0);
181                 }
182
183                 if (!IS_MAC_PART(mac_part))
184                         comerrno(EX_BAD, "Unable to find boot partition");
185
186         } while (i++ < pmMapBlkCnt);
187
188         return (0);
189 }
190 #endif