/[pearpc]/src/io/prom/fs/hfs/medium.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /src/io/prom/fs/hfs/medium.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 6588 byte(s)
import upstream CVS
1 dpavlin 1 /*
2     * libhfs - library for reading and writing Macintosh HFS volumes
3     * Copyright (C) 1996-1998 Robert Leslie
4     *
5     * This program is free software; you can redistribute it and/or modify
6     * it under the terms of the GNU General Public License as published by
7     * the Free Software Foundation; either version 2 of the License, or
8     * (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18     *
19     */
20    
21     # ifdef HAVE_CONFIG_H
22     # include "config.h"
23     # endif
24    
25     # include <stdlib.h>
26     # include <string.h>
27     # include <errno.h>
28    
29     # include "libhfs.h"
30     # include "block.h"
31     # include "low.h"
32     # include "medium.h"
33    
34     /* Driver Descriptor Record Routines ======================================= */
35    
36     /*
37     * NAME: medium->zeroddr()
38     * DESCRIPTION: write a new/empty driver descriptor record
39     */
40     int m_zeroddr(hfsvol *vol)
41     {
42     Block0 ddr;
43     int i;
44    
45     ASSERT(vol->pnum == 0 && vol->vlen != 0);
46    
47     ddr.sbSig = HFS_DDR_SIGWORD;
48     ddr.sbBlkSize = HFS_BLOCKSZ;
49     ddr.sbBlkCount = vol->vlen;
50    
51     ddr.sbDevType = 0;
52     ddr.sbDevId = 0;
53     ddr.sbData = 0;
54    
55     ddr.sbDrvrCount = 0;
56    
57     ddr.ddBlock = 0;
58     ddr.ddSize = 0;
59     ddr.ddType = 0;
60    
61     for (i = 0; i < 243; ++i)
62     ddr.ddPad[i] = 0;
63    
64     return l_putddr(vol, &ddr);
65     }
66    
67     /* Partition Map Routines ================================================== */
68    
69     /*
70     * NAME: medium->zeropm()
71     * DESCRIPTION: write new/empty partition map
72     */
73     int m_zeropm(hfsvol *vol, unsigned int maxparts)
74     {
75     ApplePartition map;
76     unsigned int i;
77    
78     ASSERT(vol->pnum == 0 && vol->vlen != 0);
79    
80     if (maxparts < 2)
81     ERROR(EINVAL, "must allow at least 2 partitions");
82    
83     /* first entry: partition map itself */
84    
85     map.pmSig = HFS_PM_SIGWORD;
86     map.pmSigPad = 0;
87     map.pmMapBlkCnt = 2;
88    
89     map.pmPyPartStart = 1;
90     map.pmPartBlkCnt = maxparts;
91    
92     strcpy((char *) map.pmPartName, "Apple");
93     strcpy((char *) map.pmParType, "Apple_partition_map");
94    
95     map.pmLgDataStart = 0;
96     map.pmDataCnt = map.pmPartBlkCnt;
97    
98     map.pmPartStatus = 0;
99    
100     map.pmLgBootStart = 0;
101     map.pmBootSize = 0;
102     map.pmBootAddr = 0;
103     map.pmBootAddr2 = 0;
104     map.pmBootEntry = 0;
105     map.pmBootEntry2 = 0;
106     map.pmBootCksum = 0;
107    
108     strcpy((char *) map.pmProcessor, "");
109    
110     for (i = 0; i < 188; ++i)
111     map.pmPad[i] = 0;
112    
113     if (l_putpmentry(vol, &map, 1) == -1)
114     goto fail;
115    
116     /* second entry: rest of medium */
117    
118     map.pmPyPartStart = 1 + maxparts;
119     map.pmPartBlkCnt = vol->vlen - 1 - maxparts;
120    
121     strcpy((char *) map.pmPartName, "Extra");
122     strcpy((char *) map.pmParType, "Apple_Free");
123    
124     map.pmDataCnt = map.pmPartBlkCnt;
125    
126     if (l_putpmentry(vol, &map, 2) == -1)
127     goto fail;
128    
129     /* zero rest of partition map's partition */
130    
131     if (maxparts > 2)
132     {
133     block b;
134    
135     memset(&b, 0, sizeof(b));
136    
137     for (i = 3; i <= maxparts; ++i)
138     {
139     if (b_writepb(vol, i, &b, 1) == -1)
140     goto fail;
141     }
142     }
143    
144     return 0;
145    
146     fail:
147     return -1;
148     }
149    
150     /*
151     * NAME: medium->findpmentry()
152     * DESCRIPTION: locate a partition map entry
153     */
154     int m_findpmentry(hfsvol *vol, const char *type,
155     ApplePartition *map, unsigned long *start)
156     {
157     unsigned long bnum;
158     int found = 0;
159    
160     if (start && *start > 0)
161     {
162     bnum = *start;
163    
164     /* if (bnum++ >= (unsigned long) map->pmMapBlkCnt) {
165     ERROR(EINVAL, "partition not found");
166     }*/
167     }
168     else
169     bnum = 1;
170    
171     while (1)
172     {
173     if (l_getpmentry(vol, map, bnum) == -1)
174     {
175     found = -1;
176     goto fail;
177     }
178    
179     if (map->pmSig != HFS_PM_SIGWORD)
180     {
181     found = -1;
182    
183     if (map->pmSig == HFS_PM_SIGWORD_OLD)
184     ERROR(EINVAL, "old partition map format not supported");
185     else
186     ERROR(EINVAL, "invalid partition map");
187     }
188    
189     if (strcmp((char *) map->pmParType, type) == 0)
190     {
191     found = 1;
192     goto done;
193     }
194    
195     if (bnum++ >= (unsigned long) map->pmMapBlkCnt) {
196     ERROR(EINVAL, "partition not found");
197     }
198     }
199    
200     done:
201     /* if (start)
202     *start = bnum;*/
203    
204     fail:
205     return found;
206     }
207    
208     /*
209     * NAME: medium->mkpart()
210     * DESCRIPTION: create a new partition from available free space
211     */
212     int m_mkpart(hfsvol *vol,
213     const char *name, const char *type, unsigned long len)
214     {
215     ApplePartition map;
216     unsigned int nparts, maxparts;
217     unsigned long bnum, start, remain;
218     int found;
219    
220     if (strlen(name) > 32 ||
221     strlen(type) > 32)
222     ERROR(EINVAL, "partition name/type can each be at most 32 chars");
223    
224     if (len == 0)
225     ERROR(EINVAL, "partition length must be > 0");
226    
227     found = m_findpmentry(vol, "Apple_partition_map", &map, 0);
228     if (found == -1)
229     goto fail;
230    
231     if (! found)
232     ERROR(EIO, "cannot find partition map's partition");
233    
234     nparts = map.pmMapBlkCnt;
235     maxparts = map.pmPartBlkCnt;
236    
237     bnum = 0;
238     do
239     {
240     found = m_findpmentry(vol, "Apple_Free", &map, &bnum);
241     if (found == -1)
242     goto fail;
243    
244     if (! found)
245     ERROR(ENOSPC, "no available partitions");
246     }
247     while (len > (unsigned long) map.pmPartBlkCnt);
248    
249     start = (unsigned long) map.pmPyPartStart + len;
250     remain = (unsigned long) map.pmPartBlkCnt - len;
251    
252     if (remain && nparts >= maxparts)
253     ERROR(EINVAL, "must allocate all blocks in free space");
254    
255     map.pmPartBlkCnt = len;
256    
257     strcpy((char *) map.pmPartName, name);
258     strcpy((char *) map.pmParType, type);
259    
260     map.pmLgDataStart = 0;
261     map.pmDataCnt = len;
262    
263     map.pmPartStatus = 0;
264    
265     if (l_putpmentry(vol, &map, bnum) == -1)
266     goto fail;
267    
268     if (remain)
269     {
270     map.pmPyPartStart = start;
271     map.pmPartBlkCnt = remain;
272    
273     strcpy((char *) map.pmPartName, "Extra");
274     strcpy((char *) map.pmParType, "Apple_Free");
275    
276     map.pmDataCnt = remain;
277    
278     if (l_putpmentry(vol, &map, ++nparts) == -1)
279     goto fail;
280    
281     for (bnum = 1; bnum <= nparts; ++bnum)
282     {
283     if (l_getpmentry(vol, &map, bnum) == -1)
284     goto fail;
285    
286     map.pmMapBlkCnt = nparts;
287    
288     if (l_putpmentry(vol, &map, bnum) == -1)
289     goto fail;
290     }
291     }
292    
293     return 0;
294    
295     fail:
296     return -1;
297     }
298    
299     /* Boot Blocks Routines ==================================================== */
300    
301     /*
302     * NAME: medium->zerobb()
303     * DESCRIPTION: write new/empty volume boot blocks
304     */
305     int m_zerobb(hfsvol *vol)
306     {
307     block b;
308    
309     memset(&b, 0, sizeof(b));
310    
311     if (b_writelb(vol, 0, &b) == -1 ||
312     b_writelb(vol, 1, &b) == -1)
313     goto fail;
314    
315     return 0;
316    
317     fail:
318     return -1;
319     }

  ViewVC Help
Powered by ViewVC 1.1.26