diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2012-12-31 05:04:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2012-12-31 05:04:42 +0400 |
commit | 71dc8760ff4de5f365330d1bc571d934deb54af9 (patch) | |
tree | 7346d42a282562a3937d82307012b5857d642ce6 /libhfs_iso/block.c | |
download | cdrkit-71dc8760ff4de5f365330d1bc571d934deb54af9.tar.gz |
Imported Upstream version 1.1.11upstream/1.1.11upstream
Diffstat (limited to 'libhfs_iso/block.c')
-rw-r--r-- | libhfs_iso/block.c | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/libhfs_iso/block.c b/libhfs_iso/block.c new file mode 100644 index 0000000..bbca145 --- /dev/null +++ b/libhfs_iso/block.c @@ -0,0 +1,219 @@ +/* + * This file has been modified for the cdrkit suite. + * + * The behaviour and appearence of the program code below can differ to a major + * extent from the version distributed by the original author(s). + * + * For details, see Changelog file distributed with the cdrkit package. If you + * received this file from another source then ask the distributing person for + * a log of modifications. + * + */ + +/* @(#)block.c 1.3 01/11/01 joerg */ +/* + * hfsutils - tools for reading and writing Macintosh HFS volumes + * Copyright (C) 1996, 1997 Robert Leslie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <mconfig.h> +#include <strdefs.h> +#include <unixstd.h> +#include <errno.h> + +#include "internal.h" +#include "data.h" +#include "block.h" +#include "low.h" + +#ifdef DEBUG +#include <stdio.h> +#endif /* DEBUG */ + +/* + * NAME: block->readlb() + * DESCRIPTION: read a logical block from a volume + */ +int b_readlb(hfsvol *vol, unsigned long num, block *bp) +{ +#ifndef APPLE_HYB + int bytes; +#endif +#ifdef APPLE_HYB + block *b; + hce_mem *hce; + +#ifdef DEBUG + fprintf(stderr,"b_readlb: start block = %d\n", vol->vstart + num); +#endif /* DEBUG */ + + hce = vol->hce; + +/* Check to see if requested block is in the HFS header or catalog/exents + files. If it is, read info from memory copy. If not, then something + has gone horribly wrong ... */ + + if (num < hce->hfs_hdr_size) + b = (block *)hce->hfs_hdr + num; + else if (num < hce->hfs_hdr_size + hce->hfs_ce_size) + b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size; + else + { + ERROR(EIO, "should not happen!"); + return -1; + } + + memcpy(bp, b, HFS_BLOCKSZ); + +#else + + if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0) + { + ERROR(errno, "error seeking device"); + return -1; + } + + bytes = read(vol->fd, bp, HFS_BLOCKSZ); + if (bytes < 0) + { + ERROR(errno, "error reading from device"); + return -1; + } + else if (bytes == 0) + { + ERROR(EIO, "read EOF on volume"); + return -1; + } + else if (bytes != HFS_BLOCKSZ) + { + ERROR(EIO, "read incomplete block"); + return -1; + } +#endif /* APPLE_HYB */ + return 0; +} + +/* + * NAME: block->writelb() + * DESCRIPTION: write a logical block to a volume + */ +int b_writelb(hfsvol *vol, unsigned long num, block *bp) +{ +#ifndef APPLE_HYB + int bytes; +#endif +#ifdef APPLE_HYB + block *b; + hce_mem *hce; + +#ifdef DEBUG + fprintf(stderr,"b_writelb: start block = %d\n", vol->vstart + num); +#endif /* DEBUG */ + + hce = vol->hce; + +/* Check to see if requested block is in the HFS header or catalog/exents + files. If it is, write info to memory copy. If not, then it's a block + for an ordinary file - and as we are writing the files later, then just + ignore and return OK */ + if (num < hce->hfs_hdr_size) + b = (block *)hce->hfs_hdr + num; + else if (num < hce->hfs_hdr_size + hce->hfs_ce_size) + b = (block *)hce->hfs_ce + num - hce->hfs_hdr_size; + else + { +#ifdef DEBUG + fprintf(stderr,"b_writelb: ignoring\n"); +#endif /* DEBUG */ + return 0; + } + + memcpy(b, bp, HFS_BLOCKSZ); + +#else + + if (lseek(vol->fd, (vol->vstart + num) * HFS_BLOCKSZ, SEEK_SET) < 0) + { + ERROR(errno, "error seeking device"); + return -1; + } + + bytes = write(vol->fd, bp, HFS_BLOCKSZ); + + if (bytes < 0) + { + ERROR(errno, "error writing to device"); + return -1; + } + else if (bytes != HFS_BLOCKSZ) + { + ERROR(EIO, "wrote incomplete block"); + return -1; + } +#endif /* APPLE_HYB */ + return 0; +} + +/* + * NAME: block->readab() + * DESCRIPTION: read a block from an allocation block from a volume + */ +int b_readab(hfsvol *vol, unsigned int anum, unsigned int idx, block *bp) +{ + /* verify the allocation block exists and is marked as in-use */ + + if (anum >= vol->mdb.drNmAlBlks) + { + ERROR(EIO, "read nonexistent block"); + return -1; + } + else if (vol->vbm && ! BMTST(vol->vbm, anum)) + { + ERROR(EIO, "read unallocated block"); + return -1; + } + + return b_readlb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp); +} + +/* + * NAME: b->writeab() + * DESCRIPTION: write a block to an allocation block to a volume + */ +int b_writeab(hfsvol *vol, unsigned int anum, unsigned int idx, block *bp) +{ + /* verify the allocation block exists and is marked as in-use */ + + if (anum >= vol->mdb.drNmAlBlks) + { + ERROR(EIO, "write nonexistent block"); + return -1; + } + else if (vol->vbm && ! BMTST(vol->vbm, anum)) + { + ERROR(EIO, "write unallocated block"); + return -1; + } + + vol->mdb.drAtrb &= ~HFS_ATRB_UMOUNTED; + vol->mdb.drLsMod = d_tomtime(time(0)); + ++vol->mdb.drWrCnt; + + vol->flags |= HFS_UPDATE_MDB; + + return b_writelb(vol, vol->mdb.drAlBlSt + anum * vol->lpa + idx, bp); +} |