📄 volume.c
字号:
/* @(#)volume.c 1.6 00/04/27 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */#ifndef lintstatic char sccsid[] = "@(#)volume.c 1.6 00/04/27 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson";#endif/* * Copyright (c) 1997, 1998, 1999, 2000 James Pearson * * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//* * volume.c: prepare HFS volume for mkhybrid * * James Pearson 17/7/97 * modified JCP 29/7/97 to improve allocation sizes to cut * down on wasted space. Now uses the HFS "allocation" size rounded * up to the nearest 2048 bytes. Savings can be significant with * a large volume containing lots of smallish files. * * Updated for v1.12 - now uses the built in RELOCATED_DIRECTORY * flag for finding the real directory location JCP 8/1/97 */#ifdef APPLE_HYB#include "config.h"#include "mkisofs.h"#include <errno.h>#define HFS_MIN_SIZE 1600 /* 800k == 1600 HFS blocks */static hfsvol *vol_save = 0; /* used to "destroy" an HFS volume */static int AlcSiz __PR((int));static int XClpSiz __PR((int));static int get_vol_size __PR((int)); int make_mac_volume __PR((struct directory *, int));static int copy_to_mac_vol __PR((hfsvol *, struct directory *));static void set_dir_info __PR((hfsvol *, struct directory *));/* * AlcSiz: find allocation size for given volume size */static intAlcSiz(vlen) int vlen;{ int lpa, drAlBlkSiz; /* code extracted from hfs_format() */ lpa = 1 + vlen / 65536; drAlBlkSiz = lpa * HFS_BLOCKSZ; /* * now set our "allocation size" to the allocation block rounded up to * the nearest SECTOR_SIZE (2048 bytes) */ drAlBlkSiz = ROUND_UP(drAlBlkSiz, SECTOR_SIZE); return (drAlBlkSiz);}/* * XClpSiz: find the default size of the catalog/extent file */static intXClpSiz(vlen) int vlen;{ int olpa, lpa, drNmAlBlks, drAlBlkSiz; int vbmsz, drXTClpSiz; /* code extracted from hfs_format() */ /* get the lpa from our calculated allocation block size */ drAlBlkSiz = AlcSiz(vlen); lpa = drAlBlkSiz / HFS_BLOCKSZ; vbmsz = (vlen / lpa + 4095) / 4096; drNmAlBlks = (vlen - 5 - vbmsz) / lpa; drXTClpSiz = drNmAlBlks / 128 * drAlBlkSiz; /* * make allowances because we have possibly rounded up the * allocation size get the "original" lpa " */ olpa = 1 + vlen / 65536; /* adjust size upwards */ drXTClpSiz = (drXTClpSiz * lpa) / olpa; /* round up to the nearest alloaction size */ drXTClpSiz = ROUND_UP(drXTClpSiz, drAlBlkSiz); return (drXTClpSiz);}/* * get_vol_size: get the size of the volume including the extent/catalog */static intget_vol_size(vblen) int vblen;{ int drXTClpSiz; int drAlBlkSiz; int new_vblen; /* * try to estimate a "volume size" based on the code in hfs_format * - we need the size of the catalog/extents and Desktop files included * in the volume, as we add this to the end of the ISO volume */ drXTClpSiz = XClpSiz(vblen); drAlBlkSiz = AlcSiz(vblen); /* * catalog file is set at CTC times (default twice) the extents * file size - hence the (ctc_size + 1) below. The Desktop starts of * the same size as the "clump size" == 4 x drAlBlkSiz, * plus a spare drAlBlkSiz for the alternative MDB */ new_vblen = vblen + ((hce->ctc_size + 1) * drXTClpSiz + 5 * drAlBlkSiz) / HFS_BLOCKSZ; return (new_vblen);}/* * write_fork: "write" file data to the volume * * This is used to update the HFS file internal structures * but no data is actually written (it's trapped deep down in * libhfs). */intwrite_fork(hfp, tot) hfsfile *hfp; long tot;{ char blk[HFS_BLOCKSZ]; unsigned short start; long len; len = tot; /* we need to know where this fork starts */ start = hfs_get_drAllocPtr(hfp); /* loop through the data a block at a time */ while (len >= HFS_BLOCKSZ) { if (hfs_write(hfp, blk, HFS_BLOCKSZ) < 0) return (-1); len -= HFS_BLOCKSZ; } /* write out anything left */ if (len) if (hfs_write(hfp, blk, len) < 0) return (-1); /* * set the start of the allocation search to be immediately after * this fork */ hfs_set_drAllocPtr(hfp, start, tot); return (0);}/* * make_mac_volume: "create" an HFS volume using the ISO data * * The HFS volume structures are set up (but no data is written yet). * * ISO volumes have a allocation size of 2048 bytes - regardless * of the size of the volume. HFS allocation size is depends on volume * size, so we may have to update the ISO structures to add in any * padding. */intmake_mac_volume(dpnt, start_extent) struct directory *dpnt; int start_extent;{ char vol_name[HFS_MAX_VLEN + 1]; /* Mac volume name */ hfsvol *vol; /* Mac volume */ int vlen, vblen; /* vol length (bytes, blocks) */ int Csize, lastCsize; /* allocation sizes */ int ret = 0; /* return value */ int loop = 1; /* umount volume if we have had a previous attempt */ if (vol_save) if (hfs_umount(vol_save, 0) < 0) return (-1); /* set the default clump size to the ISO block size */ Csize = lastCsize = SECTOR_SIZE; if (verbose > 1) fprintf(stderr, "Creating HFS Volume info\n"); /* name or copy ISO volume name to Mac Volume name */ strncpy(vol_name, hfs_volume_id ? hfs_volume_id : volume_id, HFS_MAX_VLEN); vol_name[HFS_MAX_VLEN] = '\0'; /* get initial size of HFS volume (size of current ISO volume) */ vblen = (last_extent - session_start) * HFS_BLK_CONV; /* make sure volume is at least 800k */ if (vblen < HFS_MIN_SIZE) vblen += insert_padding_file(HFS_MIN_SIZE - vblen); /* * add on size of extents/catalog file, but this may mean the * allocation size will change, so loop round until the * allocation size doesn't change */ while (loop) { hce->XTCsize = XClpSiz(vblen); vblen = get_vol_size(vblen); Csize = AlcSiz(vblen); if (Csize == lastCsize) { /* allocation size hasn't changed, so carry on */ loop = 0; } else { /* * allocation size has changed, so update * ISO volume size */ if ((vlen = get_adj_size(Csize)) < 0) { sprintf(hce->error, "too many files for HFS volume"); return (-1); } vlen += ROUND_UP((start_extent - session_start) * SECTOR_SIZE, Csize); vblen = vlen / HFS_BLOCKSZ; lastCsize = Csize; } } /* set vlen to size in bytes */ /* take off the label/map size */ vblen -= hce->hfs_map_size; vlen = hce->hfs_vol_size = vblen * HFS_BLOCKSZ; /* set the default allocation size for libhfs */ hce->Csize = Csize; /* format and mount the "volume" */ if (hfs_format(hce, 0, vol_name) < 0) { sprintf(hce->error, "can't HFS format %s", vol_name); return (-1); } /* * update the ISO structures with new start extents and any * padding required */ if (Csize != SECTOR_SIZE) { last_extent = adj_size(Csize, start_extent, hce->hfs_hdr_size + hce->hfs_map_size); adj_size_other(dpnt); } if ((vol = hfs_mount(hce, 0, 0)) == 0) { sprintf(hce->error, "can't HFS mount %s", vol_name); return (-1); } /* save the volume for possible later use */ vol_save = vol; /* * Recursively "copy" the files to the volume * - we need to know the first allocation block in the volume as * starting blocks of files are relative to this. */ ret = copy_to_mac_vol(vol, dpnt); if (ret < 0) return (ret); /* * make the Desktop files - I *think* this stops the Mac rebuilding the * desktop when the CD is mounted on a Mac These will be ignored if they * already exist */ if (create_dt) ret = make_desktop(vol, (last_extent - session_start) * HFS_BLK_CONV); if (ret < 0) return (ret); /* close the volume */ if (hfs_flush(vol) < 0) return (-1); /* unmount and set the start blocks for the catalog/extents files */ if (hfs_umount(vol, (last_extent - session_start) * HFS_BLK_CONV) < 0) return (-1); return (Csize);}#define TEN 10 /* well, it is! */#define LCHAR "_"/* copy_to_mac_vol: copy all files in a directory to corresponding * Mac folder. * * Files are copied recursively to corresponding folders on the Mac * volume. The caller routine needs to do a hfs_chdir before calling this * routine. */static intcopy_to_mac_vol(vol, node) hfsvol *vol; struct directory *node;{ struct directory_entry *s_entry; /* ISO directory entry */ struct directory_entry *s_entry1; /* tmp ISO directory entry */ struct directory *dpnt; /* ISO directory */ hfsfile *hfp; /* HFS file */ hfsdirent *ent; /* HFS file entities */ long id; /* current HFS folder */ long dext, rext; /* real data/rsrc start blk */ int ret; /* result code */ int new_name; /* HFS file has modified name */ int tens; int digits; int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -