patch: make *outfile extern
[platform/upstream/cdrkit.git] / libhfs_iso / block.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 /* @(#)block.c  1.3 01/11/01 joerg */
14 /*
15  * hfsutils - tools for reading and writing Macintosh HFS volumes
16  * Copyright (C) 1996, 1997 Robert Leslie
17  *
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 2 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31  */
32
33 #include <mconfig.h>
34 #include <strdefs.h>
35 #include <unixstd.h>
36 #include <errno.h>
37
38 #include "internal.h"
39 #include "data.h"
40 #include "block.h"
41 #include "low.h"
42
43 #ifdef DEBUG
44 #include <stdio.h>
45 #endif /* DEBUG */
46
47 /*
48  * NAME:        block->readlb()
49  * DESCRIPTION: read a logical block from a volume
50  */
51 int b_readlb(hfsvol *vol, unsigned long num, block *bp)
52 {
53 #ifndef APPLE_HYB
54   int bytes;
55 #endif
56 #ifdef APPLE_HYB
57   block *b;
58   hce_mem *hce;
59
60 #ifdef DEBUG
61   fprintf(stderr,"b_readlb: start block = %d\n", vol->vstart + num);
62 #endif /* DEBUG */
63
64   hce = vol->hce;
65
66 /* Check to see if requested block is in the HFS header or catalog/exents
67    files. If it is, read info from memory copy. If not, then something
68    has gone horribly wrong ... */
69
70   if (num < hce->hfs_hdr_size) 
71       b = (block *)hce->hfs_hdr + num;
72   else if (num < hce->hfs_hdr_size + hce->hfs_ce_size)
73       b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size;
74   else
75     {
76       ERROR(EIO, "should not happen!");
77       return -1;
78     }
79
80   memcpy(bp, b, HFS_BLOCKSZ);
81
82 #else
83
84   if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0)
85     {
86       ERROR(errno, "error seeking device");
87       return -1;
88     }
89
90   bytes = read(vol->fd, bp, HFS_BLOCKSZ);
91   if (bytes < 0)
92     {
93       ERROR(errno, "error reading from device");
94       return -1;
95     }
96   else if (bytes == 0)
97     {
98       ERROR(EIO, "read EOF on volume");
99       return -1;
100     }
101   else if (bytes != HFS_BLOCKSZ)
102     {
103       ERROR(EIO, "read incomplete block");
104       return -1;
105     }
106 #endif /* APPLE_HYB */
107   return 0;
108 }
109
110 /*
111  * NAME:        block->writelb()
112  * DESCRIPTION: write a logical block to a volume
113  */
114 int b_writelb(hfsvol *vol, unsigned long num, block *bp)
115 {
116 #ifndef APPLE_HYB
117   int bytes;
118 #endif
119 #ifdef APPLE_HYB
120   block *b;
121   hce_mem *hce;
122
123 #ifdef DEBUG
124   fprintf(stderr,"b_writelb: start block = %d\n", vol->vstart + num);
125 #endif /* DEBUG */
126
127    hce = vol->hce;
128
129 /* Check to see if requested block is in the HFS header or catalog/exents
130    files. If it is, write info to memory copy. If not, then it's a block
131    for an ordinary file - and as we are writing the files later, then just
132    ignore and return OK */
133   if (num < hce->hfs_hdr_size) 
134       b = (block *)hce->hfs_hdr + num;
135   else if (num < hce->hfs_hdr_size + hce->hfs_ce_size)
136       b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size;
137   else
138     {
139 #ifdef DEBUG
140       fprintf(stderr,"b_writelb: ignoring\n");
141 #endif /* DEBUG */
142       return 0;
143     }
144
145   memcpy(b, bp, HFS_BLOCKSZ);
146
147 #else
148
149   if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0)
150     {
151       ERROR(errno, "error seeking device");
152       return -1;
153     }
154
155   bytes = write(vol->fd, bp, HFS_BLOCKSZ);
156
157   if (bytes < 0)
158     {
159       ERROR(errno, "error writing to device");
160       return -1;
161     }
162   else if (bytes != HFS_BLOCKSZ)
163     {
164       ERROR(EIO, "wrote incomplete block");
165       return -1;
166     }
167 #endif /* APPLE_HYB */
168   return 0;
169 }
170
171 /*
172  * NAME:        block->readab()
173  * DESCRIPTION: read a block from an allocation block from a volume
174  */
175 int b_readab(hfsvol *vol, unsigned int anum, unsigned int idx, block *bp)
176 {
177   /* verify the allocation block exists and is marked as in-use */
178
179   if (anum >= vol->mdb.drNmAlBlks)
180     {
181       ERROR(EIO, "read nonexistent block");
182       return -1;
183     }
184   else if (vol->vbm && ! BMTST(vol->vbm, anum))
185     {
186       ERROR(EIO, "read unallocated block");
187       return -1;
188     }
189
190   return b_readlb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp);
191 }
192
193 /*
194  * NAME:        b->writeab()
195  * DESCRIPTION: write a block to an allocation block to a volume
196  */
197 int b_writeab(hfsvol *vol, unsigned int anum, unsigned int idx, block *bp)
198 {
199   /* verify the allocation block exists and is marked as in-use */
200
201   if (anum >= vol->mdb.drNmAlBlks)
202     {
203       ERROR(EIO, "write nonexistent block");
204       return -1;
205     }
206   else if (vol->vbm && ! BMTST(vol->vbm, anum))
207     {
208       ERROR(EIO, "write unallocated block");
209       return -1;
210     }
211
212   vol->mdb.drAtrb &= ~HFS_ATRB_UMOUNTED;
213   vol->mdb.drLsMod = d_tomtime(time(0));
214   ++vol->mdb.drWrCnt;
215
216   vol->flags |= HFS_UPDATE_MDB;
217
218   return b_writelb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp);
219 }