summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeemant Kulleen <seemant@gentoo.org>2004-03-07 08:19:24 +0000
committerSeemant Kulleen <seemant@gentoo.org>2004-03-07 08:19:24 +0000
commitab08864a2a194a5a4c9690622011cb5909f15400 (patch)
tree02506dbc308e4194d6b3da88fd56dd56bdb6b516 /sys-apps
parentmips keywords don't belong in linux-headers, removing. (diff)
downloadhistorical-ab08864a2a194a5a4c9690622011cb5909f15400.tar.gz
historical-ab08864a2a194a5a4c9690622011cb5909f15400.tar.bz2
historical-ab08864a2a194a5a4c9690622011cb5909f15400.zip
move patches to tarballs on gentoo mirrors. Also switch to the use_enable and use_with syntax in econf
Diffstat (limited to 'sys-apps')
-rw-r--r--sys-apps/parted/ChangeLog11
-rw-r--r--sys-apps/parted/Manifest23
-rw-r--r--sys-apps/parted/files/digest-parted-1.6.51
-rw-r--r--sys-apps/parted/files/digest-parted-1.6.5-r11
-rw-r--r--sys-apps/parted/files/digest-parted-1.6.61
-rw-r--r--sys-apps/parted/files/digest-parted-1.6.6-r11
-rw-r--r--sys-apps/parted/files/parted-1.6.5-gcc-3.3.patch51
-rw-r--r--sys-apps/parted/files/parted-1.6.5-hfs-8.patch3635
-rw-r--r--sys-apps/parted/files/parted-1.6.6-2-6headers.patch17
-rw-r--r--sys-apps/parted/files/parted-1.6.6-assert.patch141
-rw-r--r--sys-apps/parted/files/parted-1.6.6-gcc-3.3.patch36
-rw-r--r--sys-apps/parted/files/parted-1.6.6-hfs-8.patch3636
-rw-r--r--sys-apps/parted/files/parted-1.6.6-hfs-9.patch3887
-rw-r--r--sys-apps/parted/parted-1.6.5-r1.ebuild26
-rw-r--r--sys-apps/parted/parted-1.6.5.ebuild38
-rw-r--r--sys-apps/parted/parted-1.6.6-r1.ebuild28
-rw-r--r--sys-apps/parted/parted-1.6.6.ebuild27
17 files changed, 65 insertions, 11495 deletions
diff --git a/sys-apps/parted/ChangeLog b/sys-apps/parted/ChangeLog
index e019b7af04bd..4eb9ee0f1c90 100644
--- a/sys-apps/parted/ChangeLog
+++ b/sys-apps/parted/ChangeLog
@@ -1,6 +1,15 @@
# ChangeLog for sys-apps/parted
# Copyright 2002-2004 Gentoo Technologies, Inc.; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/ChangeLog,v 1.28 2004/03/07 01:48:34 iluxa Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/ChangeLog,v 1.29 2004/03/07 08:19:24 seemant Exp $
+
+ 07 Mar 2004; Seemant Kulleen <seemant@gentoo.org> parted-1.6.5-r1.ebuild,
+ parted-1.6.5.ebuild, parted-1.6.6-r1.ebuild, parted-1.6.6.ebuild,
+ files/parted-1.6.5-gcc-3.3.patch, files/parted-1.6.5-hfs-8.patch,
+ files/parted-1.6.6-2-6headers.patch, files/parted-1.6.6-assert.patch,
+ files/parted-1.6.6-gcc-3.3.patch, files/parted-1.6.6-hfs-8.patch,
+ files/parted-1.6.6-hfs-9.patch:
+ move patches to tarballs on gentoo mirrors. Also switch to the use_enable and
+ use_with syntax in econf
06 Mar 2004; Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
parted-1.6.6-r1.ebuild:
diff --git a/sys-apps/parted/Manifest b/sys-apps/parted/Manifest
index f751e39d9217..d0eaf3c27adf 100644
--- a/sys-apps/parted/Manifest
+++ b/sys-apps/parted/Manifest
@@ -1,17 +1,8 @@
-MD5 7d005eee74fa06d5bfd23aefa0d66d77 ChangeLog 4533
+MD5 302a6544bbb5c4df38c785653dc2c578 parted-1.6.5-r1.ebuild 1324
+MD5 3a89100445163a054fd7d4da207ea8bf parted-1.6.6.ebuild 1355
+MD5 a7163eb26b2a07e440f620d26e4b35c9 parted-1.6.6-r1.ebuild 1350
+MD5 a56fb44d912fcd179befeb879dc6222e ChangeLog 5029
MD5 9a09f8d531c582e78977dbfd96edc1f2 metadata.xml 164
-MD5 46b500966190e54eff8ede87de4e8466 parted-1.6.5-r1.ebuild 1370
-MD5 20141a34f45705183113e119e0742a03 parted-1.6.5.ebuild 1260
-MD5 3a53143572d8d2d356766b5ca9759911 parted-1.6.6.ebuild 1425
-MD5 c3af8d1b40c7e906ff4f5b8db62b6bdc parted-1.6.6-r1.ebuild 1444
-MD5 c4eb5801edd996be57aabfd201b96711 files/digest-parted-1.6.5 65
-MD5 c4eb5801edd996be57aabfd201b96711 files/digest-parted-1.6.5-r1 65
-MD5 5c05e8c799c1b96a7daa24e5d77af13b files/digest-parted-1.6.6 65
-MD5 98aebf81c63f7c31f615c6c7b57c4eb2 files/parted-1.6.5-gcc-3.3.patch 2221
-MD5 ca37d240601c525a3c9c4e2ce86a85b8 files/parted-1.6.5-hfs-8.patch 110746
-MD5 b484cabe8abad0bf4f3103e92e0579d8 files/parted-1.6.6-gcc-3.3.patch 1453
-MD5 1c74b6306e8e3932d6742760c9b9a7bd files/parted-1.6.6-hfs-8.patch 110701
-MD5 5c05e8c799c1b96a7daa24e5d77af13b files/digest-parted-1.6.6-r1 65
-MD5 e16c7c8de3af17f52a7dc9b96f4ae8c1 files/parted-1.6.6-2-6headers.patch 549
-MD5 5fd83a5087fd78bdb4a2521865f9bfb8 files/parted-1.6.6-assert.patch 4484
-MD5 b1cea5b1df822639ac9c34e612b2cdab files/parted-1.6.6-hfs-9.patch 118794
+MD5 6f43c57a0726ccc02e6c72f846b38b4d files/digest-parted-1.6.5-r1 136
+MD5 5d070cbf01c5069caea1fca614e23fda files/digest-parted-1.6.6-r1 139
+MD5 b020ac3a8080ad690bb3ce376e5273bb files/digest-parted-1.6.6 136
diff --git a/sys-apps/parted/files/digest-parted-1.6.5 b/sys-apps/parted/files/digest-parted-1.6.5
deleted file mode 100644
index a7eda273b070..000000000000
--- a/sys-apps/parted/files/digest-parted-1.6.5
+++ /dev/null
@@ -1 +0,0 @@
-MD5 8a5be3262685d0854165960d31392a94 parted-1.6.5.tar.gz 1168153
diff --git a/sys-apps/parted/files/digest-parted-1.6.5-r1 b/sys-apps/parted/files/digest-parted-1.6.5-r1
index a7eda273b070..191e809fc1d4 100644
--- a/sys-apps/parted/files/digest-parted-1.6.5-r1
+++ b/sys-apps/parted/files/digest-parted-1.6.5-r1
@@ -1 +1,2 @@
MD5 8a5be3262685d0854165960d31392a94 parted-1.6.5.tar.gz 1168153
+MD5 e491781b10088e3db5e584771cb2a6ec parted-1.6.5-gentoo.tar.bz2 17823
diff --git a/sys-apps/parted/files/digest-parted-1.6.6 b/sys-apps/parted/files/digest-parted-1.6.6
index 70e4af8b02bb..bca96d39898d 100644
--- a/sys-apps/parted/files/digest-parted-1.6.6
+++ b/sys-apps/parted/files/digest-parted-1.6.6
@@ -1 +1,2 @@
MD5 563ab3855124c2ed706ea71eb8e47cf5 parted-1.6.6.tar.gz 1255043
+MD5 e67c1e85b24b337a88ae0bba19280956 parted-1.6.6-gentoo.tar.bz2 17859
diff --git a/sys-apps/parted/files/digest-parted-1.6.6-r1 b/sys-apps/parted/files/digest-parted-1.6.6-r1
index 70e4af8b02bb..8ffab8b0acc9 100644
--- a/sys-apps/parted/files/digest-parted-1.6.6-r1
+++ b/sys-apps/parted/files/digest-parted-1.6.6-r1
@@ -1 +1,2 @@
MD5 563ab3855124c2ed706ea71eb8e47cf5 parted-1.6.6.tar.gz 1255043
+MD5 e1594a682d866001890682a54b525f18 parted-1.6.6-r1-gentoo.tar.bz2 20002
diff --git a/sys-apps/parted/files/parted-1.6.5-gcc-3.3.patch b/sys-apps/parted/files/parted-1.6.5-gcc-3.3.patch
deleted file mode 100644
index 86c6c5d1060e..000000000000
--- a/sys-apps/parted/files/parted-1.6.5-gcc-3.3.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-diff -ruN parted-1.6.5.orig/libparted/disk_gpt.c parted-1.6.5/libparted/disk_gpt.c
---- parted-1.6.5.orig/libparted/disk_gpt.c 2003-06-27 18:11:23.000000000 +0200
-+++ parted-1.6.5/libparted/disk_gpt.c 2003-06-27 17:15:53.000000000 +0200
-@@ -51,9 +51,9 @@
- #define EFI_PMBR_OSTYPE_EFI 0xEE
- #define MSDOS_MBR_SIGNATURE 0xaa55
-
--#define GPT_HEADER_SIGNATURE 0x5452415020494645
--#define GPT_HEADER_REVISION_V1_00 0x00010000
--#define GPT_HEADER_REVISION_V0_99 0x00009900
-+#define GPT_HEADER_SIGNATURE 0x5452415020494645LL
-+#define GPT_HEADER_REVISION_V1_00 0x00010000LL
-+#define GPT_HEADER_REVISION_V0_99 0x00009900LL
-
- typedef uint16_t efi_char16_t; /* UNICODE character */
-
-diff -ruN parted-1.6.5.orig/libparted/disk_sun.c parted-1.6.5/libparted/disk_sun.c
---- parted-1.6.5.orig/libparted/disk_sun.c 2003-06-27 18:11:23.000000000 +0200
-+++ parted-1.6.5/libparted/disk_sun.c 2003-06-27 17:28:14.000000000 +0200
-@@ -38,7 +38,7 @@
- /* Most of this came from util-linux's sun support, which was mostly done
- by Jakub Jelinek. */
-
--#define SUN_DISK_MAGIC 0xDABE /* Disk magic number */
-+#define SUN_DISK_MAGIC 0xDABE /* Disk magic number */
- #define SUN_DISK_MAXPARTITIONS 8
-
- #define WHOLE_DISK_ID 0x05
-@@ -354,7 +354,7 @@
- if (!ped_device_read (disk->dev, &old_label, 0, 1))
- return;
- if (old_label.info [0]
-- && old_label.magic == PED_CPU_TO_LE32 (SUN_DISK_MAGIC))
-+ && old_label.magic == PED_CPU_TO_LE16 (SUN_DISK_MAGIC))
- memcpy (&sun_specific->raw_label, &old_label, 512);
- }
-
-diff -ruN parted-1.6.5.orig/libparted/fs_ext2/ext2.c parted-1.6.5/libparted/fs_ext2/ext2.c
---- parted-1.6.5.orig/libparted/fs_ext2/ext2.c 2003-06-27 18:11:23.000000000 +0200
-+++ parted-1.6.5/libparted/fs_ext2/ext2.c 2003-06-27 18:14:52.000000000 +0200
-@@ -355,8 +355,8 @@
- inode->i_blocks = PED_CPU_TO_LE32(EXT2_INODE_BLOCKS(*inode)
- + delta * i512perblock);
- size = EXT2_INODE_SIZE(*inode) + delta * fs->blocksize;
-- inode->i_size = PED_CPU_TO_LE32(size % 0x100000000);
-- inode->i_size_high = PED_CPU_TO_LE32(size / 0x100000000);
-+ inode->i_size = PED_CPU_TO_LE32(size % 0x100000000LL);
-+ inode->i_size_high = PED_CPU_TO_LE32(size / 0x100000000LL);
- inode->i_mtime = PED_CPU_TO_LE32(time(NULL));
- }
-
diff --git a/sys-apps/parted/files/parted-1.6.5-hfs-8.patch b/sys-apps/parted/files/parted-1.6.5-hfs-8.patch
deleted file mode 100644
index ffaea6de7261..000000000000
--- a/sys-apps/parted/files/parted-1.6.5-hfs-8.patch
+++ /dev/null
@@ -1,3635 +0,0 @@
-diff -u -r -N parted-1.6.5/AUTHORS parted-1.6.5-hfs/AUTHORS
---- parted-1.6.5/AUTHORS Wed Jun 26 04:29:49 2002
-+++ parted-1.6.5-hfs/AUTHORS Tue Apr 29 05:46:52 2003
-@@ -137,3 +137,6 @@
- Bernardo João Torres da Silveira <bernardojt@ig.com.br>
- * pt_BR translation of FAQ and parted.texi
-
-+Guillaume Knispel <k_guillaume@libertysurf.fr>
-+ * nearly all hfs and hfs+ code (libparted/fs_hfs)
-+ * hfs+ support for mac partitions (libparted/disk_mac.c)
-diff -u -r -N parted-1.6.5/libparted/disk_mac.c parted-1.6.5-hfs/libparted/disk_mac.c
---- parted-1.6.5/libparted/disk_mac.c Mon Apr 8 12:08:03 2002
-+++ parted-1.6.5-hfs/libparted/disk_mac.c Tue Apr 29 05:47:10 2003
-@@ -1068,7 +1068,8 @@
- return 1;
- }
-
-- if (fs_type && !strcmp (fs_type->name, "hfs")) {
-+ if (fs_type && ( !strcmp (fs_type->name, "hfs")
-+ || !strcmp (fs_type->name, "hfs+"))) {
- strcpy (mac_data->system_name, "Apple_HFS");
- mac_data->status |= 0x7f;
- } else {
-@@ -1082,7 +1083,6 @@
- static int
- mac_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
- {
-- PedFileSystemType* hfs = ped_file_system_type_get ("hfs");
- MacPartitionData* mac_data;
-
- PED_ASSERT (part != NULL, return 0);
-diff -u -r -N parted-1.6.5/libparted/fs_hfs/hfs.c parted-1.6.5-hfs/libparted/fs_hfs/hfs.c
---- parted-1.6.5/libparted/fs_hfs/hfs.c Mon Apr 8 12:10:25 2002
-+++ parted-1.6.5-hfs/libparted/fs_hfs/hfs.c Tue Apr 29 05:48:04 2003
-@@ -1,6 +1,6 @@
- /*
- libparted - a library for manipulating disk partitions
-- Copyright (C) 2000 Free Software Foundation, Inc.
-+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
-
- 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
-@@ -17,10 +17,52 @@
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-+/*
-+ Technical doc about Apple HFS and HFS+ file systems is available at :
-+ * For HFS, section "Data Organization on Volumes",
-+ "Chapter 2 - File Manager"
-+ of the book "Inside Macintosh: Files"
-+ http://developer.apple.com/techpubs/mac/Files/Files-99.html#HEADING99-0
-+ * For HFS+, "Technical Note TN1150", "HFS Plus Volume Format"
-+ http://developer.apple.com/technotes/tn/tn1150.html
-+
-+ Some useful HFS precisions concerning alignement and bit ordering
-+ are in the HFS+ TN
-+*/
-+
-+/* HISTORY :
-+## modifications dd-mm-yyyy
-+---------------------- PATCH FOR PARTED 1.6.5 ----------------------------
-+ 1 initial revision 07-04-2003
-+ 2 one pass resizing, removal of debug info 08-04-2003
-+ 3 safe abort if resize failed, code cleanups, timer, 10-04-2003
-+ source file split, won't resize if not unmounted,
-+ only relocate data if needed, minimize disk operations
-+ 4 memory leaks removal, code cleanups, resize hfs+ code, 17-04-2003
-+ more checks, minor hfs resize bugfix, probe code
-+ returns real geometry
-+ 5 hfs+ resize bugfixes : 19-04-2003
-+ * fragmented fs could be corrupted
-+ * VH wasn't written on error during alloc map writing
-+ * attributes file could be corrupted
-+ 6 Use PedSector to be able to use > 2 To HD 23-04-2003
-+ Minor probe bugfix, Cleanups, HFS+ Timer tuning,
-+ 7 80 columns indentation 23-04-2003
-+ 8 Bugfix free blocks calculation in wrapper
-+ (makes Mac OS boot !) 28-04-2003
-+*/
-+
-+/* TODO : Think about a mean to do more allocation bitmap
-+ saves when shrinking hfs+ */
-+
- #include "config.h"
-
-+#include <stdlib.h>
-+#include <string.h>
- #include <parted/parted.h>
- #include <parted/endian.h>
-+#include <parted/debug.h>
-+#include <stdint.h>
-
- #if ENABLE_NLS
- # include <libintl.h>
-@@ -31,32 +73,2902 @@
-
- #include <string.h>
-
--#define HFS_SIGNATURE 0x4244
-+#include "hfs.h"
-+
-+
-+
-+/* -------------------- */
-+/* -- CODE -- */
-+/* -------------------- */
-+
-+/* Probe an HFS volume, detecting it even if
-+it is in fact a wrapper to an HFS+ volume */
-+/* Used by hfsplus_probe and hfs_probe */
-+static PedGeometry*
-+hfs_and_wrapper_probe (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ HfsMasterDirectoryBlock *mdb;
-+ PedGeometry* geom_ret;
-+ PedSector search, max;
-+
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if ((geom->length < 5)
-+ || (!ped_geometry_read (geom, buf, 2, 1))
-+ || (PED_BE16_TO_CPU (mdb->signature) != HFS_SIGNATURE) )
-+ return NULL;
-+
-+ search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
-+ * (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE )));
-+ max = search + ( PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE );
-+ if (!(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
-+ return NULL;
-+
-+ for (; search < max; search++) {
-+ if (!ped_geometry_set (geom_ret, geom_ret->start, search + 2)
-+ || !ped_geometry_read (geom_ret, buf, search, 1))
-+ break;
-+ if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE)
-+ return geom_ret;
-+ }
-+
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+}
-+
-+static PedGeometry*
-+hfsplus_probe (PedGeometry* geom)
-+{
-+ PedGeometry* geom_ret;
-+ uint8_t buf[PED_SECTOR_SIZE];
-+
-+ if ((geom_ret = hfs_and_wrapper_probe(geom))) {
-+ /* HFS+ is embedded in an HFS volume ? */
-+ HfsMasterDirectoryBlock *mdb;
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1)
-+ || (PED_BE16_TO_CPU (mdb->old_new.embedded.signature)
-+ != HFSP_SIGNATURE)) {
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+ } else
-+ return geom_ret;
-+ } else {
-+ /* This is a standalone HFS+ volume ? */
-+ PedSector search, max;
-+ HfsPVolumeHeader *vh;
-+ vh = (HfsPVolumeHeader *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1)
-+ || (PED_BE16_TO_CPU (vh->signature) != HFSP_SIGNATURE))
-+ return NULL;
-+
-+ max = (PedSector) PED_BE32_TO_CPU (vh->total_blocks)
-+ * ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE );
-+ search = max - ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) - 1;
-+ if (!(geom_ret = ped_geometry_new (geom->dev, geom->start,
-+ search + 2)))
-+ return NULL;
-+
-+ for (; search < max; search++) {
-+ if (!ped_geometry_set (geom_ret, geom_ret->start,
-+ search + 2)
-+ || !ped_geometry_read (geom_ret, buf, search, 1))
-+ break;
-+ if (PED_BE16_TO_CPU (vh->signature) == HFSP_SIGNATURE)
-+ return geom_ret;
-+ }
-+
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+ }
-+}
-
- static PedGeometry*
- hfs_probe (PedGeometry* geom)
- {
-- char buf[512];
-+ PedGeometry* geom_base;
-+ PedGeometry* geom_plus = NULL;
-+
-+ if ((geom_base = hfs_and_wrapper_probe(geom))
-+ && (!(geom_plus = hfsplus_probe(geom_base))))
-+ return geom_base;
-+ else {
-+ if (geom_base) ped_geometry_destroy (geom_base);
-+ if (geom_plus) ped_geometry_destroy (geom_plus);
-+ return NULL;
-+ }
-+}
-+
-+#ifndef DISCOVER_ONLY
-+/* declaration used by hfs_btree_search (indirect recursion) */
-+static int
-+hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector);
-+
-+static int
-+hfs_clobber (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+
-+ memset (buf, 0, PED_SECTOR_SIZE);
-+
-+ /* destroy boot blocks, mdb, alternate mdb ... */
-+ return ped_geometry_write (geom, buf, 0, 1) &
-+ ped_geometry_write (geom, buf, 1, 1) &
-+ ped_geometry_write (geom, buf, 2, 1) &
-+ ped_geometry_write (geom, buf, geom->length - 2, 1) &
-+ ped_geometry_write (geom, buf, geom->length - 1, 1);
-+}
-+
-+static int
-+hfsplus_clobber (PedGeometry* geom)
-+{
-+ unsigned int i = 1;
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ HfsMasterDirectoryBlock *mdb;
-+
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1))
-+ return 0;
-+
-+
-+ if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE) {
-+ /* embedded hfs+ */
-+ PedGeometry *embedded;
-+
-+ i = (PED_BE32_TO_CPU(mdb->block_size) / PED_SECTOR_SIZE);
-+ embedded = ped_geometry_new (
-+ geom->dev,
-+ (PedSector) geom->start
-+ + PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) PED_BE16_TO_CPU (
-+ mdb->old_new.embedded.location.start_block ) * i,
-+ (PedSector) PED_BE16_TO_CPU (
-+ mdb->old_new.embedded.location.block_count ) * i );
-+ i = hfs_clobber (embedded);
-+ ped_geometry_destroy (embedded);
-+ }
-+
-+ /* non-embedded or envelop destroy as hfs */
-+ return ( hfs_clobber (geom) && i );
-+}
-+
-+/* Open the data fork of a file with its first three extents and its CNID */
-+static HfsPrivateFile*
-+hfs_file_open (PedFileSystem *fs, uint32_t CNID,
-+ HfsExtDataRec ext_desc, PedSector sect_nb)
-+{
-+ HfsPrivateFile* file;
-+
-+ file = (HfsPrivateFile*) ped_malloc (sizeof (HfsPrivateFile));
-+
-+ file->fs = fs;
-+ file->sect_nb = sect_nb;
-+ file->CNID = CNID;
-+ memcpy(file->first, ext_desc, sizeof (HfsExtDataRec));
-+ memcpy(file->cache, ext_desc, sizeof (HfsExtDataRec));
-+ file->start_cache = 0;
-+
-+ return file;
-+}
-+
-+/* Close an HFS file */
-+static void
-+hfs_file_close (HfsPrivateFile* file)
-+{
-+ ped_free (file);
-+}
-+
-+/* do a B-Tree lookup */
-+/* read the first record immediatly inferior or egal to the given key */
-+/* return 0 on error */
-+/* record_out _must_ be large enough to receive record_size bytes */
-+static int
-+hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
-+ void *record_out, unsigned int record_size,
-+ HfsCPrivateLeafRec* record_ref)
-+{
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsPrivateGenericKey* record_key = NULL;
-+ unsigned int node_number, record_number;
-+ int i;
-+
-+ /* Read the header node */
-+ if (!hfs_file_read_sector(b_tree_file, node, 0))
-+ return 0;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+
-+ /* Get the node number of the root */
-+ node_number = PED_BE32_TO_CPU(header->root_node);
-+
-+ /* Read the root node */
-+ if (!hfs_file_read_sector(b_tree_file, node, node_number))
-+ return 0;
-+
-+ /* Follow the white rabbit */
-+ while (1) {
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = record_number; i; i--) {
-+ int cmp, min_length;
-+
-+ record_key = (HfsPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*i)))));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)record_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)record_key - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return 0;
-+ min_length = ( (key->key_length
-+ > record_key->key_length) ?
-+ (record_key->key_length) :
-+ (key->key_length) );
-+ cmp = memcmp (record_key->key_content,
-+ key->key_content, min_length);
-+ if (cmp < 0 || ( cmp == 0 && record_key->key_length
-+ <= key->key_length))
-+ break;
-+ }
-+ if (!i) return 0;
-+ if (desc->type == HFS_IDX_NODE) {
-+ unsigned int skip;
-+
-+ skip = (1 + record_key->key_length + 1) & ~1;
-+ node_number = PED_BE32_TO_CPU (*((uint32_t *)
-+ (((uint8_t *) record_key) + skip)));
-+ if (!hfs_file_read_sector(b_tree_file, node,
-+ node_number))
-+ return 0;
-+ } else
-+ break;
-+ }
-+
-+ /* copy the result if needed */
-+ if (record_size)
-+ memcpy (record_out, record_key, record_size);
-+
-+ /* send record reference if needed */
-+ if (record_ref) {
-+ record_ref->node_size = 1; /* in sectors */
-+ record_ref->node_number = node_number;
-+ record_ref->record_pos = (uint8_t*)record_key - node;
-+ record_ref->record_number = i;
-+ }
-+
-+ /* success */
-+ return 1;
-+}
-+
-+static int
-+hfs_get_extent_containing (HfsPrivateFile* file, unsigned int block,
-+ HfsExtDataRec cache, uint16_t* ptr_start_cache)
-+{
-+ uint8_t record[sizeof (HfsExtentKey)
-+ + sizeof (HfsExtDataRec)];
-+ HfsExtentKey search;
-+ HfsExtentKey* ret_key = (HfsExtentKey*) record;
-+ HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
-+ (record + sizeof (HfsExtentKey));
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ file->fs->type_specific;
-+
-+
-+ search.key_length = sizeof (HfsExtentKey) - 1;
-+ search.type = HFS_DATA_FORK;
-+ search.file_ID = file->CNID;
-+ search.start = PED_CPU_TO_BE16 (block);
-+
-+ if (!hfs_btree_search (priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL))
-+ return 0;
-+
-+ if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
-+ return 0;
-+
-+ memcpy (cache, ret_cache, sizeof(HfsExtDataRec));
-+ *ptr_start_cache = PED_BE16_TO_CPU (ret_key->start);
-+
-+ return 1;
-+}
-+
-+/* find and return the nth sector of a file */
-+/* return 0 on error */
-+static PedSector
-+hfs_file_find_sector (HfsPrivateFile* file, PedSector sector)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ file->fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ unsigned int i, s, vol_block;
-+ unsigned int block = sector
-+ / (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ unsigned int offset = sector
-+ % (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+
-+ /* in the three first extent */
-+ for (s = 0, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->first[i].block_count)) {
-+ if ((block >= s) && ( block < s + PED_BE16_TO_CPU (
-+ file->first[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->first[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE16_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->cache[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ /* update cache */
-+ if (!hfs_get_extent_containing (file, block, file->cache,
-+ &(file->start_cache)))
-+ return 0;
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE16_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->cache[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ return 0;
-+
-+ sector_found:
-+ return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) vol_block * (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE)
-+ + offset;
-+}
-+
-+/* Read the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-+{
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfs_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_read (file->fs->geom, buf,
-+ abs_sector, 1);
-+}
-+
-+/* Write the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfs_file_write_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-+{
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfs_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_write (file->fs->geom, buf,
-+ abs_sector, 1);
-+}
-+
-+/* This function reads bad blocks extents in the extents file
-+ and store it in f.s. specific data of fs */
-+static int
-+hfs_read_bad_blocks (const PedFileSystem *fs)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (!priv_data->bad_blocks_loaded) {
-+ uint8_t record[sizeof (HfsExtentKey)
-+ + sizeof (HfsExtDataRec)];
-+ HfsExtentKey search;
-+ HfsExtentKey* ret_key = (HfsExtentKey*) record;
-+ HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
-+ (record
-+ + sizeof (HfsExtentKey));
-+ unsigned int block, last_start, first_pass = 1;
-+
-+ search.key_length = sizeof (HfsExtentKey) - 1;
-+ search.type = HFS_DATA_FORK;
-+ search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+
-+ last_start = -1; block = 0;
-+ while (1) {
-+ int i;
-+
-+ search.start = PED_CPU_TO_BE16 (block);
-+ if (!hfs_btree_search (priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL)) {
-+ if (first_pass)
-+ break;
-+ else
-+ return 0;
-+ }
-+ if (ret_key->file_ID != search.file_ID
-+ || ret_key->type != search.type)
-+ break;
-+ if (PED_BE16_TO_CPU (ret_key->start) == last_start)
-+ break;
-+
-+ last_start = PED_BE16_TO_CPU (ret_key->start);
-+ for (i = 0; i < HFS_EXT_NB; i++) {
-+ if (ret_cache[i].block_count) {
-+ HfsPrivateLinkExtent* new_xt =
-+ (HfsPrivateLinkExtent*) ped_malloc (
-+ sizeof (HfsPrivateLinkExtent));
-+ new_xt->next =
-+ priv_data->bad_blocks_xtent_list;
-+ memcpy(&(new_xt->extent), ret_cache+i,
-+ sizeof (HfsExtDescriptor));
-+ priv_data->bad_blocks_xtent_list =
-+ new_xt;
-+ priv_data->bad_blocks_xtent_nb++;
-+ block += PED_BE16_TO_CPU (
-+ ret_cache[i].block_count);
-+ }
-+ }
-+ first_pass = 0;
-+ }
-+
-+ priv_data->bad_blocks_loaded = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+/* free the bad blocks linked list */
-+static void
-+hfs_free_bad_blocks_list(HfsPrivateLinkExtent* first)
-+{
-+ HfsPrivateLinkExtent* next;
-+
-+ while (first) {
-+ next = first->next;
-+ ped_free (first);
-+ first = next;
-+ }
-+}
-+
-+/* This function check if fblock is a bad block */
-+static int
-+hfs_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsPrivateLinkExtent* walk;
-+
-+ for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
-+ /* Won't compile without the strange cast ! gcc bug ? */
-+ /* or maybe C subtilties... */
-+ if ((fblock >= PED_BE16_TO_CPU (walk->extent.start_block)) &&
-+ (fblock < (unsigned int) (PED_BE16_TO_CPU (
-+ walk->extent.start_block)
-+ + PED_BE16_TO_CPU (
-+ walk->extent.block_count))))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves data of size blocks starting
-+ at block *ptr_fblock to block *ptr_to_fblock */
-+/* return new start or -1 on failure */
-+static int
-+hfs_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock, unsigned int size)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t* block;
-+ unsigned int i;
-+ unsigned int new_start;
-+
-+ /* try to find enough room to fit the extent */
-+ for (i = *ptr_to_fblock;
-+ i < *ptr_to_fblock + size && i < *ptr_fblock;
-+ i++) {
-+ if (hfs_is_bad_block (fs, i))
-+ *ptr_to_fblock = i+1;
-+ }
-+
-+ if (*ptr_to_fblock < *ptr_fblock) {
-+ /* enough room */
-+ block = (uint8_t*) ped_malloc(PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size));
-+
-+ new_start = *ptr_to_fblock;
-+
-+ /* move blocks one by one */
-+ for (i = 0; i < size; i++) {
-+ PedSector abs_sector;
-+ unsigned int bit, byte;
-+ unsigned int to_bit, to_byte;
-+
-+ abs_sector = (PedSector) PED_BE16_TO_CPU (
-+ priv_data->mdb->start_block)
-+ + (PedSector) (*ptr_fblock + i)
-+ * (PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ if (!ped_geometry_read (fs->geom, block, abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ abs_sector = (PedSector) PED_BE16_TO_CPU (
-+ priv_data->mdb->start_block)
-+ + (PedSector) (*ptr_to_fblock + i)
-+ * (PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ if (!ped_geometry_write (fs->geom, block, abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ bit = 7 - ((*ptr_fblock + i) & 7);
-+ byte = (*ptr_fblock + i) / 8;
-+
-+ to_bit = 7 - ((*ptr_to_fblock + i) & 7);
-+ to_byte = (*ptr_to_fblock + i) / 8;
-+
-+ /* free source block */
-+ priv_data->alloc_map[byte] &= ~(1 << bit);
-+
-+ /* set dest block */
-+ priv_data->alloc_map[to_byte] |= (1 << to_bit);
-+ }
-+
-+ /* save the allocation map */
-+ if (!ped_geometry_write(fs->geom, priv_data->alloc_map,
-+ PED_BE16_TO_CPU (
-+ priv_data->mdb->volume_bitmap_block),
-+ ( PED_BE16_TO_CPU (
-+ priv_data->mdb->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1)
-+ / (PED_SECTOR_SIZE * 8)))
-+ return -1;
-+
-+ ped_free (block);
-+
-+ *ptr_fblock += size;
-+ *ptr_to_fblock += size;
-+ } else {
-+ /* not enough room */
-+ new_start = *ptr_fblock;
-+ *ptr_fblock = *ptr_to_fblock = new_start + size;
-+ }
-+
-+ return new_start;
-+}
-+
-+/* Search an extent in the catalog file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_catalog (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsCatalogKey* catalog_key;
-+ HfsCatalog* catalog_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j;
-+ int new_start;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfs_file_read_sector (priv_data->catalog_file, node, 0))
-+ return -1;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfs_file_read_sector (priv_data->catalog_file, node,
-+ leaf_node))
-+ return -1;
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ /* fucking undocumented alignement powered by apple :p */
-+ unsigned int skip;
-+ catalog_key = (HfsCatalogKey*) (node + PED_BE16_TO_CPU(
-+ *((uint16_t *)(node+(PED_SECTOR_SIZE - 2*i)))));
-+ skip = (1 + catalog_key->key_length + 1) & ~1;
-+ catalog_data = (HfsCatalog*)(((uint8_t*)catalog_key)
-+ + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)catalog_data - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return -1;
-+ if (catalog_data->type != HFS_CAT_FILE) continue;
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (catalog_data
-+ ->sel.file.extents_data[j].block_count
-+ && PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_data[j].start_block)
-+ == (*ptr_fblock))
-+ goto catalog_data_found;
-+ if (catalog_data
-+ ->sel.file.extents_res[j].block_count
-+ && PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_res[j].start_block)
-+ == (*ptr_fblock))
-+ goto catalog_res_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ return 0;
-+
-+
-+ /* an extent part of a data fork has been found in the catalog file */
-+ catalog_data_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = catalog_data->sel.file.extents_data[j].start_block;
-+ catalog_data->sel.file.extents_data[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ /* write if any changes */
-+ if ((old_start != PED_CPU_TO_BE16 (new_start))
-+ && !hfs_file_write_sector (priv_data->catalog_file,
-+ node, leaf_node))
-+ return -1;
-+ return 1;
-+ } else
-+ return -1;
-+
-+ /* an extent part of a resource fork has been found in the catalog file */
-+ catalog_res_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_res[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = catalog_data->sel.file.extents_res[j].start_block;
-+ catalog_data->sel.file.extents_res[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ /* write if any changes */
-+ if ((old_start != PED_CPU_TO_BE16 (new_start))
-+ && !hfs_file_write_sector (priv_data->catalog_file,
-+ node, leaf_node))
-+ return -1;
-+ return 1;
-+ } else
-+ return -1;
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsExtentKey* extent_key;
-+ HfsExtDescriptor* extent_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j;
-+ int new_start;
-+
-+ /* Search the extent in the extent file */
-+ if (!hfs_file_read_sector (priv_data->extent_file, node, 0))
-+ return -1;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfs_file_read_sector (priv_data->extent_file, node,
-+ leaf_node))
-+ return -1;
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ extent_key = (HfsExtentKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*i)))));
-+ extent_data = (HfsExtDescriptor*)(((uint8_t*)extent_key)
-+ + sizeof (HfsExtentKey));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)extent_data - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return -1;
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (extent_data[j].block_count
-+ && PED_BE16_TO_CPU (
-+ extent_data[j].start_block)
-+ == (*ptr_fblock))
-+ goto extent_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the extents file */
-+ return 0;
-+
-+ /* an extent has been found in the extents file */
-+ extent_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (extent_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = extent_data[j].start_block;
-+ extent_data[j].start_block = PED_CPU_TO_BE16 (new_start);
-+ /* This extent might have been cached into the file structure
-+ of the extent or catalog file */
-+ if (priv_data->catalog_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->catalog_file->cache, extent_data,
-+ sizeof (HfsExtDataRec));
-+ if (priv_data->extent_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->extent_file->cache, extent_data,
-+ sizeof (HfsExtDataRec));
-+ /* write if any changes */
-+ if ((old_start != PED_CPU_TO_BE16 (new_start))
-+ && !hfs_file_write_sector (priv_data->extent_file, node,
-+ leaf_node))
-+ return -1;
-+ return 1;
-+ } else
-+ return -1;
-+}
-
-- if (geom->length < 2)
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_primary (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ unsigned int j;
-+ int new_start;
-+
-+ /* Search an extent in the MDB */
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (priv_data->mdb->extents_file_rec[j].block_count
-+ && PED_BE16_TO_CPU (priv_data->mdb->extents_file_rec[j]
-+ .start_block)
-+ == (*ptr_fblock))
-+ goto ext_file_found;
-+ if (priv_data->mdb->catalog_file_rec[j].block_count
-+ && PED_BE16_TO_CPU (priv_data->mdb->catalog_file_rec[j]
-+ .start_block)
-+ == (*ptr_fblock))
-+ goto cat_file_found;
-+ }
-+ return 0;
-+
-+ ext_file_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (priv_data->mdb
-+ ->extents_file_rec[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ priv_data->mdb->extents_file_rec[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ memcpy (priv_data->extent_file->first,
-+ priv_data->mdb->extents_file_rec,
-+ sizeof (HfsExtDataRec));
-+ if (!priv_data->extent_file->start_cache)
-+ memcpy (priv_data->extent_file->cache,
-+ priv_data->extent_file->first,
-+ sizeof (HfsExtDataRec));
-+ goto update_mdb;
-+ } else
-+ return -1;
-+
-+
-+ cat_file_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (priv_data->mdb
-+ ->catalog_file_rec[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ priv_data->mdb->catalog_file_rec[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ memcpy (priv_data->catalog_file->first,
-+ priv_data->mdb->catalog_file_rec,
-+ sizeof (HfsExtDataRec));
-+ if (!priv_data->catalog_file->start_cache)
-+ memcpy (priv_data->catalog_file->cache,
-+ priv_data->catalog_file->first,
-+ sizeof (HfsExtDataRec));
-+ goto update_mdb;
-+ } else
-+ return -1;
-+
-+ update_mdb:
-+ if (!ped_geometry_read (fs->geom, node, 2, 1))
-+ return -1;
-+ memcpy (node, priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, node, 2, 1))
-+ return -1;
-+ if (!ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1))
-+ return -1;
-+ return 1;
-+}
-+
-+/* This function moves an extent starting at block fblock to block to_fblock
-+ if there's enough room */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ int ret;
-+
-+ /* order = decreasing probability to be found */
-+ if ((ret = hfs_search_move_catalog (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfs_search_move_extent (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfs_search_move_primary (fs, ptr_fblock, ptr_to_fblock))) {
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves file's data to compact used and free space,
-+ starting at fblock block */
-+/* return 0 on error */
-+static int
-+hfs_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
-+ PedTimer* timer)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ unsigned int to_fblock = fblock;
-+ unsigned int start = fblock;
-+ unsigned int div = PED_BE16_TO_CPU (mdb->total_blocks)
-+ + 1 - start;
-+ int byte, bit, ret;
-+ int to_byte, to_bit;
-+
-+ to_byte = byte = fblock / 8;
-+ to_bit = bit = 7 - (fblock & 7);
-+
-+ if (!hfs_read_bad_blocks (fs))
-+ return 0;
-+
-+ while (fblock < PED_BE16_TO_CPU (mdb->total_blocks)) {
-+ if (((priv_data->alloc_map[byte] >> bit) & 1)
-+ && (!hfs_is_bad_block (fs, fblock))) {
-+ if (!(ret = hfs_move_extent_starting_at (fs, &fblock,
-+ &to_fblock)))
-+ to_fblock = ++fblock;
-+ else if (ret == -1)
-+ return 0;
-+ } else {
-+ fblock++;
-+ }
-+
-+ byte = fblock / 8;
-+ bit = 7 - (fblock & 7);
-+
-+ to_byte = to_fblock / 8;
-+ to_bit = 7 - (to_fblock & 7);
-+
-+ ped_timer_update(timer, (float)(fblock - start)/div);
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function returns the first sector of the last free block of an
-+ HFS volume we can get after a hfs_pack_free_space_from_block call */
-+static PedSector
-+hfs_get_empty_end (const PedFileSystem *fs)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ HfsPrivateLinkExtent* link;
-+ unsigned int block, last_bad, end_free_blocks;
-+ int byte, bit;
-+
-+ /* find the next block to the last bad block of the volume */
-+ if (!hfs_read_bad_blocks (fs))
- return 0;
-+
-+ last_bad = 0;
-+ for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
-+ if ((unsigned int) PED_BE16_TO_CPU (link->extent.start_block)
-+ + PED_BE16_TO_CPU (link->extent.block_count) > last_bad)
-+ last_bad = PED_BE16_TO_CPU (link->extent.start_block)
-+ + PED_BE16_TO_CPU (link->extent.block_count);
-+ }
-+
-+ /* Count the free blocks from last_bad to the end of the volume */
-+ end_free_blocks = 0;
-+ for (block = last_bad;
-+ block < PED_BE16_TO_CPU (mdb->total_blocks);
-+ block++) {
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if (!((priv_data->alloc_map[byte]>>bit)&1))
-+ end_free_blocks++;
-+ }
-+
-+ /* Calculate the block that will by the first free at the
-+ end of the volume */
-+ block = PED_BE16_TO_CPU (mdb->total_blocks) - end_free_blocks;
-+
-+ return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) block * (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+}
-+
-+/* return the block which should be used to pack data to have at
-+ least free fblock blocks at the end of the volume */
-+static unsigned int
-+hfs_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ unsigned int block;
-+
-+ for (block = PED_BE16_TO_CPU (priv_data->mdb->total_blocks) - 1;
-+ block && fblock;
-+ block--) {
-+ if (!((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ fblock--;
-+ }
-+
-+ while (block && !((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ block--;
-+ if ((priv_data->alloc_map[block / 8] >> (7 - (block & 7))) & 1)
-+ block++;
-+
-+ return block;
-+}
-+
-+static PedFileSystem*
-+hfs_open (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ PedFileSystem* fs;
-+ HfsMasterDirectoryBlock* mdb;
-+ HfsPrivateFSData* priv_data;
-+
-+ /* Read MDB */
- if (!ped_geometry_read (geom, buf, 2, 1))
-+ return NULL;
-+
-+ /* Allocate memory */
-+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
-+ mdb = (HfsMasterDirectoryBlock*) ped_malloc (
-+ sizeof (HfsMasterDirectoryBlock));
-+ priv_data = (HfsPrivateFSData*) ped_malloc (
-+ sizeof (HfsPrivateFSData));
-+
-+ memcpy (mdb, buf, sizeof (HfsMasterDirectoryBlock));
-+
-+ /* init structures */
-+ priv_data->mdb = mdb;
-+ priv_data->bad_blocks_loaded = 0;
-+ priv_data->bad_blocks_xtent_nb = 0;
-+ priv_data->bad_blocks_xtent_list = NULL;
-+ priv_data->extent_file =
-+ hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
-+ mdb->extents_file_rec,
-+ PED_CPU_TO_BE32 (mdb->extents_file_size)
-+ / PED_SECTOR_SIZE);
-+ priv_data->catalog_file =
-+ hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
-+ mdb->catalog_file_rec,
-+ PED_CPU_TO_BE32 (mdb->catalog_file_size)
-+ / PED_SECTOR_SIZE);
-+
-+ /* Read allocation blocks */
-+ if (!ped_geometry_read(geom, priv_data->alloc_map,
-+ PED_BE16_TO_CPU (mdb->volume_bitmap_block),
-+ ( PED_BE16_TO_CPU (mdb->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 )
-+ / (PED_SECTOR_SIZE * 8) ) ) {
-+ hfs_file_close (priv_data->extent_file);
-+ hfs_file_close (priv_data->catalog_file);
-+ ped_free(fs); ped_free(mdb); ped_free(priv_data);
-+ return NULL;
-+ }
-+
-+ fs->type = &hfs_type;
-+ fs->geom = ped_geometry_duplicate (geom);
-+ fs->type_specific = (void*) priv_data;
-+ fs->checked = ( PED_BE16_TO_CPU (mdb->volume_attributes)
-+ >> HFS_UNMOUNTED ) & 1;
-+
-+ return fs;
-+}
-+
-+static int
-+hfs_close (PedFileSystem *fs)
-+{
-+ hfs_file_close (((HfsPrivateFSData*)(fs->type_specific))->extent_file);
-+ hfs_file_close (((HfsPrivateFSData*)(fs->type_specific))->catalog_file);
-+ if (((HfsPrivateFSData*)(fs->type_specific))->bad_blocks_loaded)
-+ hfs_free_bad_blocks_list (
-+ ((HfsPrivateFSData*)(fs->type_specific))
-+ ->bad_blocks_xtent_list);
-+ ped_free (((HfsPrivateFSData*)(fs->type_specific))->mdb);
-+ ped_free (fs->type_specific);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+
-+ return 1;
-+}
-+
-+static PedConstraint*
-+hfs_get_resize_constraint (const PedFileSystem *fs)
-+{
-+ PedDevice* dev = fs->geom->dev;
-+ PedAlignment start_align;
-+ PedGeometry start_sector;
-+ PedGeometry full_dev;
-+ PedSector min_size;
-+
-+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
-+ return NULL;
-+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
-+ return NULL;
-+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
-+ return NULL;
-+ /* 2 = last two sectors (alternate MDB and unused sector) */
-+ min_size = hfs_get_empty_end(fs) + 2;
-+
-+ return ped_constraint_new (&start_align, ped_alignment_any,
-+ &start_sector, &full_dev, min_size,
-+ fs->geom->length);
-+}
-+
-+static int
-+hfs_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ unsigned int nblock, nfree;
-+ unsigned int block;
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ int resize = 1;
-+ unsigned int hfs_sect_block = ( PED_BE32_TO_CPU (
-+ mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+
-+
-+ /* check preconditions */
-+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
-+
-+ if (fs->geom->start != geom->start)
-+ {
-+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
-+ PED_EXCEPTION_CANCEL,
-+ _("Sorry, can't move the start of hfs partitions yet!"));
-+ return 0;
-+ }
-+
-+ if (geom->length > fs->geom->length
-+ || geom->length < hfs_get_empty_end(fs) + 2)
-+ return 0;
-+
-+ /* Clear the unmounted bit */
-+ mdb->volume_attributes &= PED_CPU_TO_BE16 (~( 1 << HFS_UNMOUNTED ));
-+ if (!ped_geometry_read (fs->geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, buf, 2, 1))
-+ return 0;
-+
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name(timer, _("shrinking"));
-+ ped_timer_update(timer, 0.0);
-+ /* relocate data */
-+ block = hfs_find_start_pack (fs, ( fs->geom->length - geom->length
-+ + hfs_sect_block - 1 )
-+ / hfs_sect_block );
-+ if (!hfs_pack_free_space_from_block (fs, block, timer)) {
-+ resize = 0;
-+ goto write_MDB;
-+ }
-+
-+ /* Calculate new block number and other MDB field */
-+ nblock = ( geom->length - (PED_BE16_TO_CPU (mdb->start_block) + 2) )
-+ / hfs_sect_block;
-+ nfree = PED_BE16_TO_CPU (mdb->free_blocks)
-+ - ( PED_BE16_TO_CPU (mdb->total_blocks) - nblock );
-+
-+ /* Check that all block after future end are really free */
-+ for (block = nblock;
-+ block < PED_BE16_TO_CPU (mdb->total_blocks);
-+ block++) {
-+ int byte, bit;
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if ((priv_data->alloc_map[byte]>>bit)&1) {
-+ resize = 0;
-+ goto write_MDB;
-+ }
-+ }
-+
-+ /* Update geometry */
-+ if (resize) {
-+ /* update in fs structure */
-+ if (PED_BE16_TO_CPU (mdb->next_allocation) >= nblock)
-+ mdb->next_allocation = PED_CPU_TO_BE16 (0);
-+ mdb->total_blocks = PED_CPU_TO_BE16 (nblock);
-+ mdb->free_blocks = PED_CPU_TO_BE16 (nfree);
-+ /* update parted structure */
-+ fs->geom->length = geom->length;
-+ fs->geom->end = fs->geom->start + geom->length - 1;
-+ }
-+
-+ /* Set the unmounted bit */
-+ mdb->volume_attributes |= PED_CPU_TO_BE16 ( 1 << HFS_UNMOUNTED );
-+
-+ /* Effective write */
-+ write_MDB:
-+ ped_timer_set_state_name(timer,_("writing HFS Master Directory Block"));
-+ if (!ped_geometry_read (fs->geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, buf, 2, 1))
- return 0;
-+ if (!ped_geometry_write (fs->geom, buf, fs->geom->length - 2, 1))
-+ return 0;
-+ ped_timer_update(timer, 1.0);
-+
-+ return (resize);
-+}
-+
-+/* ----- HFS+ ----- */
-+
-+/* Open the data fork of a file with its first eight extents and its CNID */
-+static HfsPPrivateFile*
-+hfsplus_file_open (PedFileSystem *fs, HfsPNodeID CNID,
-+ HfsPExtDataRec ext_desc, PedSector sect_nb)
-+{
-+ HfsPPrivateFile* file;
-+
-+ file = (HfsPPrivateFile*) ped_malloc (sizeof (HfsPPrivateFile));
-+
-+ file->fs = fs;
-+ file->sect_nb = sect_nb;
-+ file->CNID = CNID;
-+ memcpy(file->first, ext_desc, sizeof (HfsPExtDataRec));
-+ memcpy(file->cache, ext_desc, sizeof (HfsPExtDataRec));
-+ file->start_cache = 0;
-+
-+ return file;
-+}
-
-- if (PED_BE16_TO_CPU (*(uint16_t*) buf) == HFS_SIGNATURE)
-- return ped_geometry_duplicate (geom);
-- else
-+/* Close an HFS+ file */
-+static void
-+hfsplus_file_close (HfsPPrivateFile* file)
-+{
-+ ped_free (file);
-+}
-+
-+/* declaration of hfsplus_file_read(_sector)
-+ because it's used by hfsplus_btree_search (indirect recursion) */
-+static int
-+hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector);
-+static int
-+hfsplus_file_read(HfsPPrivateFile* file, void *buf,
-+ PedSector sector, unsigned int nb);
-+
-+/* do a B-Tree lookup */
-+/* read the first record immediatly inferior or egal to the given key */
-+/* return 0 on error */
-+/* record_out _must_ be large enough to receive the whole record (key + data) */
-+static int
-+hfsplus_btree_search (HfsPPrivateFile* b_tree_file, HfsPPrivateGenericKey* key,
-+ void *record_out, unsigned int record_size,
-+ HfsCPrivateLeafRec* record_ref)
-+{
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPPrivateGenericKey* record_key = NULL;
-+ unsigned int node_number, record_number, size, bsize;
-+ int i;
-+
-+ /* Read the header node */
-+ if (!hfsplus_file_read_sector(b_tree_file, node_1, 0))
-+ return 0;
-+ header = (HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC);
-+
-+ /* Get the node number of the root */
-+ node_number = PED_BE32_TO_CPU (header->root_node);
-+
-+ /* Get the size of a node in sectors and allocate buffer */
-+ size = (bsize = PED_BE16_TO_CPU (header->node_size)) / PED_SECTOR_SIZE;
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ /* Read the root node */
-+ if (!hfsplus_file_read (b_tree_file, node,
-+ (PedSector) node_number * size, size))
-+ return 0;
-+
-+ /* Follow the white rabbit */
-+ while (1) {
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = record_number; i; i--) {
-+ int cmp, min_length;
-+
-+ record_key = (HfsPPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)record_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)record_key - node
-+ >= (signed)bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return 0;
-+ }
-+ min_length = ((PED_BE16_TO_CPU(key->key_length)
-+ >PED_BE16_TO_CPU(record_key->key_length))?
-+ PED_BE16_TO_CPU(record_key->key_length) :
-+ PED_BE16_TO_CPU(key->key_length) );
-+ cmp = memcmp (record_key->key_content, key->key_content,
-+ min_length);
-+ if (cmp < 0 || ( cmp == 0 && PED_BE16_TO_CPU (
-+ record_key->key_length)
-+ <= PED_BE16_TO_CPU (
-+ key->key_length)))
-+ break;
-+ }
-+ if (!i) { ped_free (node); return 0; }
-+ if (desc->type == HFS_IDX_NODE) {
-+ unsigned int skip;
-+
-+ skip = ( 2 + PED_BE16_TO_CPU (record_key->key_length)
-+ + 1 ) & ~1;
-+ node_number = PED_BE32_TO_CPU (*((uint32_t *)
-+ (((uint8_t *) record_key) + skip)));
-+ if (!hfsplus_file_read(b_tree_file, node,
-+ (PedSector) node_number * size,
-+ size)) {
-+ ped_free (node);
-+ return 0;
-+ }
-+ } else
-+ break;
-+ }
-+
-+ /* copy the result if needed */
-+ if (record_size)
-+ memcpy (record_out, record_key, record_size);
-+
-+ /* send record reference if needed */
-+ if (record_ref) {
-+ record_ref->node_size = size; /* in sectors */
-+ record_ref->node_number = node_number;
-+ record_ref->record_pos = (uint8_t*)record_key - node;
-+ record_ref->record_number = i;
-+ }
-+
-+ /* success */
-+ ped_free (node);
-+ return 1;
-+}
-+
-+static int
-+hfsplus_get_extent_containing (HfsPPrivateFile* file, unsigned int block,
-+ HfsPExtDataRec cache, uint32_t* ptr_start_cache)
-+{
-+ uint8_t record[sizeof (HfsPExtentKey)
-+ + sizeof (HfsPExtDataRec)];
-+ HfsPExtentKey search;
-+ HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
-+ HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
-+ (record + sizeof (HfsPExtentKey));
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+
-+
-+ search.key_length = PED_CPU_TO_BE16 (sizeof (HfsPExtentKey) - 2);
-+ search.type = HFS_DATA_FORK;
-+ search.pad = 0;
-+ search.file_ID = file->CNID;
-+ search.start = PED_CPU_TO_BE32 (block);
-+
-+ if (!hfsplus_btree_search (priv_data->extents_file,
-+ (HfsPPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL))
-+ return 0;
-+
-+ if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
-+ return 0;
-+
-+ memcpy (cache, ret_cache, sizeof(HfsPExtDataRec));
-+ *ptr_start_cache = PED_BE32_TO_CPU (ret_key->start);
-+
-+ return 1;
-+}
-+
-+/* find the nth sector of a file */
-+/* return 0 on error */
-+static PedSector
-+hfsplus_file_find_sector (HfsPPrivateFile* file, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data-> vh;
-+ unsigned int i, s, vol_block;
-+ unsigned int block = sector
-+ / ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ unsigned int offset = sector
-+ % ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+
-+ /* in the three first extent */
-+ for (s = 0, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->first[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->first[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->first[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->cache[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ /* update cache */
-+ if (!hfsplus_get_extent_containing (file, block, file->cache,
-+ &(file->start_cache)))
-+ return 0;
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->cache[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ return 0;
-+
-+ plus_sector_found:
-+ return (PedSector) vol_block * ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) + offset;
-+}
-+
-+/* Read the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfsplus_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_read (priv_data->plus_geom, buf,
-+ abs_sector, 1);
-+}
-+
-+static int
-+hfsplus_file_read(HfsPPrivateFile* file, void *buf, PedSector sector,
-+ unsigned int nb)
-+{
-+ while (nb) {
-+ if (!hfsplus_file_read_sector (file, buf, sector))
-+ return 0;
-+
-+ buf += PED_SECTOR_SIZE;
-+ nb--;
-+ sector++;
-+ }
-+
-+ return 1;
-+}
-+
-+/* Write the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfsplus_file_write_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfsplus_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_write (priv_data->plus_geom, buf,
-+ abs_sector, 1);
-+}
-+
-+static int
-+hfsplus_file_write (HfsPPrivateFile* file, void *buf, PedSector sector,
-+ unsigned int nb)
-+{
-+ while (nb) {
-+ if (!hfsplus_file_write_sector (file, buf, sector))
-+ return 0;
-+
-+ buf += PED_SECTOR_SIZE;
-+ nb--;
-+ sector++;
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function reads bad blocks extents in the extents file
-+ and store it in f.s. specific data of fs */
-+static int
-+hfsplus_read_bad_blocks (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (!priv_data->bad_blocks_loaded) {
-+ uint8_t record[sizeof (HfsPExtentKey)
-+ + sizeof (HfsPExtDataRec)];
-+ HfsPExtentKey search;
-+ HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
-+ HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
-+ (record + sizeof (HfsPExtentKey));
-+ int block, first_pass = 1;
-+ unsigned int last_start;
-+
-+ search.key_length = sizeof (HfsExtentKey) - 2;
-+ search.type = HFS_DATA_FORK;
-+ search.pad = 0;
-+ search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+
-+ last_start = -1; block = 0;
-+ while (1) {
-+ int i;
-+
-+ search.start = PED_CPU_TO_BE32 (block);
-+ if (!hfsplus_btree_search (priv_data->extents_file,
-+ (HfsPPrivateGenericKey*)
-+ &search,
-+ record, sizeof (record),
-+ NULL)) {
-+ if (first_pass)
-+ break;
-+ else
-+ return 0;
-+ }
-+ if (ret_key->file_ID != search.file_ID
-+ || ret_key->type != search.type)
-+ break;
-+ if (PED_BE32_TO_CPU (ret_key->start) == last_start)
-+ break;
-+
-+ last_start = PED_BE32_TO_CPU (ret_key->start);
-+ for (i = 0; i < HFSP_EXT_NB; i++) {
-+ if (ret_cache[i].block_count) {
-+ HfsPPrivateLinkExtent* new_xt =
-+ (HfsPPrivateLinkExtent*) ped_malloc (
-+ sizeof (HfsPPrivateLinkExtent));
-+ new_xt->next =
-+ priv_data->bad_blocks_xtent_list;
-+ memcpy (&(new_xt->extent), ret_cache+i,
-+ sizeof (HfsPExtDescriptor));
-+ priv_data->bad_blocks_xtent_list =
-+ new_xt;
-+ priv_data->bad_blocks_xtent_nb++;
-+ block += PED_BE32_TO_CPU (ret_cache[i]
-+ .block_count);
-+ }
-+ }
-+ first_pass = 0;
-+ }
-+
-+ priv_data->bad_blocks_loaded = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+/* free the bad blocks linked list */
-+static void
-+hfsplus_free_bad_blocks_list(HfsPPrivateLinkExtent* first)
-+{
-+ HfsPPrivateLinkExtent* next;
-+
-+ while (first) {
-+ next = first->next;
-+ ped_free (first);
-+ first = next;
-+ }
-+}
-+
-+/* This function check if fblock is a bad block */
-+static int
-+hfsplus_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPPrivateLinkExtent* walk;
-+
-+ for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
-+ /* Won't compile without the strange cast ! gcc bug ? */
-+ /* or maybe C subtilties... */
-+ if ((fblock >= PED_BE32_TO_CPU (walk->extent.start_block)) &&
-+ (fblock < (unsigned int)(PED_BE32_TO_CPU (
-+ walk->extent.start_block)
-+ + PED_BE32_TO_CPU (walk->extent.block_count))))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+hfsplus_close (PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (priv_data->wrapper) hfs_close(priv_data->wrapper);
-+ if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
-+ ped_free(priv_data->alloc_map);
-+ hfsplus_file_close (priv_data->extents_file);
-+ hfsplus_file_close (priv_data->catalog_file);
-+ hfsplus_file_close (priv_data->attributes_file);
-+ if (priv_data->bad_blocks_loaded)
-+ hfsplus_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
-+ ped_free (priv_data->vh);
-+ ped_free (priv_data);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+
-+ return 1;
-+}
-+
-+static PedFileSystem*
-+hfsplus_open (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ PedFileSystem* fs;
-+ HfsPVolumeHeader* vh;
-+ HfsPPrivateFSData* priv_data;
-+ PedGeometry* wrapper_geom;
-+ HfsPPrivateFile* allocation_file;
-+ unsigned int map_sectors;
-+
-+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
-+ vh = (HfsPVolumeHeader*) ped_malloc (sizeof (HfsPVolumeHeader));
-+ priv_data = (HfsPPrivateFSData*)ped_malloc (sizeof (HfsPPrivateFSData));
-+
-+ fs->geom = ped_geometry_duplicate (geom);
-+ fs->type_specific = (void*) priv_data;
-+
-+ if ((wrapper_geom = hfs_and_wrapper_probe (geom))) {
-+ HfsPrivateFSData* hfs_priv_data;
-+ PedSector abs_sect, length;
-+ unsigned int bs;
-+
-+ ped_geometry_destroy (wrapper_geom);
-+ priv_data->wrapper = hfs_open(geom);
-+ hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ bs = PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+ abs_sect = (PedSector) geom->start
-+ + (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->start_block)
-+ + (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.start_block )
-+ * bs;
-+ length = (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count)
-+ * bs;
-+ priv_data->plus_geom = ped_geometry_new (geom->dev, abs_sect,
-+ length);
-+ priv_data->free_geom = 1;
-+ } else {
-+ priv_data->wrapper = NULL;
-+ priv_data->plus_geom = fs->geom;
-+ priv_data->free_geom = 0;
-+ }
-+
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1)) {
-+ if (priv_data->wrapper)
-+ hfs_close(priv_data->wrapper);
-+ if (priv_data->free_geom)
-+ ped_geometry_destroy (priv_data->plus_geom);
-+ ped_free (vh);
-+ ped_free (priv_data);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
- return NULL;
-+ }
-+
-+ memcpy (vh, buf, sizeof (HfsPVolumeHeader));
-+
-+ priv_data->vh = vh;
-+ priv_data->bad_blocks_loaded = 0;
-+ priv_data->bad_blocks_xtent_nb = 0;
-+ priv_data->bad_blocks_xtent_list = NULL;
-+ priv_data->extents_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
-+ vh->extents_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->extents_file.logical_size )
-+ / PED_SECTOR_SIZE);
-+ priv_data->catalog_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
-+ vh->catalog_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->catalog_file.logical_size )
-+ / PED_SECTOR_SIZE);
-+ priv_data->attributes_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ATTRIB_ID),
-+ vh->attributes_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->attributes_file.logical_size)
-+ / PED_SECTOR_SIZE);
-+ map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 ) / (PED_SECTOR_SIZE * 8);
-+ priv_data->alloc_map = (uint8_t*)
-+ ped_malloc (map_sectors * PED_SECTOR_SIZE);
-+
-+ allocation_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
-+ vh->allocation_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->allocation_file.logical_size)
-+ / PED_SECTOR_SIZE);
-+ if (!hfsplus_file_read (allocation_file, priv_data->alloc_map, 0,
-+ map_sectors)) {
-+ hfsplus_file_close (allocation_file);
-+ hfsplus_close(fs);
-+ return NULL;
-+ }
-+ hfsplus_file_close (allocation_file);
-+
-+ fs->type = &hfsplus_type;
-+ fs->checked = ((PED_BE32_TO_CPU (vh->attributes) >> HFS_UNMOUNTED) & 1)
-+ && !((PED_BE32_TO_CPU (vh->attributes) >> HFSP_INCONSISTENT) & 1);
-+
-+ return fs;
- }
-
--#ifndef DISCOVER_ONLY
-+/* This function moves data of size blocks starting at block *ptr_fblock
-+ to block *ptr_to_fblock */
-+/* return new start or -1 on failure */
- static int
--hfs_clobber (PedGeometry* geom)
-+hfsplus_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock, unsigned int size)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t* block;
-+ unsigned int i;
-+ unsigned int new_start;
-+
-+ /* try to find enough room to fit the extent */
-+ for (i = *ptr_to_fblock;
-+ i < *ptr_to_fblock + size && i < *ptr_fblock;
-+ i++) {
-+ if (hfsplus_is_bad_block (fs, i))
-+ *ptr_to_fblock = i+1;
-+ }
-+
-+ if (*ptr_to_fblock < *ptr_fblock) {
-+ /* enough room */
-+ block = (uint8_t*) ped_malloc(PED_BE32_TO_CPU (
-+ priv_data->vh->block_size));
-+
-+ new_start = *ptr_to_fblock;
-+
-+ /* move blocks one by one */
-+ for (i = 0; i < size; i++) {
-+ PedSector abs_sector;
-+ unsigned int bit, byte;
-+ unsigned int to_bit, to_byte;
-+
-+ abs_sector = (PedSector) (*ptr_fblock + i)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ if (!ped_geometry_read (priv_data->plus_geom, block,
-+ abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->block_size )
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ abs_sector = (PedSector) (*ptr_to_fblock + i)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ if (!ped_geometry_write (priv_data->plus_geom, block,
-+ abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->block_size )
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ bit = 7 - ((*ptr_fblock + i) & 7);
-+ byte = (*ptr_fblock + i) / 8;
-+
-+ to_bit = 7 - ((*ptr_to_fblock + i) & 7);
-+ to_byte = (*ptr_to_fblock + i) / 8;
-+
-+ /* free source block */
-+ priv_data->alloc_map[byte] &= ~(1 << bit);
-+
-+ /* set dest block */
-+ priv_data->alloc_map[to_byte] |= (1 << to_bit);
-+ }
-+
-+/* TODO : a better handling of allocation map saving process */
-+#if 0
-+ /* save the allocation map */
-+ if (!ped_geometry_write(fs->geom, priv_data->alloc_map, PED_BE16_TO_CPU (priv_data->mdb->volume_bitmap_block),
-+ (PED_BE16_TO_CPU (priv_data->mdb->total_blocks) + PED_SECTOR_SIZE * 8 - 1) / (PED_SECTOR_SIZE * 8)))
-+ return -1;
-+#endif
-+
-+ ped_free (block);
-+
-+ *ptr_fblock += size;
-+ *ptr_to_fblock += size;
-+ } else {
-+ /* not enough room */
-+ new_start = *ptr_fblock;
-+ *ptr_fblock = *ptr_to_fblock = new_start + size;
-+ }
-+
-+ return new_start;
-+}
-+
-+/* Search an extent in the catalog file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_catalog (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPCatalogKey* catalog_key;
-+ HfsPCatalog* catalog_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ int new_start;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfsplus_file_read_sector (priv_data->catalog_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ unsigned int skip;
-+ catalog_key = (HfsPCatalogKey*)
-+ ( node + PED_BE16_TO_CPU (*((uint16_t *)
-+ (node+(bsize - 2*i)))) );
-+ skip = ( 2 + PED_BE16_TO_CPU (catalog_key->key_length)
-+ + 1) & ~1;
-+ catalog_data = (HfsPCatalog*)
-+ (((uint8_t*)catalog_key) + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)catalog_data - node
-+ >= (signed) bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ if (PED_BE16_TO_CPU(catalog_data->type)!=HFS_CAT_FILE)
-+ continue;
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( catalog_data->sel.file
-+ .data_fork.extents[j].block_count
-+ && PED_BE32_TO_CPU (catalog_data->sel
-+ .file.data_fork.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_catalog_data_found;
-+ if ( catalog_data->sel.file.res_fork
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (catalog_data->sel
-+ .file.res_fork.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_catalog_res_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ ped_free (node);
-+ return 0;
-+
-+
-+ /* an extent part of a data fork has been found in the catalog file */
-+ plus_catalog_data_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ catalog_data->sel.file
-+ .data_fork.extents[j]
-+ .block_count ));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = catalog_data->sel.file.data_fork
-+ .extents[j].start_block;
-+ catalog_data->sel.file.data_fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+
-+ /* an extent part of a resource fork has been found
-+ in the catalog file */
-+ plus_catalog_res_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ catalog_data->sel.file
-+ .res_fork.extents[j]
-+ .block_count ));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = catalog_data->sel.file.res_fork
-+ .extents[j].start_block;
-+ catalog_data->sel.file.res_fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the attributes file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_attributes (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
- {
-- char buf[512];
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPPrivateGenericKey* generic_key;
-+ HfsPForkDataAttr* fork_ext_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ int new_start;
-+
-+ /* attributes file is facultative */
-+ if (!priv_data->attributes_file->sect_nb)
-+ return 0;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfsplus_file_read_sector (priv_data->attributes_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ unsigned int skip;
-+ generic_key = (HfsPPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ skip = ( 2 + PED_BE16_TO_CPU (generic_key->key_length)
-+ + 1 ) & ~1;
-+ fork_ext_data = (HfsPForkDataAttr*)
-+ (((uint8_t*)generic_key) + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)generic_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)fork_ext_data - node
-+ >= (signed) bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ if ( PED_BE32_TO_CPU (fork_ext_data->record_type )
-+ == HFSP_ATTR_FORK) {
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( fork_ext_data->fork_res.fork
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .fork.extents[j].start_block )
-+ == (*ptr_fblock) )
-+ goto plus_attr_fork_found;
-+ }
-+ } else if ( PED_BE32_TO_CPU (fork_ext_data->record_type)
-+ == HFSP_ATTR_EXTENTS ) {
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( fork_ext_data->fork_res
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_attr_ext_found;
-+ }
-+ } else continue;
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ ped_free (node);
-+ return 0;
-
-- memset (buf, 0, 512);
-- return ped_geometry_write (geom, buf, 2, 1);
-+
-+ /* an extent part of a attr fork has been found in the catalog file */
-+ plus_attr_fork_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .fork.extents[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = fork_ext_data->fork_res.fork.extents[j].start_block;
-+ fork_ext_data->fork_res.fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+
-+ /* an extent part of a attr ext has been found in the catalog file */
-+ plus_attr_ext_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = fork_ext_data->fork_res.extents[j].start_block;
-+ fork_ext_data->fork_res.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node;
-+ HfsPExtentKey* extent_key;
-+ HfsPExtDescriptor* extent_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ int new_start;
-+
-+ /* Search the extent in the extent file */
-+ if (!hfsplus_file_read_sector (priv_data->extents_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->extents_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ extent_key = (HfsPExtentKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ extent_data = (HfsPExtDescriptor*)
-+ (((uint8_t*)extent_key) + sizeof (HfsPExtentKey));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)extent_data - node
-+ >= (signed)bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( extent_data[j].block_count
-+ && PED_BE32_TO_CPU (
-+ extent_data[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_extent_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the extents file */
-+ ped_free (node);
-+ return 0;
-+
-+ /* an extent has been found in the extents file */
-+ plus_extent_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ extent_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = extent_data[j].start_block;
-+ extent_data[j].start_block = PED_CPU_TO_BE32 (new_start);
-+ /* This extent might have been cached into the file structure
-+ of the extent or catalog file */
-+ if (priv_data->catalog_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->catalog_file->cache, extent_data,
-+ sizeof (HfsPExtDataRec));
-+ if (priv_data->extents_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->extents_file->cache, extent_data,
-+ sizeof (HfsPExtDataRec));
-+ if (priv_data->attributes_file->cache[j].start_block
-+ == old_start)
-+ memcpy (priv_data->attributes_file->cache,
-+ extent_data, sizeof (HfsPExtDataRec));
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->extents_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_primary (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ unsigned int j;
-+ int new_start;
-+
-+ /* Search an extent in the MDB */
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( priv_data->vh->extents_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->extents_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_ext_file_found;
-+ if ( priv_data->vh->catalog_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->catalog_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_cat_file_found;
-+ if ( priv_data->vh->allocation_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->allocation_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_alloc_file_found;
-+ if ( priv_data->vh->attributes_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->attributes_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_attrib_file_found;
-+ if ( priv_data->vh->startup_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->startup_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_start_file_found;
-+ }
-+ return 0;
-+
-+ plus_start_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->startup_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->startup_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+#if 0
-+ memcpy (priv_data->startup_file->first, priv_data->vh->startup_file.extents, sizeof (HfsPExtDataRec));
-+ if (!priv_data->startup_file->start_cache)
-+ memcpy (priv_data->startup_file->cache, priv_data->startup_file->first, sizeof (HfsPExtDataRec));
-+#endif
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_attrib_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh
-+ ->attributes_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->attributes_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->attributes_file->first,
-+ priv_data->vh->attributes_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->attributes_file->start_cache)
-+ memcpy (priv_data->attributes_file->cache,
-+ priv_data->attributes_file->first,
-+ sizeof (HfsPExtDataRec));
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_alloc_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh
-+ ->allocation_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->allocation_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+#if 0
-+ memcpy (priv_data->allocation_file->first, priv_data->vh->allocation_file.extents, sizeof (HfsPExtDataRec));
-+ if (!priv_data->allocation_file->start_cache)
-+ memcpy (priv_data->allocation_file->cache, priv_data->allocation_file->first, sizeof (HfsPExtDataRec));
-+#endif
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_ext_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->extents_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->extents_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->extents_file->first,
-+ priv_data->vh->extents_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->extents_file->start_cache)
-+ memcpy (priv_data->extents_file->cache,
-+ priv_data->extents_file->first,
-+ sizeof (HfsPExtDataRec));
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_cat_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->catalog_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->catalog_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->catalog_file->first,
-+ priv_data->vh->catalog_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->catalog_file->start_cache)
-+ memcpy (priv_data->catalog_file->cache,
-+ priv_data->catalog_file->first,
-+ sizeof (HfsPExtDataRec));
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_update_vh:
-+ if (!ped_geometry_read (priv_data->plus_geom, node, 2, 1))
-+ return -1;
-+ memcpy (node, priv_data->vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, node, 2, 1))
-+ return -1;
-+ if (!ped_geometry_write (priv_data->plus_geom, node,
-+ priv_data->plus_geom->length - 2, 1))
-+ return -1;
-+ return 1;
-+}
-+
-+/* This function moves an extent starting at block fblock
-+ to block to_fblock if there's enough room */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ int ret;
-+
-+ /* order = decreasing probability to be found */
-+ if ((ret = hfsplus_search_move_catalog (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfsplus_search_move_extent (fs, ptr_fblock,
-+ ptr_to_fblock))
-+ || (ret = hfsplus_search_move_primary (fs, ptr_fblock,
-+ ptr_to_fblock))
-+ || (ret = hfsplus_search_move_attributes (fs, ptr_fblock,
-+ ptr_to_fblock))) {
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves file's data to compact used and free space,
-+ starting at fblock block */
-+/* return 0 on error */
-+static int
-+hfsplus_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
-+ PedTimer* timer)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ unsigned int to_fblock = fblock;
-+ int byte, bit, ret;
-+ int to_byte, to_bit;
-+ unsigned int start = fblock;
-+ unsigned int div = PED_BE32_TO_CPU (vh->total_blocks)
-+ + 1 - start;
-+
-+ to_byte = byte = fblock / 8;
-+ to_bit = bit = 7 - (fblock & 7);
-+
-+ if (!hfsplus_read_bad_blocks (fs))
-+ return 0;
-+
-+ while ( fblock < ( priv_data->plus_geom->length - 2 )
-+ / ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) ) {
-+ if (((priv_data->alloc_map[byte] >> bit) & 1)
-+ && (!hfsplus_is_bad_block (fs, fblock))) {
-+ if (!(ret = hfsplus_move_extent_starting_at (fs,
-+ &fblock,
-+ &to_fblock)))
-+ to_fblock = ++fblock;
-+ else if (ret == -1)
-+ return 0;
-+ } else {
-+ fblock++;
-+ }
-+
-+ byte = fblock / 8;
-+ bit = 7 - (fblock & 7);
-+
-+ to_byte = to_fblock / 8;
-+ to_bit = 7 - (to_fblock & 7);
-+
-+ ped_timer_update(timer, (float)(fblock - start) / div);
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function returns the first sector of the last free block of
-+ an HFS+ volume we can get after a hfsplus_pack_free_space_from_block call */
-+static PedSector
-+hfsplus_get_empty_end (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ HfsPPrivateLinkExtent* link;
-+ unsigned int block, last_bad, end_free_blocks;
-+ int byte, bit;
-+
-+ /* find the next block to the last bad block of the volume */
-+ if (!hfsplus_read_bad_blocks (fs))
-+ return 0;
-+
-+ last_bad = 0;
-+ for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
-+ if ((unsigned int) PED_BE32_TO_CPU (link->extent.start_block)
-+ + PED_BE32_TO_CPU (link->extent.block_count) > last_bad)
-+ last_bad = PED_BE32_TO_CPU (link->extent.start_block)
-+ + PED_BE32_TO_CPU (link->extent.block_count);
-+ }
-+
-+ /* Count the free blocks from last_bad to the end of the volume */
-+ end_free_blocks = 0;
-+ for (block = last_bad;
-+ block < PED_BE32_TO_CPU (vh->total_blocks);
-+ block++) {
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if (!((priv_data->alloc_map[byte]>>bit)&1))
-+ end_free_blocks++;
-+ }
-+
-+ /* Calculate the block that will by the first free at
-+ the end of the volume */
-+ block = PED_BE32_TO_CPU (vh->total_blocks) - end_free_blocks;
-+
-+ return (PedSector) block * ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+}
-+
-+static PedSector
-+hfsplus_get_min_size (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedSector min_size;
-+
-+ /* don't need to add anything because every sector
-+ is part of allocation blocks in HFS+ */
-+ min_size = hfsplus_get_empty_end(fs);
-+
-+ if (priv_data->wrapper) {
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block;
-+ hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+ /*
-+ * if hfs+ is embedded in an hfs wrapper then the new size is :
-+ * the new size of the hfs+ volume rounded up to the size
-+ * of hfs blocks
-+ * + the minimum size of the hfs wrapper without any hfs+
-+ * modification
-+ * - the current size of the hfs+ volume in the hfs wrapper
-+ */
-+ min_size = ((min_size + hfs_sect_block - 1) / hfs_sect_block)
-+ * hfs_sect_block
-+ + hfs_get_empty_end(priv_data->wrapper) + 2
-+ - (PedSector) PED_BE16_TO_CPU ( hfs_priv_data->mdb
-+ ->old_new.embedded
-+ .location.block_count )
-+ * hfs_sect_block;
-+ }
-+
-+ return min_size;
-+}
-+
-+static PedConstraint*
-+hfsplus_get_resize_constraint (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedDevice* dev = fs->geom->dev;
-+ PedAlignment start_align;
-+ PedGeometry start_sector;
-+ PedGeometry full_dev;
-+ PedSector min_size;
-+
-+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
-+ return NULL;
-+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
-+ return NULL;
-+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
-+ return NULL;
-+
-+ min_size = hfsplus_get_min_size (fs);
-+
-+ return ped_constraint_new (&start_align, ped_alignment_any,
-+ &start_sector, &full_dev, min_size,
-+ fs->geom->length);
-+}
-+
-+/* return the block which should be used to pack data to have
-+ at least free fblock blocks at the end of the volume */
-+static unsigned int
-+hfsplus_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ unsigned int block;
-+
-+ for (block = PED_BE32_TO_CPU (priv_data->vh->total_blocks) - 1;
-+ block && fblock;
-+ block--) {
-+ if (!((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ fblock--;
-+ }
-+
-+ while (block && !((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ block--;
-+ if ((priv_data->alloc_map[block / 8] >> (7 - (block & 7))) & 1)
-+ block++;
-+
-+ return block;
-+}
-+
-+static int
-+hfsplus_volume_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ unsigned int nblock, nfree;
-+ unsigned int block;
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ int resize = 1;
-+ unsigned int hfsp_sect_block =
-+ ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ HfsPPrivateFile* allocation_file;
-+ unsigned int map_sectors;
-+
-+ /* Clear the unmounted bit */
-+ vh->attributes &= PED_CPU_TO_BE32 (~( 1 << HFS_UNMOUNTED ));
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, buf, 2, 1))
-+ return 0;
-+
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name(timer, _("shrinking"));
-+ ped_timer_update(timer, 0.0);
-+ /* relocate data */
-+ block = hfsplus_find_start_pack (fs, ( priv_data->plus_geom->length
-+ - geom->length + hfsp_sect_block
-+ - 1 ) / hfsp_sect_block );
-+ if (!hfsplus_pack_free_space_from_block (fs, block, timer)) {
-+ resize = 0;
-+ goto write_VH;
-+ }
-+
-+ /* Calculate new block number and other VH field */
-+ nblock = (geom->length + hfsp_sect_block - 1) / hfsp_sect_block;
-+ nfree = PED_BE32_TO_CPU (vh->free_blocks)
-+ - (PED_BE32_TO_CPU (vh->total_blocks) - nblock);
-+ if (priv_data->plus_geom->length % hfsp_sect_block == 1)
-+ nfree++;
-+ if (geom->length % hfsp_sect_block == 1)
-+ nfree--;
-+
-+ /* Check that all block after future end are really free */
-+ for ( block = nblock;
-+ block < ( priv_data->plus_geom->length - 2 )
-+ / ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE );
-+ block++ ) {
-+ int byte, bit;
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if ((priv_data->alloc_map[byte]>>bit)&1) {
-+ resize = 0;
-+ goto write_VH;
-+ }
-+ }
-+
-+ /* Update geometry */
-+ if (resize) {
-+ /* update in fs structure */
-+ if (PED_BE32_TO_CPU (vh->next_allocation) >= nblock)
-+ vh->next_allocation = PED_CPU_TO_BE32 (0);
-+ vh->total_blocks = PED_CPU_TO_BE32 (nblock);
-+ vh->free_blocks = PED_CPU_TO_BE32 (nfree);
-+ /* update parted structure */
-+ priv_data->plus_geom->length = geom->length;
-+ priv_data->plus_geom->end = priv_data->plus_geom->start
-+ + geom->length - 1;
-+ }
-+
-+ /* Effective write */
-+ write_VH:
-+ /* lasts two sectors are allocated by the alternate VH
-+ and a reserved sector */
-+ block = (priv_data->plus_geom->length - 1) / hfsp_sect_block;
-+ priv_data->alloc_map[block / 8] |= 1 << (7 - (block & 7));
-+ block = (priv_data->plus_geom->length - 2) / hfsp_sect_block;
-+ priv_data->alloc_map[block / 8] |= 1 << (7 - (block & 7));
-+ map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 ) / (PED_SECTOR_SIZE * 8);
-+ allocation_file =
-+ hfsplus_file_open ( fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
-+ vh->allocation_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->allocation_file.logical_size )
-+ / PED_SECTOR_SIZE );
-+ if (!hfsplus_file_write (allocation_file, priv_data->alloc_map,
-+ 0, map_sectors))
-+ resize = 0;
-+ hfsplus_file_close (allocation_file);
-+
-+ if (resize) {
-+ /* Set the unmounted bit and clear the inconsistent bit */
-+ vh->attributes |= PED_CPU_TO_BE32 ( 1 << HFS_UNMOUNTED );
-+ vh->attributes &= ~ PED_CPU_TO_BE32 ( 1 << HFSP_INCONSISTENT );
-+ }
-+
-+ ped_timer_set_state_name(timer, _("writing HFS+ Volume Header"));
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1 ))
-+ return 0;
-+ memcpy (buf, vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, buf, 2, 1 ))
-+ return 0;
-+ if (!ped_geometry_write ( priv_data->plus_geom, buf,
-+ priv_data->plus_geom->length - 2, 1 ))
-+ return 0;
-+ ped_timer_update(timer, 1.0);
-+
-+ return (resize);
-+}
-+
-+/* Update the HFS wrapper mdb and bad blocks file to reflect
-+ the new geometry of the embedded HFS+ volume */
-+static int
-+hfsplus_wrapper_update (PedFileSystem* fs)
-+{
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsCPrivateLeafRec ref;
-+ HfsExtentKey key;
-+ HfsNodeDescriptor* node_desc = (HfsNodeDescriptor*) node;
-+ HfsExtentKey* ret_key;
-+ HfsExtDescriptor* ret_data;
-+ unsigned int i, j;
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE ;
-+ PedSector hfsplus_sect = (PedSector)
-+ PED_BE32_TO_CPU (priv_data->vh->total_blocks)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ unsigned int hfs_blocks_embedded =
-+ (hfsplus_sect + hfs_sect_block - 1)
-+ / hfs_sect_block;
-+ unsigned int hfs_blocks_embedded_old;
-+
-+ /* update HFS wrapper MDB */
-+ hfs_blocks_embedded_old = PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count );
-+ hfs_priv_data->mdb->old_new.embedded.location.block_count =
-+ PED_CPU_TO_BE16 (hfs_blocks_embedded);
-+ /* maybe macOS will boot with this */
-+ hfs_priv_data->mdb->free_blocks =
-+ PED_CPU_TO_BE16 ( PED_BE16_TO_CPU (hfs_priv_data->mdb->free_blocks)
-+ + hfs_blocks_embedded_old
-+ - hfs_blocks_embedded );
-+
-+ if (!ped_geometry_read (fs->geom, node, 2, 1))
-+ return 0;
-+ memcpy (node, hfs_priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, node, 2, 1))
-+ return 0;
-+ if (!ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1))
-+ return 0;
-+
-+ /* force reload bad block list */
-+ if (hfs_priv_data->bad_blocks_loaded) {
-+ hfs_free_bad_blocks_list (hfs_priv_data->bad_blocks_xtent_list);
-+ hfs_priv_data->bad_blocks_xtent_list = NULL;
-+ hfs_priv_data->bad_blocks_xtent_nb = 0;
-+ hfs_priv_data->bad_blocks_loaded = 0;
-+ }
-+
-+ /* clean HFS wrapper allocation map */
-+ for (i = PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new.embedded
-+ .location.start_block )
-+ + hfs_blocks_embedded;
-+ i < PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new.embedded
-+ .location.start_block )
-+ + hfs_blocks_embedded_old;
-+ i++ ) {
-+ hfs_priv_data->alloc_map[i/8] &= ~(1 << (7 - (i & 7)));
-+ }
-+ /* and save it */
-+ if (!ped_geometry_write (fs->geom, hfs_priv_data->alloc_map,
-+ PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->volume_bitmap_block ),
-+ ( PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->total_blocks )
-+ + PED_SECTOR_SIZE * 8 - 1 )
-+ / (PED_SECTOR_SIZE * 8)))
-+ return 0;
-+
-+
-+ /* search and update the bad blocks file */
-+ key.key_length = sizeof(key) - 1;
-+ key.type = HFS_DATA_FORK;
-+ key.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+ key.start = 0;
-+ if (!hfs_btree_search (hfs_priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &key, NULL, 0, &ref))
-+ return 0;
-+ if (!hfs_file_read_sector (hfs_priv_data->extent_file, node,
-+ ref.node_number))
-+ return 0;
-+ ret_key = (HfsExtentKey*) (node + ref.record_pos);
-+ ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
-+ + sizeof (HfsExtentKey) );
-+
-+ while (ret_key->type == key.type && ret_key->file_ID == key.file_ID) {
-+ for (i = 0; i < HFS_EXT_NB; i++) {
-+ if ( ret_data[i].start_block
-+ == hfs_priv_data->mdb->old_new
-+ .embedded.location.start_block) {
-+ ret_data[i].block_count =
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count;
-+ /* found ! : update */
-+ if (!hfs_file_write_sector (
-+ hfs_priv_data->extent_file,
-+ node, ref.node_number))
-+ return 0;
-+ return 1;
-+ }
-+ }
-+
-+ if (ref.record_number < PED_BE16_TO_CPU (node_desc->rec_nb)) {
-+ ref.record_number++;
-+ } else {
-+ ref.node_number = PED_BE32_TO_CPU (node_desc->next);
-+ if (!ref.node_number
-+ || !hfs_file_read_sector(hfs_priv_data->extent_file,
-+ node, ref.node_number))
-+ return 0;
-+ ref.record_number = 1;
-+ }
-+
-+ ref.record_pos = PED_BE16_TO_CPU (*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*ref.record_number))));
-+ ret_key = (HfsExtentKey*) (node + ref.record_pos);
-+ ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
-+ + sizeof (HfsExtentKey) );
-+ }
-+
-+ /* not found : not a valid hfs+ wrapper : failure */
-+ return 0;
-+}
-+
-+static int
-+hfsplus_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedTimer* timer_plus;
-+ PedGeometry* embedded_geom;
-+
-+ /* check preconditions */
-+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
-+
-+ if (fs->geom->start != geom->start)
-+ {
-+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
-+ PED_EXCEPTION_CANCEL,
-+ _("Sorry, can't move the start of hfs partitions yet!"));
-+ return 0;
-+ }
-+
-+ if (geom->length > fs->geom->length
-+ || geom->length < hfsplus_get_min_size (fs))
-+ return 0;
-+
-+ if (priv_data->wrapper) {
-+ PedSector red, hgee;
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+
-+ /* There is a wrapper so we must calculate the new geometry
-+ of the embedded HFS+ volume */
-+ red = ( (fs->geom->length - geom->length + hfs_sect_block - 1)
-+ / hfs_sect_block ) * hfs_sect_block;
-+ /* Can't we shrink the hfs+ volume by the desired size ? */
-+ if ( red > priv_data->plus_geom->length
-+ - (hgee = hfsplus_get_empty_end (fs))) {
-+ /* No, shrink hfs+ by the greatest possible value */
-+ hgee = ((hgee + hfs_sect_block - 1) / hfs_sect_block)
-+ * hfs_sect_block;
-+ red = priv_data->plus_geom->length - hgee;
-+ }
-+ embedded_geom = ped_geometry_new (geom->dev,
-+ priv_data->plus_geom->start,
-+ priv_data->plus_geom->length
-+ - red);
-+
-+ /* There is a wrapper so the resize process is a two stages
-+ process (embedded resizing then wrapper resizing) :
-+ we create a sub timer */
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name (timer,
-+ _("shrinking embedded HFS+ volume"));
-+ ped_timer_update(timer, 0.0);
-+ timer_plus = ped_timer_new_nested (timer, 0.98);
-+ } else {
-+ /* No wrapper : the desired geometry is the desired
-+ HFS+ volume geometry */
-+ embedded_geom = geom;
-+ timer_plus = timer;
-+ }
-+
-+ /* Resize the HFS+ volume */
-+ if (!hfsplus_volume_resize (fs, embedded_geom, timer_plus)) {
-+ if (timer_plus != timer) ped_timer_destroy_nested (timer_plus);
-+ return 0;
-+ }
-+
-+ if (priv_data->wrapper) {
-+ ped_geometry_destroy (embedded_geom);
-+ ped_timer_destroy_nested (timer_plus);
-+ ped_timer_set_state_name(timer, _("shrinking HFS wrapper"));
-+ timer_plus = ped_timer_new_nested (timer, 0.02);
-+ /* There's a wrapper : second stage = resizing it */
-+ if (!hfsplus_wrapper_update (fs)
-+ || !hfs_resize (priv_data->wrapper, geom, timer_plus)) {
-+ ped_timer_destroy_nested (timer_plus);
-+ return 0;
-+ }
-+ ped_timer_destroy_nested (timer_plus);
-+ }
-+ ped_timer_update(timer, 1.0);
-+
-+ return 1;
- }
- #endif /* !DISCOVER_ONLY */
-
-@@ -64,9 +2976,44 @@
- probe: hfs_probe,
- #ifndef DISCOVER_ONLY
- clobber: hfs_clobber,
-+ open: hfs_open,
-+ create: NULL,
-+ close: hfs_close,
-+ check: NULL,
-+ copy: NULL,
-+ resize: hfs_resize,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: hfs_get_resize_constraint,
-+ get_copy_constraint: NULL,
- #else
- clobber: NULL,
-+ open: NULL,
-+ create: NULL,
-+ close: NULL,
-+ check: NULL,
-+ copy: NULL,
-+ resize: NULL,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: NULL,
-+ get_copy_constraint: NULL,
- #endif
-+};
-+
-+static PedFileSystemOps hfsplus_ops = {
-+ probe: hfsplus_probe,
-+#ifndef DISCOVER_ONLY
-+ clobber: hfsplus_clobber,
-+ open: hfsplus_open,
-+ create: NULL,
-+ close: hfsplus_close,
-+ check: NULL,
-+ copy: NULL,
-+ resize: hfsplus_resize,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: hfsplus_get_resize_constraint,
-+ get_copy_constraint: NULL,
-+#else
-+ clobber: NULL,
- open: NULL,
- create: NULL,
- close: NULL,
-@@ -76,23 +3023,32 @@
- get_create_constraint: NULL,
- get_resize_constraint: NULL,
- get_copy_constraint: NULL,
-+#endif
- };
-
-+
- static PedFileSystemType hfs_type = {
- next: NULL,
- ops: &hfs_ops,
- name: "hfs"
- };
-
-+static PedFileSystemType hfsplus_type = {
-+ next: NULL,
-+ ops: &hfsplus_ops,
-+ name: "hfs+"
-+};
-+
- void
- ped_file_system_hfs_init ()
- {
- ped_file_system_type_register (&hfs_type);
-+ ped_file_system_type_register (&hfsplus_type);
- }
-
- void
- ped_file_system_hfs_done ()
- {
- ped_file_system_type_unregister (&hfs_type);
-+ ped_file_system_type_unregister (&hfsplus_type);
- }
--
-diff -u -r -N parted-1.6.5/libparted/fs_hfs/hfs.h parted-1.6.5-hfs/libparted/fs_hfs/hfs.h
---- parted-1.6.5/libparted/fs_hfs/hfs.h Thu Jan 1 01:00:00 1970
-+++ parted-1.6.5-hfs/libparted/fs_hfs/hfs.h Tue Apr 29 05:48:04 2003
-@@ -0,0 +1,543 @@
-+/*
-+ libparted - a library for manipulating disk partitions
-+ Copyright (C) 2003 Free Software Foundation, Inc.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+#ifndef _HFS_H
-+#define _HFS_H
-+
-+
-+#undef HFS_DEBUG
-+
-+#define HFS_SIGNATURE 0x4244
-+#define HFSP_SIGNATURE 0x482B
-+
-+#define HFS_HARD_LOCK 7
-+#define HFS_UNMOUNTED 8
-+#define HFS_BAD_SPARED 9
-+#define HFS_SOFT_LOCK 15
-+#define HFSP_NO_CACHE 10
-+#define HFSP_INCONSISTENT 11
-+
-+#define HFS_IDX_NODE 0x00
-+#define HFS_HDR_NODE 0x01
-+#define HFS_MAP_NODE 0x02
-+#define HFS_LEAF_NODE 0xFF
-+
-+#define HFS_FIRST_REC 0x0E
-+#define HFS_NSD_HD_REC 0x78
-+#define HFS_MAP_REC 0xF8
-+
-+#define HFS_DATA_FORK 0x00
-+#define HFS_RES_FORK 0xFF
-+
-+#define HFS_CAT_DIR 0x01
-+#define HFS_CAT_FILE 0x02
-+#define HFS_CAT_DIR_TH 0x03
-+#define HFS_CAT_FILE_TH 0x04
-+
-+#define HFSP_ATTR_INLINE 0x10
-+#define HFSP_ATTR_FORK 0x20
-+#define HFSP_ATTR_EXTENTS 0x30
-+
-+#define HFS_ROOT_PAR_ID 0x01
-+#define HFS_ROOT_DIR_ID 0x02
-+#define HFS_XTENT_ID 0x03
-+#define HFS_CATALOG_ID 0x04
-+#define HFS_BAD_BLOCK_ID 0x05
-+#define HFSP_ALLOC_ID 0x06
-+#define HFSP_STARTUP_ID 0x07
-+#define HFSP_ATTRIB_ID 0x08
-+#define HFSP_BOGUS_ID 0x0F
-+#define HFSP_FIRST_AV_ID 0x10
-+
-+#define HFS_EXT_NB 3
-+#define HFSP_EXT_NB 8
-+
-+static PedFileSystemType hfs_type;
-+static PedFileSystemType hfsplus_type;
-+
-+
-+
-+/* ----------------------------------- */
-+/* -- HFS DATA STRUCTURES -- */
-+/* ----------------------------------- */
-+
-+/* Extent descriptor */
-+struct __attribute__ ((packed)) _HfsExtDescriptor {
-+ uint16_t start_block;
-+ uint16_t block_count;
-+};
-+typedef struct _HfsExtDescriptor HfsExtDescriptor;
-+typedef HfsExtDescriptor HfsExtDataRec[HFS_EXT_NB];
-+
-+/* Volume header */
-+struct __attribute__ ((packed)) _HfsMasterDirectoryBlock {
-+ uint16_t signature;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint16_t volume_attributes;
-+ uint16_t files_in_root;
-+ uint16_t volume_bitmap_block; /* in sectors */
-+ uint16_t next_allocation;
-+ uint16_t total_blocks;
-+ uint32_t block_size; /* in bytes */
-+ uint32_t def_clump_size; /* in bytes */
-+ uint16_t start_block; /* in sectors */
-+ uint32_t next_free_node;
-+ uint16_t free_blocks;
-+ uint8_t name_length;
-+ char name[27];
-+ uint32_t backup_date;
-+ uint16_t backup_number;
-+ uint32_t write_count;
-+ uint32_t extents_clump;
-+ uint32_t catalog_clump;
-+ uint16_t dirs_in_root;
-+ uint32_t file_count;
-+ uint32_t dir_count;
-+ uint32_t finder_info[8];
-+ union __attribute__ ((packed)) {
-+ struct __attribute__ ((packed)) {
-+ uint16_t volume_cache_size; /* in blocks */
-+ uint16_t bitmap_cache_size; /* in blocks */
-+ uint16_t common_cache_size; /* in blocks */
-+ } legacy;
-+ struct __attribute__ ((packed)) {
-+ uint16_t signature;
-+ HfsExtDescriptor location;
-+ } embedded;
-+ } old_new;
-+ uint32_t extents_file_size; /* in bytes, block size multiple */
-+ HfsExtDataRec extents_file_rec;
-+ uint32_t catalog_file_size; /* in bytes, block size multiple */
-+ HfsExtDataRec catalog_file_rec;
-+};
-+typedef struct _HfsMasterDirectoryBlock HfsMasterDirectoryBlock;
-+
-+/* B*-Tree Node Descriptor */
-+struct __attribute__ ((packed)) _HfsNodeDescriptor {
-+ uint32_t next;
-+ uint32_t previous;
-+ int8_t type;
-+ uint8_t height;
-+ uint16_t rec_nb;
-+ uint16_t reserved;
-+};
-+typedef struct _HfsNodeDescriptor HfsNodeDescriptor;
-+
-+/* Header record of a whole B*-Tree */
-+struct __attribute__ ((packed)) _HfsHeaderRecord {
-+ uint16_t depth;
-+ uint32_t root_node;
-+ uint32_t leaf_records;
-+ uint32_t first_leaf_node;
-+ uint32_t last_leaf_node;
-+ uint16_t node_size;
-+ uint16_t max_key_len;
-+ uint32_t total_nodes;
-+ uint32_t free_nodes;
-+ int8_t reserved[76];
-+};
-+typedef struct _HfsHeaderRecord HfsHeaderRecord;
-+
-+/* Catalog key for B*-Tree lookup in the catalog file */
-+struct __attribute__ ((packed)) _HfsCatalogKey {
-+ int8_t key_length; /* length of the key without key_length */
-+ int8_t reserved;
-+ uint32_t parent_ID;
-+ int8_t name_length;
-+ char name[31]; /* in fact physicaly 1 upto 31 */
-+};
-+typedef struct _HfsCatalogKey HfsCatalogKey;
-+
-+/* Extents overflow key for B*-Tree lookup */
-+struct __attribute__ ((packed)) _HfsExtentKey {
-+ int8_t key_length; /* length of the key without key_length */
-+ int8_t type; /* data or ressource fork */
-+ uint32_t file_ID;
-+ uint16_t start;
-+};
-+typedef struct _HfsExtentKey HfsExtentKey;
-+
-+/* Catalog subdata case directory */
-+struct __attribute__ ((packed)) _HfsDir {
-+ uint16_t flags;
-+ uint16_t valence; /* number of files in this directory */
-+ uint32_t dir_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ int8_t DInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t DXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t reserved[4];
-+};
-+typedef struct _HfsDir HfsDir;
-+
-+/* Catalog subdata case file */
-+struct __attribute__ ((packed)) _HfsFile {
-+ int8_t flags;
-+ int8_t type; /* should be 0 */
-+ int8_t FInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t file_ID;
-+ uint16_t data_start_block;
-+ uint32_t data_sz_byte;
-+ uint32_t data_sz_block;
-+ uint16_t res_start_block;
-+ uint32_t res_sz_byte;
-+ uint32_t res_sz_block;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ int8_t FXInfo[16]; /* used by Finder, handle as reserved */
-+ uint16_t clump_size;
-+ HfsExtDataRec extents_data;
-+ HfsExtDataRec extents_res;
-+ uint32_t reserved;
-+};
-+typedef struct _HfsFile HfsFile;
-+
-+/* Catalog subdata case directory thread */
-+struct __attribute__ ((packed)) _HfsDirTh {
-+ uint32_t reserved[2];
-+ uint32_t parent_ID;
-+ int8_t name_length;
-+ char name[31];
-+};
-+typedef struct _HfsDirTh HfsDirTh;
-+
-+/* Catalog subdata case file thread */
-+typedef struct _HfsDirTh HfsFileTh; /* same as directory thread */
-+
-+/* Catalog data */
-+struct __attribute__ ((packed)) _HfsCatalog {
-+ int8_t type;
-+ int8_t reserved;
-+ union {
-+ HfsDir dir;
-+ HfsFile file;
-+ HfsDirTh dir_th;
-+ HfsFileTh file_th;
-+ } sel;
-+};
-+typedef struct _HfsCatalog HfsCatalog;
-+
-+
-+
-+/* ------------------------------------ */
-+/* -- HFS+ DATA STRUCTURES -- */
-+/* ------------------------------------ */
-+
-+/* Permission struct is reserved in HFS+ official specification */
-+/* May be it could be used in unix implementations of HFS+ */
-+struct __attribute__ ((packed)) _HfsPPerms {
-+ uint32_t owner_ID; /* reserved */
-+ uint32_t group_ID; /* reserved */
-+ uint32_t permissions; /* reserved */
-+ uint32_t special_devices; /* reserved */
-+};
-+typedef struct _HfsPPerms HfsPPerms;
-+
-+/* HFS+ extent descriptor*/
-+struct __attribute__ ((packed)) _HfsPExtDescriptor {
-+ uint32_t start_block;
-+ uint32_t block_count;
-+};
-+typedef struct _HfsPExtDescriptor HfsPExtDescriptor;
-+typedef HfsPExtDescriptor HfsPExtDataRec[HFSP_EXT_NB];
-+
-+/* HFS+ fork data structure */
-+struct __attribute__ ((packed)) _HfsPForkData {
-+ uint64_t logical_size;
-+ uint32_t clump_size;
-+ uint32_t total_blocks;
-+ HfsPExtDataRec extents;
-+};
-+typedef struct _HfsPForkData HfsPForkData;
-+
-+/* HFS+ catalog node ID */
-+typedef uint32_t HfsPNodeID;
-+
-+/* HFS+ file names */
-+typedef uint16_t unichar;
-+struct __attribute__ ((packed)) _HfsPUniStr255 {
-+ uint16_t length;
-+ unichar unicode[255]; /* 1 upto 255 */
-+};
-+typedef struct _HfsPUniStr255 HfsPUniStr255;
-+
-+/* HFS+ volume header */
-+struct __attribute__ ((packed)) _HfsPVolumeHeader {
-+ uint16_t signature;
-+ uint16_t version;
-+ uint32_t attributes;
-+ uint32_t last_mounted_version;
-+ uint32_t reserved;
-+
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ uint32_t checked_date;
-+
-+ uint32_t file_count;
-+ uint32_t dir_count;
-+
-+ uint32_t block_size;
-+ uint32_t total_blocks;
-+ uint32_t free_blocks;
-+
-+ uint32_t next_allocation;
-+ uint32_t res_clump_size;
-+ uint32_t data_clump_size;
-+ HfsPNodeID next_catalog_ID;
-+
-+ uint32_t write_count;
-+ uint64_t encodings_bitmap;
-+
-+ uint8_t finder_info[32];
-+
-+ HfsPForkData allocation_file;
-+ HfsPForkData extents_file;
-+ HfsPForkData catalog_file;
-+ HfsPForkData attributes_file;
-+ HfsPForkData startup_file;
-+};
-+typedef struct _HfsPVolumeHeader HfsPVolumeHeader;
-+
-+/* HFS+ B-Tree Node Descriptor */ /* same as HFS btree */
-+struct __attribute__ ((packed)) _HfsPNodeDescriptor {
-+ uint32_t next;
-+ uint32_t previous;
-+ int8_t type;
-+ uint8_t height;
-+ uint16_t rec_nb;
-+ uint16_t reserved;
-+};
-+typedef struct _HfsPNodeDescriptor HfsPNodeDescriptor;
-+
-+/* Header record of a whole HFS+ B-Tree */
-+struct __attribute__ ((packed)) _HfsPHeaderRecord {
-+ uint16_t depth;
-+ uint32_t root_node;
-+ uint32_t leaf_records;
-+ uint32_t first_leaf_node;
-+ uint32_t last_leaf_node;
-+ uint16_t node_size;
-+ uint16_t max_key_len;
-+ uint32_t total_nodes;
-+ uint32_t free_nodes; /* same as hfs btree until here */
-+ uint16_t reserved1;
-+
-+ uint32_t clump_size;
-+ uint8_t btree_type; /* must be 0 for HFS+ B-Tree */
-+ uint8_t reserved2;
-+ uint32_t attributes;
-+ uint32_t reserved3[16];
-+};
-+typedef struct _HfsPHeaderRecord HfsPHeaderRecord;
-+
-+/* Catalog key for B-Tree lookup in the HFS+ catalog file */
-+struct __attribute__ ((packed)) _HfsPCatalogKey {
-+ uint16_t key_length;
-+ HfsPNodeID parent_ID;
-+ HfsPUniStr255 node_name;
-+};
-+typedef struct _HfsPCatalogKey HfsPCatalogKey;
-+
-+/* HFS+ catalog subdata case dir */
-+struct __attribute__ ((packed)) _HfsPDir {
-+ uint16_t flags;
-+ uint32_t valence;
-+ HfsPNodeID dir_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t attrib_mod_date;
-+ uint32_t access_date;
-+ uint32_t backup_date;
-+ HfsPPerms permissions;
-+ int8_t DInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t DXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t text_encoding;
-+ uint32_t reserved;
-+};
-+typedef struct _HfsPDir HfsPDir;
-+
-+/* HFS+ catalog subdata case file */
-+struct __attribute__ ((packed)) _HfsPFile {
-+ uint16_t flags;
-+ uint32_t reserved1;
-+ HfsPNodeID file_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t attrib_mod_date;
-+ uint32_t access_date;
-+ uint32_t backup_date;
-+ HfsPPerms permissions;
-+ int8_t FInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t FXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t text_encoding;
-+ uint32_t reserved2;
-+
-+ HfsPForkData data_fork;
-+ HfsPForkData res_fork;
-+};
-+typedef struct _HfsPFile HfsPFile;
-+
-+/* HFS+ catalog subdata case thread */
-+struct __attribute__ ((packed)) _HfsPThread {
-+ int16_t reserved;
-+ HfsPNodeID parent_ID;
-+ HfsPUniStr255 node_name;
-+};
-+typedef struct _HfsPThread HfsPDirTh;
-+typedef struct _HfsPThread HfsPFileTh;
-+
-+/* HFS+ Catalog leaf data */
-+struct __attribute__ ((packed)) _HfsPCatalog {
-+ int16_t type;
-+ union {
-+ HfsPDir dir;
-+ HfsPFile file;
-+ HfsPDirTh dir_th;
-+ HfsPFileTh file_th;
-+ } sel;
-+};
-+typedef struct _HfsPCatalog HfsPCatalog;
-+
-+/* HFS+ extents file key */
-+struct __attribute__ ((packed)) _HfsPExtentKey {
-+ uint16_t key_length;
-+ uint8_t type;
-+ uint8_t pad;
-+ HfsPNodeID file_ID;
-+ uint32_t start;
-+};
-+typedef struct _HfsPExtentKey HfsPExtentKey;
-+
-+/* extent file data is HfsPExtDataRec */
-+
-+/* Fork data attribute file */
-+struct __attribute__ ((packed)) _HfsPForkDataAttr {
-+ uint32_t record_type;
-+ uint32_t reserved;
-+ union __attribute__ ((packed)) {
-+ HfsPForkData fork;
-+ HfsPExtDataRec extents;
-+ } fork_res;
-+};
-+typedef struct _HfsPForkDataAttr HfsPForkDataAttr;
-+
-+
-+
-+/* ---------------------------------------- */
-+/* -- INTERNAL DATA STRUCTURES -- */
-+/* ---------------------------------------- */
-+
-+/* Data of an opened HFS file */
-+struct _HfsPrivateFile {
-+ PedSector sect_nb;
-+ PedFileSystem* fs;
-+ uint32_t CNID; /* disk order (BE) */
-+ HfsExtDataRec first; /* disk order (BE) */
-+ HfsExtDataRec cache; /* disk order (BE) */
-+ uint16_t start_cache; /* CPU order */
-+};
-+typedef struct _HfsPrivateFile HfsPrivateFile;
-+
-+/* To store bad block list */
-+struct _HfsPrivateLinkExtent {
-+ HfsExtDescriptor extent;
-+ struct _HfsPrivateLinkExtent* next;
-+};
-+typedef struct _HfsPrivateLinkExtent HfsPrivateLinkExtent;
-+
-+/* HFS Filesystem specific data */
-+struct _HfsPrivateFSData {
-+ uint8_t alloc_map[(1<<16) / 8];
-+ HfsMasterDirectoryBlock* mdb;
-+ HfsPrivateFile* extent_file;
-+ HfsPrivateFile* catalog_file;
-+ char bad_blocks_loaded;
-+ unsigned int bad_blocks_xtent_nb;
-+ HfsPrivateLinkExtent* bad_blocks_xtent_list;
-+};
-+typedef struct _HfsPrivateFSData HfsPrivateFSData;
-+
-+/* Generic btree key */
-+struct __attribute__ ((packed)) _HfsPrivateGenericKey {
-+ int8_t key_length;
-+ uint8_t key_content[1]; /* we use 1 as a minimum size */
-+};
-+typedef struct _HfsPrivateGenericKey HfsPrivateGenericKey;
-+
-+/* ----- HFS+ ----- */
-+
-+/* Data of an opened HFS file */
-+struct _HfsPPrivateFile {
-+ PedSector sect_nb;
-+ PedFileSystem* fs;
-+ HfsPNodeID CNID; /* disk order (BE) */
-+ HfsPExtDataRec first; /* disk order (BE) */
-+ HfsPExtDataRec cache; /* disk order (BE) */
-+ uint32_t start_cache; /* CPU order */
-+};
-+typedef struct _HfsPPrivateFile HfsPPrivateFile;
-+
-+/* To store bad block list */
-+struct _HfsPPrivateLinkExtent {
-+ HfsPExtDescriptor extent;
-+ struct _HfsPPrivateLinkExtent* next;
-+};
-+typedef struct _HfsPPrivateLinkExtent HfsPPrivateLinkExtent;
-+
-+/* HFS+ filesystem specific data */
-+struct _HfsPPrivateFSData {
-+ PedFileSystem* wrapper; /* NULL if hfs+ is not embedded */
-+ PedGeometry* plus_geom; /* Geometry of HFS+ _volume_ */
-+ char free_geom; /* 1 = plus_geom must be freed */
-+ uint8_t* alloc_map;
-+ HfsPVolumeHeader* vh;
-+ HfsPPrivateFile* extents_file;
-+ HfsPPrivateFile* catalog_file;
-+ HfsPPrivateFile* attributes_file;
-+ char bad_blocks_loaded;
-+ unsigned int bad_blocks_xtent_nb;
-+ HfsPPrivateLinkExtent* bad_blocks_xtent_list;
-+};
-+typedef struct _HfsPPrivateFSData HfsPPrivateFSData;
-+
-+/* Generic + btree key */
-+struct __attribute__ ((packed)) _HfsPPrivateGenericKey {
-+ uint16_t key_length;
-+ uint8_t key_content[1]; /* we use 1 as a minimum size */
-+};
-+typedef struct _HfsPPrivateGenericKey HfsPPrivateGenericKey;
-+
-+/* ---- common ---- */
-+
-+/* node and lead record reference for a BTree search */
-+struct _HfsCPrivateLeafRec {
-+ unsigned int node_size; /* in sectors */
-+ unsigned int node_number;
-+ unsigned int record_pos;
-+ unsigned int record_number;
-+};
-+typedef struct _HfsCPrivateLeafRec HfsCPrivateLeafRec;
-+
-+
-+
-+#endif /* _HFS_H */
diff --git a/sys-apps/parted/files/parted-1.6.6-2-6headers.patch b/sys-apps/parted/files/parted-1.6.6-2-6headers.patch
deleted file mode 100644
index a6e7a4b8a88b..000000000000
--- a/sys-apps/parted/files/parted-1.6.6-2-6headers.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- parted-1.6.6/libparted/linux.c 2003-02-15 21:30:03.000000000 +0000
-+++ parted-1.6.6/libparted/linux.c 2004-02-02 17:38:16.000000000 +0000
-@@ -215,6 +215,14 @@
- #define I2O_MAJOR7 86
- #define I2O_MAJOR8 87
-
-+/* plasmaroo@gentoo.org :: 2.6 Compatibility */
-+
-+#undef _IOR
-+#undef _IOWR
-+
-+#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-+#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-+
- #define SCSI_BLK_MAJOR(M) ( \
- (M) == SCSI_DISK0_MAJOR \
- || (M) == SCSI_CDROM_MAJOR \
diff --git a/sys-apps/parted/files/parted-1.6.6-assert.patch b/sys-apps/parted/files/parted-1.6.6-assert.patch
deleted file mode 100644
index c13c8139f303..000000000000
--- a/sys-apps/parted/files/parted-1.6.6-assert.patch
+++ /dev/null
@@ -1,141 +0,0 @@
-diff -Nru parted-1.6.6/libparted/fs_reiserfs/geom_dal.c parted-1.6.6-assert/libparted/fs_reiserfs/geom_dal.c
---- parted-1.6.6/libparted/fs_reiserfs/geom_dal.c Sat Aug 10 02:47:33 2002
-+++ parted-1.6.6-assert/libparted/fs_reiserfs/geom_dal.c Mon Oct 27 23:25:05 2003
-@@ -34,21 +34,29 @@
- }
-
- static int __read(dal_t *dal, void *buff, blk_t block, blk_t count) {
-- blk_t k = dal->block_size / PED_SECTOR_SIZE;
-- PedSector block_pos = (PedSector)(block * k);
-- PedSector block_count = (PedSector)(count * k);
-+ blk_t k;
-+ PedSector block_pos;
-+ PedSector block_count;
-
- PED_ASSERT(dal != NULL, return 0);
-
-+ k = dal->block_size / PED_SECTOR_SIZE;
-+ block_pos = (PedSector)(block * k);
-+ block_count = (PedSector)(count * k);
-+
- return ped_geometry_read((PedGeometry *)dal->dev, buff, block_pos, block_count);
- }
-
- static int __write(dal_t *dal, void *buff, blk_t block, blk_t count) {
-- blk_t k = dal->block_size / PED_SECTOR_SIZE;
-- PedSector block_pos = (PedSector)(block * k);
-- PedSector block_count = (PedSector)(count * k);
-+ blk_t k;
-+ PedSector block_pos;
-+ PedSector block_count;
-
- PED_ASSERT(dal != NULL, return 0);
-+
-+ k = dal->block_size / PED_SECTOR_SIZE;
-+ block_pos = (PedSector)(block * k);
-+ block_count = (PedSector)(count * k);
-
- return ped_geometry_write((PedGeometry *)dal->dev, buff, block_pos,
- block_count);
-diff -Nru parted-1.6.6/libparted/geom.c parted-1.6.6-assert/libparted/geom.c
---- parted-1.6.6/libparted/geom.c Mon Apr 8 12:08:46 2002
-+++ parted-1.6.6-assert/libparted/geom.c Mon Oct 27 23:25:05 2003
-@@ -183,12 +183,14 @@
- PedSector count)
- {
- int exception_status;
-- PedSector real_start = geom->start + start;
-+ PedSector real_start;
-
- PED_ASSERT (geom != NULL, return 0);
- PED_ASSERT (buffer != NULL, return 0);
- PED_ASSERT (start >= 0, return 0);
- PED_ASSERT (count >= 0, return 0);
-+
-+ real_start = geom->start + start;
-
- if (real_start + count - 1 > geom->end) {
- exception_status = ped_exception_throw (
-@@ -217,12 +219,14 @@
- PedSector count)
- {
- int exception_status;
-- PedSector real_start = geom->start + start;
-+ PedSector real_start;
-
- PED_ASSERT (geom != NULL, return 0);
- PED_ASSERT (buffer != NULL, return 0);
- PED_ASSERT (start >= 0, return 0);
- PED_ASSERT (count >= 0, return 0);
-+
-+ real_start = geom->start + start;
-
- if (real_start + count - 1 > geom->end) {
- exception_status = ped_exception_throw (
-diff -Nru parted-1.6.6/libparted/gnu.c parted-1.6.6-assert/libparted/gnu.c
---- parted-1.6.6/libparted/gnu.c Thu Jun 26 05:57:34 2003
-+++ parted-1.6.6-assert/libparted/gnu.c Mon Oct 27 23:25:05 2003
-@@ -733,13 +733,15 @@
- static int
- gnu_sync (PedDevice* dev)
- {
-- GNUSpecific* arch_specific = GNU_SPECIFIC (dev);
-+ GNUSpecific* arch_specific;
- error_t err;
- PedExceptionOption ex_status;
- static char *last_failure = NULL;
-
- PED_ASSERT (dev != NULL, return 0);
- PED_ASSERT (!dev->external_mode, return 0);
-+
-+ arch_specific = GNU_SPECIFIC (dev);
-
- if (dev->read_only || ! dev->dirty)
- return 1;
-diff -Nru parted-1.6.6/libparted/linux.c parted-1.6.6-assert/libparted/linux.c
---- parted-1.6.6/libparted/linux.c Sat Feb 15 22:30:03 2003
-+++ parted-1.6.6-assert/libparted/linux.c Mon Oct 27 23:25:05 2003
-@@ -1011,10 +1011,12 @@
- static int
- _device_seek (PedDevice* dev, PedSector sector)
- {
-- LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
-+ LinuxSpecific* arch_specific;
-
- PED_ASSERT (dev != NULL, return 0);
- PED_ASSERT (!dev->external_mode, return 0);
-+
-+ arch_specific = LINUX_SPECIFIC (dev);
-
- #if SIZEOF_OFF_T < 8
- if (sizeof (off_t) < 8) {
-@@ -1031,11 +1033,13 @@
- static int
- _read_lastoddsector (PedDevice* dev, void* buffer)
- {
-- LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
-+ LinuxSpecific* arch_specific;
- struct blkdev_ioctl_param ioctl_param;
-
- PED_ASSERT(dev != NULL, return 0);
- PED_ASSERT(buffer != NULL, return 0);
-+
-+ arch_specific = LINUX_SPECIFIC (dev);
-
- retry:
- ioctl_param.block = 0; /* read the last sector */
-@@ -1135,11 +1139,13 @@
- static int
- _write_lastoddsector (PedDevice* dev, const void* buffer)
- {
-- LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
-+ LinuxSpecific* arch_specific;
- struct blkdev_ioctl_param ioctl_param;
-
- PED_ASSERT(dev != NULL, return 0);
- PED_ASSERT(buffer != NULL, return 0);
-+
-+ arch_specific = LINUX_SPECIFIC (dev);
-
- retry:
- ioctl_param.block = 0; /* write the last sector */
diff --git a/sys-apps/parted/files/parted-1.6.6-gcc-3.3.patch b/sys-apps/parted/files/parted-1.6.6-gcc-3.3.patch
deleted file mode 100644
index 7268de60959b..000000000000
--- a/sys-apps/parted/files/parted-1.6.6-gcc-3.3.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-diff -ruN parted-1.6.5.orig/libparted/disk_gpt.c parted-1.6.5/libparted/disk_gpt.c
---- parted-1.6.5.orig/libparted/disk_gpt.c 2003-06-27 18:11:23.000000000 +0200
-+++ parted-1.6.5/libparted/disk_gpt.c 2003-06-27 17:15:53.000000000 +0200
-@@ -51,9 +51,9 @@
- #define EFI_PMBR_OSTYPE_EFI 0xEE
- #define MSDOS_MBR_SIGNATURE 0xaa55
-
- #define GPT_HEADER_SIGNATURE 0x5452415020494645LL
--#define GPT_HEADER_REVISION_V1_00 0x00010000
--#define GPT_HEADER_REVISION_V0_99 0x00009900
-+#define GPT_HEADER_REVISION_V1_00 0x00010000LL
-+#define GPT_HEADER_REVISION_V0_99 0x00009900LL
-
- typedef uint16_t efi_char16_t; /* UNICODE character */
-
-diff -ruN parted-1.6.5.orig/libparted/disk_sun.c parted-1.6.5/libparted/disk_sun.c
---- parted-1.6.5.orig/libparted/disk_sun.c 2003-06-27 18:11:23.000000000 +0200
-+++ parted-1.6.5/libparted/disk_sun.c 2003-06-27 17:28:14.000000000 +0200
-@@ -38,7 +38,7 @@
- /* Most of this came from util-linux's sun support, which was mostly done
- by Jakub Jelinek. */
-
--#define SUN_DISK_MAGIC 0xDABE /* Disk magic number */
-+#define SUN_DISK_MAGIC 0xDABE /* Disk magic number */
- #define SUN_DISK_MAXPARTITIONS 8
-
- #define WHOLE_DISK_ID 0x05
-@@ -354,7 +354,7 @@
- if (!ped_device_read (disk->dev, &old_label, 0, 1))
- return;
- if (old_label.info [0]
-- && old_label.magic == PED_CPU_TO_LE32 (SUN_DISK_MAGIC))
-+ && old_label.magic == PED_CPU_TO_LE16 (SUN_DISK_MAGIC))
- memcpy (&sun_specific->raw_label, &old_label, 512);
- }
-
diff --git a/sys-apps/parted/files/parted-1.6.6-hfs-8.patch b/sys-apps/parted/files/parted-1.6.6-hfs-8.patch
deleted file mode 100644
index 086c529a4d61..000000000000
--- a/sys-apps/parted/files/parted-1.6.6-hfs-8.patch
+++ /dev/null
@@ -1,3636 +0,0 @@
-diff -u -r -N parted-1.6.5/AUTHORS parted-1.6.5-hfs/AUTHORS
---- parted-1.6.5/AUTHORS Wed Jun 26 04:29:49 2002
-+++ parted-1.6.5-hfs/AUTHORS Tue Apr 29 05:46:52 2003
-@@ -137,3 +137,7 @@
-
- Miloslav Trmac <mitr@volny.cz>
- * Czech translations
-+
-+Guillaume Knispel <k_guillaume@libertysurf.fr>
-+ * nearly all hfs and hfs+ code (libparted/fs_hfs)
-+ * hfs+ support for mac partitions (libparted/disk_mac.c)
-diff -u -r -N parted-1.6.5/libparted/disk_mac.c parted-1.6.5-hfs/libparted/disk_mac.c
---- parted-1.6.5/libparted/disk_mac.c Mon Apr 8 12:08:03 2002
-+++ parted-1.6.5-hfs/libparted/disk_mac.c Tue Apr 29 05:47:10 2003
-@@ -1068,7 +1068,8 @@
- return 1;
- }
-
-- if (fs_type && !strcmp (fs_type->name, "hfs")) {
-+ if (fs_type && ( !strcmp (fs_type->name, "hfs")
-+ || !strcmp (fs_type->name, "hfs+"))) {
- strcpy (mac_data->system_name, "Apple_HFS");
- mac_data->status |= 0x7f;
- } else {
-@@ -1082,7 +1083,6 @@
- static int
- mac_partition_set_flag (PedPartition* part, PedPartitionFlag flag, int state)
- {
-- PedFileSystemType* hfs = ped_file_system_type_get ("hfs");
- MacPartitionData* mac_data;
-
- PED_ASSERT (part != NULL, return 0);
-diff -u -r -N parted-1.6.5/libparted/fs_hfs/hfs.c parted-1.6.5-hfs/libparted/fs_hfs/hfs.c
---- parted-1.6.5/libparted/fs_hfs/hfs.c Mon Apr 8 12:10:25 2002
-+++ parted-1.6.5-hfs/libparted/fs_hfs/hfs.c Tue Apr 29 05:48:04 2003
-@@ -1,6 +1,6 @@
- /*
- libparted - a library for manipulating disk partitions
-- Copyright (C) 2000 Free Software Foundation, Inc.
-+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
-
- 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
-@@ -17,10 +17,52 @@
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-+/*
-+ Technical doc about Apple HFS and HFS+ file systems is available at :
-+ * For HFS, section "Data Organization on Volumes",
-+ "Chapter 2 - File Manager"
-+ of the book "Inside Macintosh: Files"
-+ http://developer.apple.com/techpubs/mac/Files/Files-99.html#HEADING99-0
-+ * For HFS+, "Technical Note TN1150", "HFS Plus Volume Format"
-+ http://developer.apple.com/technotes/tn/tn1150.html
-+
-+ Some useful HFS precisions concerning alignement and bit ordering
-+ are in the HFS+ TN
-+*/
-+
-+/* HISTORY :
-+## modifications dd-mm-yyyy
-+---------------------- PATCH FOR PARTED 1.6.5 ----------------------------
-+ 1 initial revision 07-04-2003
-+ 2 one pass resizing, removal of debug info 08-04-2003
-+ 3 safe abort if resize failed, code cleanups, timer, 10-04-2003
-+ source file split, won't resize if not unmounted,
-+ only relocate data if needed, minimize disk operations
-+ 4 memory leaks removal, code cleanups, resize hfs+ code, 17-04-2003
-+ more checks, minor hfs resize bugfix, probe code
-+ returns real geometry
-+ 5 hfs+ resize bugfixes : 19-04-2003
-+ * fragmented fs could be corrupted
-+ * VH wasn't written on error during alloc map writing
-+ * attributes file could be corrupted
-+ 6 Use PedSector to be able to use > 2 To HD 23-04-2003
-+ Minor probe bugfix, Cleanups, HFS+ Timer tuning,
-+ 7 80 columns indentation 23-04-2003
-+ 8 Bugfix free blocks calculation in wrapper
-+ (makes Mac OS boot !) 28-04-2003
-+*/
-+
-+/* TODO : Think about a mean to do more allocation bitmap
-+ saves when shrinking hfs+ */
-+
- #include "config.h"
-
-+#include <stdlib.h>
-+#include <string.h>
- #include <parted/parted.h>
- #include <parted/endian.h>
-+#include <parted/debug.h>
-+#include <stdint.h>
-
- #if ENABLE_NLS
- # include <libintl.h>
-@@ -31,32 +73,2902 @@
-
- #include <string.h>
-
--#define HFS_SIGNATURE 0x4244
-+#include "hfs.h"
-+
-+
-+
-+/* -------------------- */
-+/* -- CODE -- */
-+/* -------------------- */
-+
-+/* Probe an HFS volume, detecting it even if
-+it is in fact a wrapper to an HFS+ volume */
-+/* Used by hfsplus_probe and hfs_probe */
-+static PedGeometry*
-+hfs_and_wrapper_probe (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ HfsMasterDirectoryBlock *mdb;
-+ PedGeometry* geom_ret;
-+ PedSector search, max;
-+
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if ((geom->length < 5)
-+ || (!ped_geometry_read (geom, buf, 2, 1))
-+ || (PED_BE16_TO_CPU (mdb->signature) != HFS_SIGNATURE) )
-+ return NULL;
-+
-+ search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
-+ * (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE )));
-+ max = search + ( PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE );
-+ if (!(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
-+ return NULL;
-+
-+ for (; search < max; search++) {
-+ if (!ped_geometry_set (geom_ret, geom_ret->start, search + 2)
-+ || !ped_geometry_read (geom_ret, buf, search, 1))
-+ break;
-+ if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE)
-+ return geom_ret;
-+ }
-+
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+}
-+
-+static PedGeometry*
-+hfsplus_probe (PedGeometry* geom)
-+{
-+ PedGeometry* geom_ret;
-+ uint8_t buf[PED_SECTOR_SIZE];
-+
-+ if ((geom_ret = hfs_and_wrapper_probe(geom))) {
-+ /* HFS+ is embedded in an HFS volume ? */
-+ HfsMasterDirectoryBlock *mdb;
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1)
-+ || (PED_BE16_TO_CPU (mdb->old_new.embedded.signature)
-+ != HFSP_SIGNATURE)) {
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+ } else
-+ return geom_ret;
-+ } else {
-+ /* This is a standalone HFS+ volume ? */
-+ PedSector search, max;
-+ HfsPVolumeHeader *vh;
-+ vh = (HfsPVolumeHeader *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1)
-+ || (PED_BE16_TO_CPU (vh->signature) != HFSP_SIGNATURE))
-+ return NULL;
-+
-+ max = (PedSector) PED_BE32_TO_CPU (vh->total_blocks)
-+ * ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE );
-+ search = max - ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) - 1;
-+ if (!(geom_ret = ped_geometry_new (geom->dev, geom->start,
-+ search + 2)))
-+ return NULL;
-+
-+ for (; search < max; search++) {
-+ if (!ped_geometry_set (geom_ret, geom_ret->start,
-+ search + 2)
-+ || !ped_geometry_read (geom_ret, buf, search, 1))
-+ break;
-+ if (PED_BE16_TO_CPU (vh->signature) == HFSP_SIGNATURE)
-+ return geom_ret;
-+ }
-+
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+ }
-+}
-
- static PedGeometry*
- hfs_probe (PedGeometry* geom)
- {
-- char buf[512];
-+ PedGeometry* geom_base;
-+ PedGeometry* geom_plus = NULL;
-+
-+ if ((geom_base = hfs_and_wrapper_probe(geom))
-+ && (!(geom_plus = hfsplus_probe(geom_base))))
-+ return geom_base;
-+ else {
-+ if (geom_base) ped_geometry_destroy (geom_base);
-+ if (geom_plus) ped_geometry_destroy (geom_plus);
-+ return NULL;
-+ }
-+}
-+
-+#ifndef DISCOVER_ONLY
-+/* declaration used by hfs_btree_search (indirect recursion) */
-+static int
-+hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector);
-+
-+static int
-+hfs_clobber (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+
-+ memset (buf, 0, PED_SECTOR_SIZE);
-+
-+ /* destroy boot blocks, mdb, alternate mdb ... */
-+ return ped_geometry_write (geom, buf, 0, 1) &
-+ ped_geometry_write (geom, buf, 1, 1) &
-+ ped_geometry_write (geom, buf, 2, 1) &
-+ ped_geometry_write (geom, buf, geom->length - 2, 1) &
-+ ped_geometry_write (geom, buf, geom->length - 1, 1);
-+}
-+
-+static int
-+hfsplus_clobber (PedGeometry* geom)
-+{
-+ unsigned int i = 1;
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ HfsMasterDirectoryBlock *mdb;
-+
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1))
-+ return 0;
-+
-+
-+ if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE) {
-+ /* embedded hfs+ */
-+ PedGeometry *embedded;
-+
-+ i = (PED_BE32_TO_CPU(mdb->block_size) / PED_SECTOR_SIZE);
-+ embedded = ped_geometry_new (
-+ geom->dev,
-+ (PedSector) geom->start
-+ + PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) PED_BE16_TO_CPU (
-+ mdb->old_new.embedded.location.start_block ) * i,
-+ (PedSector) PED_BE16_TO_CPU (
-+ mdb->old_new.embedded.location.block_count ) * i );
-+ i = hfs_clobber (embedded);
-+ ped_geometry_destroy (embedded);
-+ }
-+
-+ /* non-embedded or envelop destroy as hfs */
-+ return ( hfs_clobber (geom) && i );
-+}
-+
-+/* Open the data fork of a file with its first three extents and its CNID */
-+static HfsPrivateFile*
-+hfs_file_open (PedFileSystem *fs, uint32_t CNID,
-+ HfsExtDataRec ext_desc, PedSector sect_nb)
-+{
-+ HfsPrivateFile* file;
-+
-+ file = (HfsPrivateFile*) ped_malloc (sizeof (HfsPrivateFile));
-+
-+ file->fs = fs;
-+ file->sect_nb = sect_nb;
-+ file->CNID = CNID;
-+ memcpy(file->first, ext_desc, sizeof (HfsExtDataRec));
-+ memcpy(file->cache, ext_desc, sizeof (HfsExtDataRec));
-+ file->start_cache = 0;
-+
-+ return file;
-+}
-+
-+/* Close an HFS file */
-+static void
-+hfs_file_close (HfsPrivateFile* file)
-+{
-+ ped_free (file);
-+}
-+
-+/* do a B-Tree lookup */
-+/* read the first record immediatly inferior or egal to the given key */
-+/* return 0 on error */
-+/* record_out _must_ be large enough to receive record_size bytes */
-+static int
-+hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
-+ void *record_out, unsigned int record_size,
-+ HfsCPrivateLeafRec* record_ref)
-+{
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsPrivateGenericKey* record_key = NULL;
-+ unsigned int node_number, record_number;
-+ int i;
-+
-+ /* Read the header node */
-+ if (!hfs_file_read_sector(b_tree_file, node, 0))
-+ return 0;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+
-+ /* Get the node number of the root */
-+ node_number = PED_BE32_TO_CPU(header->root_node);
-+
-+ /* Read the root node */
-+ if (!hfs_file_read_sector(b_tree_file, node, node_number))
-+ return 0;
-+
-+ /* Follow the white rabbit */
-+ while (1) {
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = record_number; i; i--) {
-+ int cmp, min_length;
-+
-+ record_key = (HfsPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*i)))));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)record_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)record_key - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return 0;
-+ min_length = ( (key->key_length
-+ > record_key->key_length) ?
-+ (record_key->key_length) :
-+ (key->key_length) );
-+ cmp = memcmp (record_key->key_content,
-+ key->key_content, min_length);
-+ if (cmp < 0 || ( cmp == 0 && record_key->key_length
-+ <= key->key_length))
-+ break;
-+ }
-+ if (!i) return 0;
-+ if (desc->type == HFS_IDX_NODE) {
-+ unsigned int skip;
-+
-+ skip = (1 + record_key->key_length + 1) & ~1;
-+ node_number = PED_BE32_TO_CPU (*((uint32_t *)
-+ (((uint8_t *) record_key) + skip)));
-+ if (!hfs_file_read_sector(b_tree_file, node,
-+ node_number))
-+ return 0;
-+ } else
-+ break;
-+ }
-+
-+ /* copy the result if needed */
-+ if (record_size)
-+ memcpy (record_out, record_key, record_size);
-+
-+ /* send record reference if needed */
-+ if (record_ref) {
-+ record_ref->node_size = 1; /* in sectors */
-+ record_ref->node_number = node_number;
-+ record_ref->record_pos = (uint8_t*)record_key - node;
-+ record_ref->record_number = i;
-+ }
-+
-+ /* success */
-+ return 1;
-+}
-+
-+static int
-+hfs_get_extent_containing (HfsPrivateFile* file, unsigned int block,
-+ HfsExtDataRec cache, uint16_t* ptr_start_cache)
-+{
-+ uint8_t record[sizeof (HfsExtentKey)
-+ + sizeof (HfsExtDataRec)];
-+ HfsExtentKey search;
-+ HfsExtentKey* ret_key = (HfsExtentKey*) record;
-+ HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
-+ (record + sizeof (HfsExtentKey));
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ file->fs->type_specific;
-+
-+
-+ search.key_length = sizeof (HfsExtentKey) - 1;
-+ search.type = HFS_DATA_FORK;
-+ search.file_ID = file->CNID;
-+ search.start = PED_CPU_TO_BE16 (block);
-+
-+ if (!hfs_btree_search (priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL))
-+ return 0;
-+
-+ if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
-+ return 0;
-+
-+ memcpy (cache, ret_cache, sizeof(HfsExtDataRec));
-+ *ptr_start_cache = PED_BE16_TO_CPU (ret_key->start);
-+
-+ return 1;
-+}
-+
-+/* find and return the nth sector of a file */
-+/* return 0 on error */
-+static PedSector
-+hfs_file_find_sector (HfsPrivateFile* file, PedSector sector)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ file->fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ unsigned int i, s, vol_block;
-+ unsigned int block = sector
-+ / (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ unsigned int offset = sector
-+ % (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+
-+ /* in the three first extent */
-+ for (s = 0, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->first[i].block_count)) {
-+ if ((block >= s) && ( block < s + PED_BE16_TO_CPU (
-+ file->first[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->first[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE16_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->cache[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ /* update cache */
-+ if (!hfs_get_extent_containing (file, block, file->cache,
-+ &(file->start_cache)))
-+ return 0;
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE16_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->cache[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ return 0;
-+
-+ sector_found:
-+ return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) vol_block * (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE)
-+ + offset;
-+}
-+
-+/* Read the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-+{
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfs_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_read (file->fs->geom, buf,
-+ abs_sector, 1);
-+}
-+
-+/* Write the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfs_file_write_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-+{
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfs_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_write (file->fs->geom, buf,
-+ abs_sector, 1);
-+}
-+
-+/* This function reads bad blocks extents in the extents file
-+ and store it in f.s. specific data of fs */
-+static int
-+hfs_read_bad_blocks (const PedFileSystem *fs)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (!priv_data->bad_blocks_loaded) {
-+ uint8_t record[sizeof (HfsExtentKey)
-+ + sizeof (HfsExtDataRec)];
-+ HfsExtentKey search;
-+ HfsExtentKey* ret_key = (HfsExtentKey*) record;
-+ HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
-+ (record
-+ + sizeof (HfsExtentKey));
-+ unsigned int block, last_start, first_pass = 1;
-+
-+ search.key_length = sizeof (HfsExtentKey) - 1;
-+ search.type = HFS_DATA_FORK;
-+ search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+
-+ last_start = -1; block = 0;
-+ while (1) {
-+ int i;
-+
-+ search.start = PED_CPU_TO_BE16 (block);
-+ if (!hfs_btree_search (priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL)) {
-+ if (first_pass)
-+ break;
-+ else
-+ return 0;
-+ }
-+ if (ret_key->file_ID != search.file_ID
-+ || ret_key->type != search.type)
-+ break;
-+ if (PED_BE16_TO_CPU (ret_key->start) == last_start)
-+ break;
-+
-+ last_start = PED_BE16_TO_CPU (ret_key->start);
-+ for (i = 0; i < HFS_EXT_NB; i++) {
-+ if (ret_cache[i].block_count) {
-+ HfsPrivateLinkExtent* new_xt =
-+ (HfsPrivateLinkExtent*) ped_malloc (
-+ sizeof (HfsPrivateLinkExtent));
-+ new_xt->next =
-+ priv_data->bad_blocks_xtent_list;
-+ memcpy(&(new_xt->extent), ret_cache+i,
-+ sizeof (HfsExtDescriptor));
-+ priv_data->bad_blocks_xtent_list =
-+ new_xt;
-+ priv_data->bad_blocks_xtent_nb++;
-+ block += PED_BE16_TO_CPU (
-+ ret_cache[i].block_count);
-+ }
-+ }
-+ first_pass = 0;
-+ }
-+
-+ priv_data->bad_blocks_loaded = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+/* free the bad blocks linked list */
-+static void
-+hfs_free_bad_blocks_list(HfsPrivateLinkExtent* first)
-+{
-+ HfsPrivateLinkExtent* next;
-+
-+ while (first) {
-+ next = first->next;
-+ ped_free (first);
-+ first = next;
-+ }
-+}
-+
-+/* This function check if fblock is a bad block */
-+static int
-+hfs_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsPrivateLinkExtent* walk;
-+
-+ for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
-+ /* Won't compile without the strange cast ! gcc bug ? */
-+ /* or maybe C subtilties... */
-+ if ((fblock >= PED_BE16_TO_CPU (walk->extent.start_block)) &&
-+ (fblock < (unsigned int) (PED_BE16_TO_CPU (
-+ walk->extent.start_block)
-+ + PED_BE16_TO_CPU (
-+ walk->extent.block_count))))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves data of size blocks starting
-+ at block *ptr_fblock to block *ptr_to_fblock */
-+/* return new start or -1 on failure */
-+static int
-+hfs_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock, unsigned int size)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t* block;
-+ unsigned int i;
-+ unsigned int new_start;
-+
-+ /* try to find enough room to fit the extent */
-+ for (i = *ptr_to_fblock;
-+ i < *ptr_to_fblock + size && i < *ptr_fblock;
-+ i++) {
-+ if (hfs_is_bad_block (fs, i))
-+ *ptr_to_fblock = i+1;
-+ }
-+
-+ if (*ptr_to_fblock < *ptr_fblock) {
-+ /* enough room */
-+ block = (uint8_t*) ped_malloc(PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size));
-+
-+ new_start = *ptr_to_fblock;
-+
-+ /* move blocks one by one */
-+ for (i = 0; i < size; i++) {
-+ PedSector abs_sector;
-+ unsigned int bit, byte;
-+ unsigned int to_bit, to_byte;
-+
-+ abs_sector = (PedSector) PED_BE16_TO_CPU (
-+ priv_data->mdb->start_block)
-+ + (PedSector) (*ptr_fblock + i)
-+ * (PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ if (!ped_geometry_read (fs->geom, block, abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ abs_sector = (PedSector) PED_BE16_TO_CPU (
-+ priv_data->mdb->start_block)
-+ + (PedSector) (*ptr_to_fblock + i)
-+ * (PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ if (!ped_geometry_write (fs->geom, block, abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ bit = 7 - ((*ptr_fblock + i) & 7);
-+ byte = (*ptr_fblock + i) / 8;
-+
-+ to_bit = 7 - ((*ptr_to_fblock + i) & 7);
-+ to_byte = (*ptr_to_fblock + i) / 8;
-+
-+ /* free source block */
-+ priv_data->alloc_map[byte] &= ~(1 << bit);
-+
-+ /* set dest block */
-+ priv_data->alloc_map[to_byte] |= (1 << to_bit);
-+ }
-+
-+ /* save the allocation map */
-+ if (!ped_geometry_write(fs->geom, priv_data->alloc_map,
-+ PED_BE16_TO_CPU (
-+ priv_data->mdb->volume_bitmap_block),
-+ ( PED_BE16_TO_CPU (
-+ priv_data->mdb->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1)
-+ / (PED_SECTOR_SIZE * 8)))
-+ return -1;
-+
-+ ped_free (block);
-+
-+ *ptr_fblock += size;
-+ *ptr_to_fblock += size;
-+ } else {
-+ /* not enough room */
-+ new_start = *ptr_fblock;
-+ *ptr_fblock = *ptr_to_fblock = new_start + size;
-+ }
-+
-+ return new_start;
-+}
-+
-+/* Search an extent in the catalog file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_catalog (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsCatalogKey* catalog_key;
-+ HfsCatalog* catalog_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j;
-+ int new_start;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfs_file_read_sector (priv_data->catalog_file, node, 0))
-+ return -1;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfs_file_read_sector (priv_data->catalog_file, node,
-+ leaf_node))
-+ return -1;
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ /* fucking undocumented alignement powered by apple :p */
-+ unsigned int skip;
-+ catalog_key = (HfsCatalogKey*) (node + PED_BE16_TO_CPU(
-+ *((uint16_t *)(node+(PED_SECTOR_SIZE - 2*i)))));
-+ skip = (1 + catalog_key->key_length + 1) & ~1;
-+ catalog_data = (HfsCatalog*)(((uint8_t*)catalog_key)
-+ + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)catalog_data - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return -1;
-+ if (catalog_data->type != HFS_CAT_FILE) continue;
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (catalog_data
-+ ->sel.file.extents_data[j].block_count
-+ && PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_data[j].start_block)
-+ == (*ptr_fblock))
-+ goto catalog_data_found;
-+ if (catalog_data
-+ ->sel.file.extents_res[j].block_count
-+ && PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_res[j].start_block)
-+ == (*ptr_fblock))
-+ goto catalog_res_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ return 0;
-+
-+
-+ /* an extent part of a data fork has been found in the catalog file */
-+ catalog_data_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = catalog_data->sel.file.extents_data[j].start_block;
-+ catalog_data->sel.file.extents_data[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ /* write if any changes */
-+ if ((old_start != PED_CPU_TO_BE16 (new_start))
-+ && !hfs_file_write_sector (priv_data->catalog_file,
-+ node, leaf_node))
-+ return -1;
-+ return 1;
-+ } else
-+ return -1;
-+
-+ /* an extent part of a resource fork has been found in the catalog file */
-+ catalog_res_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_res[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = catalog_data->sel.file.extents_res[j].start_block;
-+ catalog_data->sel.file.extents_res[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ /* write if any changes */
-+ if ((old_start != PED_CPU_TO_BE16 (new_start))
-+ && !hfs_file_write_sector (priv_data->catalog_file,
-+ node, leaf_node))
-+ return -1;
-+ return 1;
-+ } else
-+ return -1;
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsExtentKey* extent_key;
-+ HfsExtDescriptor* extent_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j;
-+ int new_start;
-+
-+ /* Search the extent in the extent file */
-+ if (!hfs_file_read_sector (priv_data->extent_file, node, 0))
-+ return -1;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfs_file_read_sector (priv_data->extent_file, node,
-+ leaf_node))
-+ return -1;
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ extent_key = (HfsExtentKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*i)))));
-+ extent_data = (HfsExtDescriptor*)(((uint8_t*)extent_key)
-+ + sizeof (HfsExtentKey));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)extent_data - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return -1;
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (extent_data[j].block_count
-+ && PED_BE16_TO_CPU (
-+ extent_data[j].start_block)
-+ == (*ptr_fblock))
-+ goto extent_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the extents file */
-+ return 0;
-+
-+ /* an extent has been found in the extents file */
-+ extent_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (extent_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = extent_data[j].start_block;
-+ extent_data[j].start_block = PED_CPU_TO_BE16 (new_start);
-+ /* This extent might have been cached into the file structure
-+ of the extent or catalog file */
-+ if (priv_data->catalog_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->catalog_file->cache, extent_data,
-+ sizeof (HfsExtDataRec));
-+ if (priv_data->extent_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->extent_file->cache, extent_data,
-+ sizeof (HfsExtDataRec));
-+ /* write if any changes */
-+ if ((old_start != PED_CPU_TO_BE16 (new_start))
-+ && !hfs_file_write_sector (priv_data->extent_file, node,
-+ leaf_node))
-+ return -1;
-+ return 1;
-+ } else
-+ return -1;
-+}
-
-- if (geom->length < 2)
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_primary (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ unsigned int j;
-+ int new_start;
-+
-+ /* Search an extent in the MDB */
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (priv_data->mdb->extents_file_rec[j].block_count
-+ && PED_BE16_TO_CPU (priv_data->mdb->extents_file_rec[j]
-+ .start_block)
-+ == (*ptr_fblock))
-+ goto ext_file_found;
-+ if (priv_data->mdb->catalog_file_rec[j].block_count
-+ && PED_BE16_TO_CPU (priv_data->mdb->catalog_file_rec[j]
-+ .start_block)
-+ == (*ptr_fblock))
-+ goto cat_file_found;
-+ }
-+ return 0;
-+
-+ ext_file_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (priv_data->mdb
-+ ->extents_file_rec[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ priv_data->mdb->extents_file_rec[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ memcpy (priv_data->extent_file->first,
-+ priv_data->mdb->extents_file_rec,
-+ sizeof (HfsExtDataRec));
-+ if (!priv_data->extent_file->start_cache)
-+ memcpy (priv_data->extent_file->cache,
-+ priv_data->extent_file->first,
-+ sizeof (HfsExtDataRec));
-+ goto update_mdb;
-+ } else
-+ return -1;
-+
-+
-+ cat_file_found:
-+ new_start = hfs_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (priv_data->mdb
-+ ->catalog_file_rec[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ priv_data->mdb->catalog_file_rec[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ memcpy (priv_data->catalog_file->first,
-+ priv_data->mdb->catalog_file_rec,
-+ sizeof (HfsExtDataRec));
-+ if (!priv_data->catalog_file->start_cache)
-+ memcpy (priv_data->catalog_file->cache,
-+ priv_data->catalog_file->first,
-+ sizeof (HfsExtDataRec));
-+ goto update_mdb;
-+ } else
-+ return -1;
-+
-+ update_mdb:
-+ if (!ped_geometry_read (fs->geom, node, 2, 1))
-+ return -1;
-+ memcpy (node, priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, node, 2, 1))
-+ return -1;
-+ if (!ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1))
-+ return -1;
-+ return 1;
-+}
-+
-+/* This function moves an extent starting at block fblock to block to_fblock
-+ if there's enough room */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ int ret;
-+
-+ /* order = decreasing probability to be found */
-+ if ((ret = hfs_search_move_catalog (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfs_search_move_extent (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfs_search_move_primary (fs, ptr_fblock, ptr_to_fblock))) {
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves file's data to compact used and free space,
-+ starting at fblock block */
-+/* return 0 on error */
-+static int
-+hfs_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
-+ PedTimer* timer)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ unsigned int to_fblock = fblock;
-+ unsigned int start = fblock;
-+ unsigned int div = PED_BE16_TO_CPU (mdb->total_blocks)
-+ + 1 - start;
-+ int byte, bit, ret;
-+ int to_byte, to_bit;
-+
-+ to_byte = byte = fblock / 8;
-+ to_bit = bit = 7 - (fblock & 7);
-+
-+ if (!hfs_read_bad_blocks (fs))
-+ return 0;
-+
-+ while (fblock < PED_BE16_TO_CPU (mdb->total_blocks)) {
-+ if (((priv_data->alloc_map[byte] >> bit) & 1)
-+ && (!hfs_is_bad_block (fs, fblock))) {
-+ if (!(ret = hfs_move_extent_starting_at (fs, &fblock,
-+ &to_fblock)))
-+ to_fblock = ++fblock;
-+ else if (ret == -1)
-+ return 0;
-+ } else {
-+ fblock++;
-+ }
-+
-+ byte = fblock / 8;
-+ bit = 7 - (fblock & 7);
-+
-+ to_byte = to_fblock / 8;
-+ to_bit = 7 - (to_fblock & 7);
-+
-+ ped_timer_update(timer, (float)(fblock - start)/div);
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function returns the first sector of the last free block of an
-+ HFS volume we can get after a hfs_pack_free_space_from_block call */
-+static PedSector
-+hfs_get_empty_end (const PedFileSystem *fs)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ HfsPrivateLinkExtent* link;
-+ unsigned int block, last_bad, end_free_blocks;
-+ int byte, bit;
-+
-+ /* find the next block to the last bad block of the volume */
-+ if (!hfs_read_bad_blocks (fs))
- return 0;
-+
-+ last_bad = 0;
-+ for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
-+ if ((unsigned int) PED_BE16_TO_CPU (link->extent.start_block)
-+ + PED_BE16_TO_CPU (link->extent.block_count) > last_bad)
-+ last_bad = PED_BE16_TO_CPU (link->extent.start_block)
-+ + PED_BE16_TO_CPU (link->extent.block_count);
-+ }
-+
-+ /* Count the free blocks from last_bad to the end of the volume */
-+ end_free_blocks = 0;
-+ for (block = last_bad;
-+ block < PED_BE16_TO_CPU (mdb->total_blocks);
-+ block++) {
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if (!((priv_data->alloc_map[byte]>>bit)&1))
-+ end_free_blocks++;
-+ }
-+
-+ /* Calculate the block that will by the first free at the
-+ end of the volume */
-+ block = PED_BE16_TO_CPU (mdb->total_blocks) - end_free_blocks;
-+
-+ return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) block * (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+}
-+
-+/* return the block which should be used to pack data to have at
-+ least free fblock blocks at the end of the volume */
-+static unsigned int
-+hfs_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ unsigned int block;
-+
-+ for (block = PED_BE16_TO_CPU (priv_data->mdb->total_blocks) - 1;
-+ block && fblock;
-+ block--) {
-+ if (!((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ fblock--;
-+ }
-+
-+ while (block && !((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ block--;
-+ if ((priv_data->alloc_map[block / 8] >> (7 - (block & 7))) & 1)
-+ block++;
-+
-+ return block;
-+}
-+
-+static PedFileSystem*
-+hfs_open (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ PedFileSystem* fs;
-+ HfsMasterDirectoryBlock* mdb;
-+ HfsPrivateFSData* priv_data;
-+
-+ /* Read MDB */
- if (!ped_geometry_read (geom, buf, 2, 1))
-+ return NULL;
-+
-+ /* Allocate memory */
-+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
-+ mdb = (HfsMasterDirectoryBlock*) ped_malloc (
-+ sizeof (HfsMasterDirectoryBlock));
-+ priv_data = (HfsPrivateFSData*) ped_malloc (
-+ sizeof (HfsPrivateFSData));
-+
-+ memcpy (mdb, buf, sizeof (HfsMasterDirectoryBlock));
-+
-+ /* init structures */
-+ priv_data->mdb = mdb;
-+ priv_data->bad_blocks_loaded = 0;
-+ priv_data->bad_blocks_xtent_nb = 0;
-+ priv_data->bad_blocks_xtent_list = NULL;
-+ priv_data->extent_file =
-+ hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
-+ mdb->extents_file_rec,
-+ PED_CPU_TO_BE32 (mdb->extents_file_size)
-+ / PED_SECTOR_SIZE);
-+ priv_data->catalog_file =
-+ hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
-+ mdb->catalog_file_rec,
-+ PED_CPU_TO_BE32 (mdb->catalog_file_size)
-+ / PED_SECTOR_SIZE);
-+
-+ /* Read allocation blocks */
-+ if (!ped_geometry_read(geom, priv_data->alloc_map,
-+ PED_BE16_TO_CPU (mdb->volume_bitmap_block),
-+ ( PED_BE16_TO_CPU (mdb->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 )
-+ / (PED_SECTOR_SIZE * 8) ) ) {
-+ hfs_file_close (priv_data->extent_file);
-+ hfs_file_close (priv_data->catalog_file);
-+ ped_free(fs); ped_free(mdb); ped_free(priv_data);
-+ return NULL;
-+ }
-+
-+ fs->type = &hfs_type;
-+ fs->geom = ped_geometry_duplicate (geom);
-+ fs->type_specific = (void*) priv_data;
-+ fs->checked = ( PED_BE16_TO_CPU (mdb->volume_attributes)
-+ >> HFS_UNMOUNTED ) & 1;
-+
-+ return fs;
-+}
-+
-+static int
-+hfs_close (PedFileSystem *fs)
-+{
-+ hfs_file_close (((HfsPrivateFSData*)(fs->type_specific))->extent_file);
-+ hfs_file_close (((HfsPrivateFSData*)(fs->type_specific))->catalog_file);
-+ if (((HfsPrivateFSData*)(fs->type_specific))->bad_blocks_loaded)
-+ hfs_free_bad_blocks_list (
-+ ((HfsPrivateFSData*)(fs->type_specific))
-+ ->bad_blocks_xtent_list);
-+ ped_free (((HfsPrivateFSData*)(fs->type_specific))->mdb);
-+ ped_free (fs->type_specific);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+
-+ return 1;
-+}
-+
-+static PedConstraint*
-+hfs_get_resize_constraint (const PedFileSystem *fs)
-+{
-+ PedDevice* dev = fs->geom->dev;
-+ PedAlignment start_align;
-+ PedGeometry start_sector;
-+ PedGeometry full_dev;
-+ PedSector min_size;
-+
-+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
-+ return NULL;
-+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
-+ return NULL;
-+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
-+ return NULL;
-+ /* 2 = last two sectors (alternate MDB and unused sector) */
-+ min_size = hfs_get_empty_end(fs) + 2;
-+
-+ return ped_constraint_new (&start_align, ped_alignment_any,
-+ &start_sector, &full_dev, min_size,
-+ fs->geom->length);
-+}
-+
-+static int
-+hfs_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ unsigned int nblock, nfree;
-+ unsigned int block;
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ int resize = 1;
-+ unsigned int hfs_sect_block = ( PED_BE32_TO_CPU (
-+ mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+
-+
-+ /* check preconditions */
-+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
-+
-+ if (fs->geom->start != geom->start)
-+ {
-+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
-+ PED_EXCEPTION_CANCEL,
-+ _("Sorry, can't move the start of hfs partitions yet!"));
-+ return 0;
-+ }
-+
-+ if (geom->length > fs->geom->length
-+ || geom->length < hfs_get_empty_end(fs) + 2)
-+ return 0;
-+
-+ /* Clear the unmounted bit */
-+ mdb->volume_attributes &= PED_CPU_TO_BE16 (~( 1 << HFS_UNMOUNTED ));
-+ if (!ped_geometry_read (fs->geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, buf, 2, 1))
-+ return 0;
-+
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name(timer, _("shrinking"));
-+ ped_timer_update(timer, 0.0);
-+ /* relocate data */
-+ block = hfs_find_start_pack (fs, ( fs->geom->length - geom->length
-+ + hfs_sect_block - 1 )
-+ / hfs_sect_block );
-+ if (!hfs_pack_free_space_from_block (fs, block, timer)) {
-+ resize = 0;
-+ goto write_MDB;
-+ }
-+
-+ /* Calculate new block number and other MDB field */
-+ nblock = ( geom->length - (PED_BE16_TO_CPU (mdb->start_block) + 2) )
-+ / hfs_sect_block;
-+ nfree = PED_BE16_TO_CPU (mdb->free_blocks)
-+ - ( PED_BE16_TO_CPU (mdb->total_blocks) - nblock );
-+
-+ /* Check that all block after future end are really free */
-+ for (block = nblock;
-+ block < PED_BE16_TO_CPU (mdb->total_blocks);
-+ block++) {
-+ int byte, bit;
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if ((priv_data->alloc_map[byte]>>bit)&1) {
-+ resize = 0;
-+ goto write_MDB;
-+ }
-+ }
-+
-+ /* Update geometry */
-+ if (resize) {
-+ /* update in fs structure */
-+ if (PED_BE16_TO_CPU (mdb->next_allocation) >= nblock)
-+ mdb->next_allocation = PED_CPU_TO_BE16 (0);
-+ mdb->total_blocks = PED_CPU_TO_BE16 (nblock);
-+ mdb->free_blocks = PED_CPU_TO_BE16 (nfree);
-+ /* update parted structure */
-+ fs->geom->length = geom->length;
-+ fs->geom->end = fs->geom->start + geom->length - 1;
-+ }
-+
-+ /* Set the unmounted bit */
-+ mdb->volume_attributes |= PED_CPU_TO_BE16 ( 1 << HFS_UNMOUNTED );
-+
-+ /* Effective write */
-+ write_MDB:
-+ ped_timer_set_state_name(timer,_("writing HFS Master Directory Block"));
-+ if (!ped_geometry_read (fs->geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, buf, 2, 1))
- return 0;
-+ if (!ped_geometry_write (fs->geom, buf, fs->geom->length - 2, 1))
-+ return 0;
-+ ped_timer_update(timer, 1.0);
-+
-+ return (resize);
-+}
-+
-+/* ----- HFS+ ----- */
-+
-+/* Open the data fork of a file with its first eight extents and its CNID */
-+static HfsPPrivateFile*
-+hfsplus_file_open (PedFileSystem *fs, HfsPNodeID CNID,
-+ HfsPExtDataRec ext_desc, PedSector sect_nb)
-+{
-+ HfsPPrivateFile* file;
-+
-+ file = (HfsPPrivateFile*) ped_malloc (sizeof (HfsPPrivateFile));
-+
-+ file->fs = fs;
-+ file->sect_nb = sect_nb;
-+ file->CNID = CNID;
-+ memcpy(file->first, ext_desc, sizeof (HfsPExtDataRec));
-+ memcpy(file->cache, ext_desc, sizeof (HfsPExtDataRec));
-+ file->start_cache = 0;
-+
-+ return file;
-+}
-
-- if (PED_BE16_TO_CPU (*(uint16_t*) buf) == HFS_SIGNATURE)
-- return ped_geometry_duplicate (geom);
-- else
-+/* Close an HFS+ file */
-+static void
-+hfsplus_file_close (HfsPPrivateFile* file)
-+{
-+ ped_free (file);
-+}
-+
-+/* declaration of hfsplus_file_read(_sector)
-+ because it's used by hfsplus_btree_search (indirect recursion) */
-+static int
-+hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector);
-+static int
-+hfsplus_file_read(HfsPPrivateFile* file, void *buf,
-+ PedSector sector, unsigned int nb);
-+
-+/* do a B-Tree lookup */
-+/* read the first record immediatly inferior or egal to the given key */
-+/* return 0 on error */
-+/* record_out _must_ be large enough to receive the whole record (key + data) */
-+static int
-+hfsplus_btree_search (HfsPPrivateFile* b_tree_file, HfsPPrivateGenericKey* key,
-+ void *record_out, unsigned int record_size,
-+ HfsCPrivateLeafRec* record_ref)
-+{
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPPrivateGenericKey* record_key = NULL;
-+ unsigned int node_number, record_number, size, bsize;
-+ int i;
-+
-+ /* Read the header node */
-+ if (!hfsplus_file_read_sector(b_tree_file, node_1, 0))
-+ return 0;
-+ header = (HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC);
-+
-+ /* Get the node number of the root */
-+ node_number = PED_BE32_TO_CPU (header->root_node);
-+
-+ /* Get the size of a node in sectors and allocate buffer */
-+ size = (bsize = PED_BE16_TO_CPU (header->node_size)) / PED_SECTOR_SIZE;
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ /* Read the root node */
-+ if (!hfsplus_file_read (b_tree_file, node,
-+ (PedSector) node_number * size, size))
-+ return 0;
-+
-+ /* Follow the white rabbit */
-+ while (1) {
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = record_number; i; i--) {
-+ int cmp, min_length;
-+
-+ record_key = (HfsPPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)record_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)record_key - node
-+ >= (signed)bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return 0;
-+ }
-+ min_length = ((PED_BE16_TO_CPU(key->key_length)
-+ >PED_BE16_TO_CPU(record_key->key_length))?
-+ PED_BE16_TO_CPU(record_key->key_length) :
-+ PED_BE16_TO_CPU(key->key_length) );
-+ cmp = memcmp (record_key->key_content, key->key_content,
-+ min_length);
-+ if (cmp < 0 || ( cmp == 0 && PED_BE16_TO_CPU (
-+ record_key->key_length)
-+ <= PED_BE16_TO_CPU (
-+ key->key_length)))
-+ break;
-+ }
-+ if (!i) { ped_free (node); return 0; }
-+ if (desc->type == HFS_IDX_NODE) {
-+ unsigned int skip;
-+
-+ skip = ( 2 + PED_BE16_TO_CPU (record_key->key_length)
-+ + 1 ) & ~1;
-+ node_number = PED_BE32_TO_CPU (*((uint32_t *)
-+ (((uint8_t *) record_key) + skip)));
-+ if (!hfsplus_file_read(b_tree_file, node,
-+ (PedSector) node_number * size,
-+ size)) {
-+ ped_free (node);
-+ return 0;
-+ }
-+ } else
-+ break;
-+ }
-+
-+ /* copy the result if needed */
-+ if (record_size)
-+ memcpy (record_out, record_key, record_size);
-+
-+ /* send record reference if needed */
-+ if (record_ref) {
-+ record_ref->node_size = size; /* in sectors */
-+ record_ref->node_number = node_number;
-+ record_ref->record_pos = (uint8_t*)record_key - node;
-+ record_ref->record_number = i;
-+ }
-+
-+ /* success */
-+ ped_free (node);
-+ return 1;
-+}
-+
-+static int
-+hfsplus_get_extent_containing (HfsPPrivateFile* file, unsigned int block,
-+ HfsPExtDataRec cache, uint32_t* ptr_start_cache)
-+{
-+ uint8_t record[sizeof (HfsPExtentKey)
-+ + sizeof (HfsPExtDataRec)];
-+ HfsPExtentKey search;
-+ HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
-+ HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
-+ (record + sizeof (HfsPExtentKey));
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+
-+
-+ search.key_length = PED_CPU_TO_BE16 (sizeof (HfsPExtentKey) - 2);
-+ search.type = HFS_DATA_FORK;
-+ search.pad = 0;
-+ search.file_ID = file->CNID;
-+ search.start = PED_CPU_TO_BE32 (block);
-+
-+ if (!hfsplus_btree_search (priv_data->extents_file,
-+ (HfsPPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL))
-+ return 0;
-+
-+ if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
-+ return 0;
-+
-+ memcpy (cache, ret_cache, sizeof(HfsPExtDataRec));
-+ *ptr_start_cache = PED_BE32_TO_CPU (ret_key->start);
-+
-+ return 1;
-+}
-+
-+/* find the nth sector of a file */
-+/* return 0 on error */
-+static PedSector
-+hfsplus_file_find_sector (HfsPPrivateFile* file, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data-> vh;
-+ unsigned int i, s, vol_block;
-+ unsigned int block = sector
-+ / ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ unsigned int offset = sector
-+ % ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+
-+ /* in the three first extent */
-+ for (s = 0, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->first[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->first[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->first[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->cache[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ /* update cache */
-+ if (!hfsplus_get_extent_containing (file, block, file->cache,
-+ &(file->start_cache)))
-+ return 0;
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->cache[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ return 0;
-+
-+ plus_sector_found:
-+ return (PedSector) vol_block * ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) + offset;
-+}
-+
-+/* Read the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfsplus_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_read (priv_data->plus_geom, buf,
-+ abs_sector, 1);
-+}
-+
-+static int
-+hfsplus_file_read(HfsPPrivateFile* file, void *buf, PedSector sector,
-+ unsigned int nb)
-+{
-+ while (nb) {
-+ if (!hfsplus_file_read_sector (file, buf, sector))
-+ return 0;
-+
-+ buf += PED_SECTOR_SIZE;
-+ nb--;
-+ sector++;
-+ }
-+
-+ return 1;
-+}
-+
-+/* Write the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfsplus_file_write_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfsplus_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_write (priv_data->plus_geom, buf,
-+ abs_sector, 1);
-+}
-+
-+static int
-+hfsplus_file_write (HfsPPrivateFile* file, void *buf, PedSector sector,
-+ unsigned int nb)
-+{
-+ while (nb) {
-+ if (!hfsplus_file_write_sector (file, buf, sector))
-+ return 0;
-+
-+ buf += PED_SECTOR_SIZE;
-+ nb--;
-+ sector++;
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function reads bad blocks extents in the extents file
-+ and store it in f.s. specific data of fs */
-+static int
-+hfsplus_read_bad_blocks (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (!priv_data->bad_blocks_loaded) {
-+ uint8_t record[sizeof (HfsPExtentKey)
-+ + sizeof (HfsPExtDataRec)];
-+ HfsPExtentKey search;
-+ HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
-+ HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
-+ (record + sizeof (HfsPExtentKey));
-+ int block, first_pass = 1;
-+ unsigned int last_start;
-+
-+ search.key_length = sizeof (HfsExtentKey) - 2;
-+ search.type = HFS_DATA_FORK;
-+ search.pad = 0;
-+ search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+
-+ last_start = -1; block = 0;
-+ while (1) {
-+ int i;
-+
-+ search.start = PED_CPU_TO_BE32 (block);
-+ if (!hfsplus_btree_search (priv_data->extents_file,
-+ (HfsPPrivateGenericKey*)
-+ &search,
-+ record, sizeof (record),
-+ NULL)) {
-+ if (first_pass)
-+ break;
-+ else
-+ return 0;
-+ }
-+ if (ret_key->file_ID != search.file_ID
-+ || ret_key->type != search.type)
-+ break;
-+ if (PED_BE32_TO_CPU (ret_key->start) == last_start)
-+ break;
-+
-+ last_start = PED_BE32_TO_CPU (ret_key->start);
-+ for (i = 0; i < HFSP_EXT_NB; i++) {
-+ if (ret_cache[i].block_count) {
-+ HfsPPrivateLinkExtent* new_xt =
-+ (HfsPPrivateLinkExtent*) ped_malloc (
-+ sizeof (HfsPPrivateLinkExtent));
-+ new_xt->next =
-+ priv_data->bad_blocks_xtent_list;
-+ memcpy (&(new_xt->extent), ret_cache+i,
-+ sizeof (HfsPExtDescriptor));
-+ priv_data->bad_blocks_xtent_list =
-+ new_xt;
-+ priv_data->bad_blocks_xtent_nb++;
-+ block += PED_BE32_TO_CPU (ret_cache[i]
-+ .block_count);
-+ }
-+ }
-+ first_pass = 0;
-+ }
-+
-+ priv_data->bad_blocks_loaded = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+/* free the bad blocks linked list */
-+static void
-+hfsplus_free_bad_blocks_list(HfsPPrivateLinkExtent* first)
-+{
-+ HfsPPrivateLinkExtent* next;
-+
-+ while (first) {
-+ next = first->next;
-+ ped_free (first);
-+ first = next;
-+ }
-+}
-+
-+/* This function check if fblock is a bad block */
-+static int
-+hfsplus_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPPrivateLinkExtent* walk;
-+
-+ for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
-+ /* Won't compile without the strange cast ! gcc bug ? */
-+ /* or maybe C subtilties... */
-+ if ((fblock >= PED_BE32_TO_CPU (walk->extent.start_block)) &&
-+ (fblock < (unsigned int)(PED_BE32_TO_CPU (
-+ walk->extent.start_block)
-+ + PED_BE32_TO_CPU (walk->extent.block_count))))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+hfsplus_close (PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (priv_data->wrapper) hfs_close(priv_data->wrapper);
-+ if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
-+ ped_free(priv_data->alloc_map);
-+ hfsplus_file_close (priv_data->extents_file);
-+ hfsplus_file_close (priv_data->catalog_file);
-+ hfsplus_file_close (priv_data->attributes_file);
-+ if (priv_data->bad_blocks_loaded)
-+ hfsplus_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
-+ ped_free (priv_data->vh);
-+ ped_free (priv_data);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+
-+ return 1;
-+}
-+
-+static PedFileSystem*
-+hfsplus_open (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ PedFileSystem* fs;
-+ HfsPVolumeHeader* vh;
-+ HfsPPrivateFSData* priv_data;
-+ PedGeometry* wrapper_geom;
-+ HfsPPrivateFile* allocation_file;
-+ unsigned int map_sectors;
-+
-+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
-+ vh = (HfsPVolumeHeader*) ped_malloc (sizeof (HfsPVolumeHeader));
-+ priv_data = (HfsPPrivateFSData*)ped_malloc (sizeof (HfsPPrivateFSData));
-+
-+ fs->geom = ped_geometry_duplicate (geom);
-+ fs->type_specific = (void*) priv_data;
-+
-+ if ((wrapper_geom = hfs_and_wrapper_probe (geom))) {
-+ HfsPrivateFSData* hfs_priv_data;
-+ PedSector abs_sect, length;
-+ unsigned int bs;
-+
-+ ped_geometry_destroy (wrapper_geom);
-+ priv_data->wrapper = hfs_open(geom);
-+ hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ bs = PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+ abs_sect = (PedSector) geom->start
-+ + (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->start_block)
-+ + (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.start_block )
-+ * bs;
-+ length = (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count)
-+ * bs;
-+ priv_data->plus_geom = ped_geometry_new (geom->dev, abs_sect,
-+ length);
-+ priv_data->free_geom = 1;
-+ } else {
-+ priv_data->wrapper = NULL;
-+ priv_data->plus_geom = fs->geom;
-+ priv_data->free_geom = 0;
-+ }
-+
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1)) {
-+ if (priv_data->wrapper)
-+ hfs_close(priv_data->wrapper);
-+ if (priv_data->free_geom)
-+ ped_geometry_destroy (priv_data->plus_geom);
-+ ped_free (vh);
-+ ped_free (priv_data);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
- return NULL;
-+ }
-+
-+ memcpy (vh, buf, sizeof (HfsPVolumeHeader));
-+
-+ priv_data->vh = vh;
-+ priv_data->bad_blocks_loaded = 0;
-+ priv_data->bad_blocks_xtent_nb = 0;
-+ priv_data->bad_blocks_xtent_list = NULL;
-+ priv_data->extents_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
-+ vh->extents_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->extents_file.logical_size )
-+ / PED_SECTOR_SIZE);
-+ priv_data->catalog_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
-+ vh->catalog_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->catalog_file.logical_size )
-+ / PED_SECTOR_SIZE);
-+ priv_data->attributes_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ATTRIB_ID),
-+ vh->attributes_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->attributes_file.logical_size)
-+ / PED_SECTOR_SIZE);
-+ map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 ) / (PED_SECTOR_SIZE * 8);
-+ priv_data->alloc_map = (uint8_t*)
-+ ped_malloc (map_sectors * PED_SECTOR_SIZE);
-+
-+ allocation_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
-+ vh->allocation_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->allocation_file.logical_size)
-+ / PED_SECTOR_SIZE);
-+ if (!hfsplus_file_read (allocation_file, priv_data->alloc_map, 0,
-+ map_sectors)) {
-+ hfsplus_file_close (allocation_file);
-+ hfsplus_close(fs);
-+ return NULL;
-+ }
-+ hfsplus_file_close (allocation_file);
-+
-+ fs->type = &hfsplus_type;
-+ fs->checked = ((PED_BE32_TO_CPU (vh->attributes) >> HFS_UNMOUNTED) & 1)
-+ && !((PED_BE32_TO_CPU (vh->attributes) >> HFSP_INCONSISTENT) & 1);
-+
-+ return fs;
- }
-
--#ifndef DISCOVER_ONLY
-+/* This function moves data of size blocks starting at block *ptr_fblock
-+ to block *ptr_to_fblock */
-+/* return new start or -1 on failure */
- static int
--hfs_clobber (PedGeometry* geom)
-+hfsplus_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock, unsigned int size)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t* block;
-+ unsigned int i;
-+ unsigned int new_start;
-+
-+ /* try to find enough room to fit the extent */
-+ for (i = *ptr_to_fblock;
-+ i < *ptr_to_fblock + size && i < *ptr_fblock;
-+ i++) {
-+ if (hfsplus_is_bad_block (fs, i))
-+ *ptr_to_fblock = i+1;
-+ }
-+
-+ if (*ptr_to_fblock < *ptr_fblock) {
-+ /* enough room */
-+ block = (uint8_t*) ped_malloc(PED_BE32_TO_CPU (
-+ priv_data->vh->block_size));
-+
-+ new_start = *ptr_to_fblock;
-+
-+ /* move blocks one by one */
-+ for (i = 0; i < size; i++) {
-+ PedSector abs_sector;
-+ unsigned int bit, byte;
-+ unsigned int to_bit, to_byte;
-+
-+ abs_sector = (PedSector) (*ptr_fblock + i)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ if (!ped_geometry_read (priv_data->plus_geom, block,
-+ abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->block_size )
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ abs_sector = (PedSector) (*ptr_to_fblock + i)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ if (!ped_geometry_write (priv_data->plus_geom, block,
-+ abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->block_size )
-+ / PED_SECTOR_SIZE))
-+ return -1;
-+
-+ bit = 7 - ((*ptr_fblock + i) & 7);
-+ byte = (*ptr_fblock + i) / 8;
-+
-+ to_bit = 7 - ((*ptr_to_fblock + i) & 7);
-+ to_byte = (*ptr_to_fblock + i) / 8;
-+
-+ /* free source block */
-+ priv_data->alloc_map[byte] &= ~(1 << bit);
-+
-+ /* set dest block */
-+ priv_data->alloc_map[to_byte] |= (1 << to_bit);
-+ }
-+
-+/* TODO : a better handling of allocation map saving process */
-+#if 0
-+ /* save the allocation map */
-+ if (!ped_geometry_write(fs->geom, priv_data->alloc_map, PED_BE16_TO_CPU (priv_data->mdb->volume_bitmap_block),
-+ (PED_BE16_TO_CPU (priv_data->mdb->total_blocks) + PED_SECTOR_SIZE * 8 - 1) / (PED_SECTOR_SIZE * 8)))
-+ return -1;
-+#endif
-+
-+ ped_free (block);
-+
-+ *ptr_fblock += size;
-+ *ptr_to_fblock += size;
-+ } else {
-+ /* not enough room */
-+ new_start = *ptr_fblock;
-+ *ptr_fblock = *ptr_to_fblock = new_start + size;
-+ }
-+
-+ return new_start;
-+}
-+
-+/* Search an extent in the catalog file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_catalog (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPCatalogKey* catalog_key;
-+ HfsPCatalog* catalog_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ int new_start;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfsplus_file_read_sector (priv_data->catalog_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ unsigned int skip;
-+ catalog_key = (HfsPCatalogKey*)
-+ ( node + PED_BE16_TO_CPU (*((uint16_t *)
-+ (node+(bsize - 2*i)))) );
-+ skip = ( 2 + PED_BE16_TO_CPU (catalog_key->key_length)
-+ + 1) & ~1;
-+ catalog_data = (HfsPCatalog*)
-+ (((uint8_t*)catalog_key) + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)catalog_data - node
-+ >= (signed) bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ if (PED_BE16_TO_CPU(catalog_data->type)!=HFS_CAT_FILE)
-+ continue;
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( catalog_data->sel.file
-+ .data_fork.extents[j].block_count
-+ && PED_BE32_TO_CPU (catalog_data->sel
-+ .file.data_fork.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_catalog_data_found;
-+ if ( catalog_data->sel.file.res_fork
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (catalog_data->sel
-+ .file.res_fork.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_catalog_res_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ ped_free (node);
-+ return 0;
-+
-+
-+ /* an extent part of a data fork has been found in the catalog file */
-+ plus_catalog_data_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ catalog_data->sel.file
-+ .data_fork.extents[j]
-+ .block_count ));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = catalog_data->sel.file.data_fork
-+ .extents[j].start_block;
-+ catalog_data->sel.file.data_fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+
-+ /* an extent part of a resource fork has been found
-+ in the catalog file */
-+ plus_catalog_res_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ catalog_data->sel.file
-+ .res_fork.extents[j]
-+ .block_count ));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = catalog_data->sel.file.res_fork
-+ .extents[j].start_block;
-+ catalog_data->sel.file.res_fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the attributes file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_attributes (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
- {
-- char buf[512];
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPPrivateGenericKey* generic_key;
-+ HfsPForkDataAttr* fork_ext_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ int new_start;
-+
-+ /* attributes file is facultative */
-+ if (!priv_data->attributes_file->sect_nb)
-+ return 0;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfsplus_file_read_sector (priv_data->attributes_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ unsigned int skip;
-+ generic_key = (HfsPPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ skip = ( 2 + PED_BE16_TO_CPU (generic_key->key_length)
-+ + 1 ) & ~1;
-+ fork_ext_data = (HfsPForkDataAttr*)
-+ (((uint8_t*)generic_key) + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)generic_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)fork_ext_data - node
-+ >= (signed) bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ if ( PED_BE32_TO_CPU (fork_ext_data->record_type )
-+ == HFSP_ATTR_FORK) {
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( fork_ext_data->fork_res.fork
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .fork.extents[j].start_block )
-+ == (*ptr_fblock) )
-+ goto plus_attr_fork_found;
-+ }
-+ } else if ( PED_BE32_TO_CPU (fork_ext_data->record_type)
-+ == HFSP_ATTR_EXTENTS ) {
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( fork_ext_data->fork_res
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_attr_ext_found;
-+ }
-+ } else continue;
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ ped_free (node);
-+ return 0;
-
-- memset (buf, 0, 512);
-- return ped_geometry_write (geom, buf, 2, 1);
-+
-+ /* an extent part of a attr fork has been found in the catalog file */
-+ plus_attr_fork_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .fork.extents[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = fork_ext_data->fork_res.fork.extents[j].start_block;
-+ fork_ext_data->fork_res.fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+
-+ /* an extent part of a attr ext has been found in the catalog file */
-+ plus_attr_ext_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = fork_ext_data->fork_res.extents[j].start_block;
-+ fork_ext_data->fork_res.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node;
-+ HfsPExtentKey* extent_key;
-+ HfsPExtDescriptor* extent_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ int new_start;
-+
-+ /* Search the extent in the extent file */
-+ if (!hfsplus_file_read_sector (priv_data->extents_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->extents_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ extent_key = (HfsPExtentKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ extent_data = (HfsPExtDescriptor*)
-+ (((uint8_t*)extent_key) + sizeof (HfsPExtentKey));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)extent_data - node
-+ >= (signed)bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( extent_data[j].block_count
-+ && PED_BE32_TO_CPU (
-+ extent_data[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_extent_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the extents file */
-+ ped_free (node);
-+ return 0;
-+
-+ /* an extent has been found in the extents file */
-+ plus_extent_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ extent_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = extent_data[j].start_block;
-+ extent_data[j].start_block = PED_CPU_TO_BE32 (new_start);
-+ /* This extent might have been cached into the file structure
-+ of the extent or catalog file */
-+ if (priv_data->catalog_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->catalog_file->cache, extent_data,
-+ sizeof (HfsPExtDataRec));
-+ if (priv_data->extents_file->cache[j].start_block == old_start)
-+ memcpy (priv_data->extents_file->cache, extent_data,
-+ sizeof (HfsPExtDataRec));
-+ if (priv_data->attributes_file->cache[j].start_block
-+ == old_start)
-+ memcpy (priv_data->attributes_file->cache,
-+ extent_data, sizeof (HfsPExtDataRec));
-+ /* write if any changes */
-+ if ((old_start != (unsigned) PED_CPU_TO_BE32 (new_start))
-+ && !hfsplus_file_write (priv_data->extents_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_primary (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ unsigned int j;
-+ int new_start;
-+
-+ /* Search an extent in the MDB */
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( priv_data->vh->extents_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->extents_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_ext_file_found;
-+ if ( priv_data->vh->catalog_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->catalog_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_cat_file_found;
-+ if ( priv_data->vh->allocation_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->allocation_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_alloc_file_found;
-+ if ( priv_data->vh->attributes_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->attributes_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_attrib_file_found;
-+ if ( priv_data->vh->startup_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->startup_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_start_file_found;
-+ }
-+ return 0;
-+
-+ plus_start_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->startup_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->startup_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+#if 0
-+ memcpy (priv_data->startup_file->first, priv_data->vh->startup_file.extents, sizeof (HfsPExtDataRec));
-+ if (!priv_data->startup_file->start_cache)
-+ memcpy (priv_data->startup_file->cache, priv_data->startup_file->first, sizeof (HfsPExtDataRec));
-+#endif
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_attrib_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh
-+ ->attributes_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->attributes_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->attributes_file->first,
-+ priv_data->vh->attributes_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->attributes_file->start_cache)
-+ memcpy (priv_data->attributes_file->cache,
-+ priv_data->attributes_file->first,
-+ sizeof (HfsPExtDataRec));
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_alloc_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh
-+ ->allocation_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->allocation_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+#if 0
-+ memcpy (priv_data->allocation_file->first, priv_data->vh->allocation_file.extents, sizeof (HfsPExtDataRec));
-+ if (!priv_data->allocation_file->start_cache)
-+ memcpy (priv_data->allocation_file->cache, priv_data->allocation_file->first, sizeof (HfsPExtDataRec));
-+#endif
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_ext_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->extents_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->extents_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->extents_file->first,
-+ priv_data->vh->extents_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->extents_file->start_cache)
-+ memcpy (priv_data->extents_file->cache,
-+ priv_data->extents_file->first,
-+ sizeof (HfsPExtDataRec));
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_cat_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->catalog_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ priv_data->vh->catalog_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->catalog_file->first,
-+ priv_data->vh->catalog_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->catalog_file->start_cache)
-+ memcpy (priv_data->catalog_file->cache,
-+ priv_data->catalog_file->first,
-+ sizeof (HfsPExtDataRec));
-+ goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_update_vh:
-+ if (!ped_geometry_read (priv_data->plus_geom, node, 2, 1))
-+ return -1;
-+ memcpy (node, priv_data->vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, node, 2, 1))
-+ return -1;
-+ if (!ped_geometry_write (priv_data->plus_geom, node,
-+ priv_data->plus_geom->length - 2, 1))
-+ return -1;
-+ return 1;
-+}
-+
-+/* This function moves an extent starting at block fblock
-+ to block to_fblock if there's enough room */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ int ret;
-+
-+ /* order = decreasing probability to be found */
-+ if ((ret = hfsplus_search_move_catalog (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfsplus_search_move_extent (fs, ptr_fblock,
-+ ptr_to_fblock))
-+ || (ret = hfsplus_search_move_primary (fs, ptr_fblock,
-+ ptr_to_fblock))
-+ || (ret = hfsplus_search_move_attributes (fs, ptr_fblock,
-+ ptr_to_fblock))) {
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves file's data to compact used and free space,
-+ starting at fblock block */
-+/* return 0 on error */
-+static int
-+hfsplus_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
-+ PedTimer* timer)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ unsigned int to_fblock = fblock;
-+ int byte, bit, ret;
-+ int to_byte, to_bit;
-+ unsigned int start = fblock;
-+ unsigned int div = PED_BE32_TO_CPU (vh->total_blocks)
-+ + 1 - start;
-+
-+ to_byte = byte = fblock / 8;
-+ to_bit = bit = 7 - (fblock & 7);
-+
-+ if (!hfsplus_read_bad_blocks (fs))
-+ return 0;
-+
-+ while ( fblock < ( priv_data->plus_geom->length - 2 )
-+ / ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) ) {
-+ if (((priv_data->alloc_map[byte] >> bit) & 1)
-+ && (!hfsplus_is_bad_block (fs, fblock))) {
-+ if (!(ret = hfsplus_move_extent_starting_at (fs,
-+ &fblock,
-+ &to_fblock)))
-+ to_fblock = ++fblock;
-+ else if (ret == -1)
-+ return 0;
-+ } else {
-+ fblock++;
-+ }
-+
-+ byte = fblock / 8;
-+ bit = 7 - (fblock & 7);
-+
-+ to_byte = to_fblock / 8;
-+ to_bit = 7 - (to_fblock & 7);
-+
-+ ped_timer_update(timer, (float)(fblock - start) / div);
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function returns the first sector of the last free block of
-+ an HFS+ volume we can get after a hfsplus_pack_free_space_from_block call */
-+static PedSector
-+hfsplus_get_empty_end (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ HfsPPrivateLinkExtent* link;
-+ unsigned int block, last_bad, end_free_blocks;
-+ int byte, bit;
-+
-+ /* find the next block to the last bad block of the volume */
-+ if (!hfsplus_read_bad_blocks (fs))
-+ return 0;
-+
-+ last_bad = 0;
-+ for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
-+ if ((unsigned int) PED_BE32_TO_CPU (link->extent.start_block)
-+ + PED_BE32_TO_CPU (link->extent.block_count) > last_bad)
-+ last_bad = PED_BE32_TO_CPU (link->extent.start_block)
-+ + PED_BE32_TO_CPU (link->extent.block_count);
-+ }
-+
-+ /* Count the free blocks from last_bad to the end of the volume */
-+ end_free_blocks = 0;
-+ for (block = last_bad;
-+ block < PED_BE32_TO_CPU (vh->total_blocks);
-+ block++) {
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if (!((priv_data->alloc_map[byte]>>bit)&1))
-+ end_free_blocks++;
-+ }
-+
-+ /* Calculate the block that will by the first free at
-+ the end of the volume */
-+ block = PED_BE32_TO_CPU (vh->total_blocks) - end_free_blocks;
-+
-+ return (PedSector) block * ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+}
-+
-+static PedSector
-+hfsplus_get_min_size (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedSector min_size;
-+
-+ /* don't need to add anything because every sector
-+ is part of allocation blocks in HFS+ */
-+ min_size = hfsplus_get_empty_end(fs);
-+
-+ if (priv_data->wrapper) {
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block;
-+ hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+ /*
-+ * if hfs+ is embedded in an hfs wrapper then the new size is :
-+ * the new size of the hfs+ volume rounded up to the size
-+ * of hfs blocks
-+ * + the minimum size of the hfs wrapper without any hfs+
-+ * modification
-+ * - the current size of the hfs+ volume in the hfs wrapper
-+ */
-+ min_size = ((min_size + hfs_sect_block - 1) / hfs_sect_block)
-+ * hfs_sect_block
-+ + hfs_get_empty_end(priv_data->wrapper) + 2
-+ - (PedSector) PED_BE16_TO_CPU ( hfs_priv_data->mdb
-+ ->old_new.embedded
-+ .location.block_count )
-+ * hfs_sect_block;
-+ }
-+
-+ return min_size;
-+}
-+
-+static PedConstraint*
-+hfsplus_get_resize_constraint (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedDevice* dev = fs->geom->dev;
-+ PedAlignment start_align;
-+ PedGeometry start_sector;
-+ PedGeometry full_dev;
-+ PedSector min_size;
-+
-+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
-+ return NULL;
-+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
-+ return NULL;
-+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
-+ return NULL;
-+
-+ min_size = hfsplus_get_min_size (fs);
-+
-+ return ped_constraint_new (&start_align, ped_alignment_any,
-+ &start_sector, &full_dev, min_size,
-+ fs->geom->length);
-+}
-+
-+/* return the block which should be used to pack data to have
-+ at least free fblock blocks at the end of the volume */
-+static unsigned int
-+hfsplus_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ unsigned int block;
-+
-+ for (block = PED_BE32_TO_CPU (priv_data->vh->total_blocks) - 1;
-+ block && fblock;
-+ block--) {
-+ if (!((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ fblock--;
-+ }
-+
-+ while (block && !((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ block--;
-+ if ((priv_data->alloc_map[block / 8] >> (7 - (block & 7))) & 1)
-+ block++;
-+
-+ return block;
-+}
-+
-+static int
-+hfsplus_volume_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ unsigned int nblock, nfree;
-+ unsigned int block;
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ int resize = 1;
-+ unsigned int hfsp_sect_block =
-+ ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ HfsPPrivateFile* allocation_file;
-+ unsigned int map_sectors;
-+
-+ /* Clear the unmounted bit */
-+ vh->attributes &= PED_CPU_TO_BE32 (~( 1 << HFS_UNMOUNTED ));
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, buf, 2, 1))
-+ return 0;
-+
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name(timer, _("shrinking"));
-+ ped_timer_update(timer, 0.0);
-+ /* relocate data */
-+ block = hfsplus_find_start_pack (fs, ( priv_data->plus_geom->length
-+ - geom->length + hfsp_sect_block
-+ - 1 ) / hfsp_sect_block );
-+ if (!hfsplus_pack_free_space_from_block (fs, block, timer)) {
-+ resize = 0;
-+ goto write_VH;
-+ }
-+
-+ /* Calculate new block number and other VH field */
-+ nblock = (geom->length + hfsp_sect_block - 1) / hfsp_sect_block;
-+ nfree = PED_BE32_TO_CPU (vh->free_blocks)
-+ - (PED_BE32_TO_CPU (vh->total_blocks) - nblock);
-+ if (priv_data->plus_geom->length % hfsp_sect_block == 1)
-+ nfree++;
-+ if (geom->length % hfsp_sect_block == 1)
-+ nfree--;
-+
-+ /* Check that all block after future end are really free */
-+ for ( block = nblock;
-+ block < ( priv_data->plus_geom->length - 2 )
-+ / ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE );
-+ block++ ) {
-+ int byte, bit;
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if ((priv_data->alloc_map[byte]>>bit)&1) {
-+ resize = 0;
-+ goto write_VH;
-+ }
-+ }
-+
-+ /* Update geometry */
-+ if (resize) {
-+ /* update in fs structure */
-+ if (PED_BE32_TO_CPU (vh->next_allocation) >= nblock)
-+ vh->next_allocation = PED_CPU_TO_BE32 (0);
-+ vh->total_blocks = PED_CPU_TO_BE32 (nblock);
-+ vh->free_blocks = PED_CPU_TO_BE32 (nfree);
-+ /* update parted structure */
-+ priv_data->plus_geom->length = geom->length;
-+ priv_data->plus_geom->end = priv_data->plus_geom->start
-+ + geom->length - 1;
-+ }
-+
-+ /* Effective write */
-+ write_VH:
-+ /* lasts two sectors are allocated by the alternate VH
-+ and a reserved sector */
-+ block = (priv_data->plus_geom->length - 1) / hfsp_sect_block;
-+ priv_data->alloc_map[block / 8] |= 1 << (7 - (block & 7));
-+ block = (priv_data->plus_geom->length - 2) / hfsp_sect_block;
-+ priv_data->alloc_map[block / 8] |= 1 << (7 - (block & 7));
-+ map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 ) / (PED_SECTOR_SIZE * 8);
-+ allocation_file =
-+ hfsplus_file_open ( fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
-+ vh->allocation_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->allocation_file.logical_size )
-+ / PED_SECTOR_SIZE );
-+ if (!hfsplus_file_write (allocation_file, priv_data->alloc_map,
-+ 0, map_sectors))
-+ resize = 0;
-+ hfsplus_file_close (allocation_file);
-+
-+ if (resize) {
-+ /* Set the unmounted bit and clear the inconsistent bit */
-+ vh->attributes |= PED_CPU_TO_BE32 ( 1 << HFS_UNMOUNTED );
-+ vh->attributes &= ~ PED_CPU_TO_BE32 ( 1 << HFSP_INCONSISTENT );
-+ }
-+
-+ ped_timer_set_state_name(timer, _("writing HFS+ Volume Header"));
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1 ))
-+ return 0;
-+ memcpy (buf, vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, buf, 2, 1 ))
-+ return 0;
-+ if (!ped_geometry_write ( priv_data->plus_geom, buf,
-+ priv_data->plus_geom->length - 2, 1 ))
-+ return 0;
-+ ped_timer_update(timer, 1.0);
-+
-+ return (resize);
-+}
-+
-+/* Update the HFS wrapper mdb and bad blocks file to reflect
-+ the new geometry of the embedded HFS+ volume */
-+static int
-+hfsplus_wrapper_update (PedFileSystem* fs)
-+{
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsCPrivateLeafRec ref;
-+ HfsExtentKey key;
-+ HfsNodeDescriptor* node_desc = (HfsNodeDescriptor*) node;
-+ HfsExtentKey* ret_key;
-+ HfsExtDescriptor* ret_data;
-+ unsigned int i, j;
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE ;
-+ PedSector hfsplus_sect = (PedSector)
-+ PED_BE32_TO_CPU (priv_data->vh->total_blocks)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ unsigned int hfs_blocks_embedded =
-+ (hfsplus_sect + hfs_sect_block - 1)
-+ / hfs_sect_block;
-+ unsigned int hfs_blocks_embedded_old;
-+
-+ /* update HFS wrapper MDB */
-+ hfs_blocks_embedded_old = PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count );
-+ hfs_priv_data->mdb->old_new.embedded.location.block_count =
-+ PED_CPU_TO_BE16 (hfs_blocks_embedded);
-+ /* maybe macOS will boot with this */
-+ hfs_priv_data->mdb->free_blocks =
-+ PED_CPU_TO_BE16 ( PED_BE16_TO_CPU (hfs_priv_data->mdb->free_blocks)
-+ + hfs_blocks_embedded_old
-+ - hfs_blocks_embedded );
-+
-+ if (!ped_geometry_read (fs->geom, node, 2, 1))
-+ return 0;
-+ memcpy (node, hfs_priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, node, 2, 1))
-+ return 0;
-+ if (!ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1))
-+ return 0;
-+
-+ /* force reload bad block list */
-+ if (hfs_priv_data->bad_blocks_loaded) {
-+ hfs_free_bad_blocks_list (hfs_priv_data->bad_blocks_xtent_list);
-+ hfs_priv_data->bad_blocks_xtent_list = NULL;
-+ hfs_priv_data->bad_blocks_xtent_nb = 0;
-+ hfs_priv_data->bad_blocks_loaded = 0;
-+ }
-+
-+ /* clean HFS wrapper allocation map */
-+ for (i = PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new.embedded
-+ .location.start_block )
-+ + hfs_blocks_embedded;
-+ i < PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new.embedded
-+ .location.start_block )
-+ + hfs_blocks_embedded_old;
-+ i++ ) {
-+ hfs_priv_data->alloc_map[i/8] &= ~(1 << (7 - (i & 7)));
-+ }
-+ /* and save it */
-+ if (!ped_geometry_write (fs->geom, hfs_priv_data->alloc_map,
-+ PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->volume_bitmap_block ),
-+ ( PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->total_blocks )
-+ + PED_SECTOR_SIZE * 8 - 1 )
-+ / (PED_SECTOR_SIZE * 8)))
-+ return 0;
-+
-+
-+ /* search and update the bad blocks file */
-+ key.key_length = sizeof(key) - 1;
-+ key.type = HFS_DATA_FORK;
-+ key.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+ key.start = 0;
-+ if (!hfs_btree_search (hfs_priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &key, NULL, 0, &ref))
-+ return 0;
-+ if (!hfs_file_read_sector (hfs_priv_data->extent_file, node,
-+ ref.node_number))
-+ return 0;
-+ ret_key = (HfsExtentKey*) (node + ref.record_pos);
-+ ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
-+ + sizeof (HfsExtentKey) );
-+
-+ while (ret_key->type == key.type && ret_key->file_ID == key.file_ID) {
-+ for (i = 0; i < HFS_EXT_NB; i++) {
-+ if ( ret_data[i].start_block
-+ == hfs_priv_data->mdb->old_new
-+ .embedded.location.start_block) {
-+ ret_data[i].block_count =
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count;
-+ /* found ! : update */
-+ if (!hfs_file_write_sector (
-+ hfs_priv_data->extent_file,
-+ node, ref.node_number))
-+ return 0;
-+ return 1;
-+ }
-+ }
-+
-+ if (ref.record_number < PED_BE16_TO_CPU (node_desc->rec_nb)) {
-+ ref.record_number++;
-+ } else {
-+ ref.node_number = PED_BE32_TO_CPU (node_desc->next);
-+ if (!ref.node_number
-+ || !hfs_file_read_sector(hfs_priv_data->extent_file,
-+ node, ref.node_number))
-+ return 0;
-+ ref.record_number = 1;
-+ }
-+
-+ ref.record_pos = PED_BE16_TO_CPU (*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*ref.record_number))));
-+ ret_key = (HfsExtentKey*) (node + ref.record_pos);
-+ ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
-+ + sizeof (HfsExtentKey) );
-+ }
-+
-+ /* not found : not a valid hfs+ wrapper : failure */
-+ return 0;
-+}
-+
-+static int
-+hfsplus_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedTimer* timer_plus;
-+ PedGeometry* embedded_geom;
-+
-+ /* check preconditions */
-+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
-+
-+ if (fs->geom->start != geom->start)
-+ {
-+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
-+ PED_EXCEPTION_CANCEL,
-+ _("Sorry, can't move the start of hfs partitions yet!"));
-+ return 0;
-+ }
-+
-+ if (geom->length > fs->geom->length
-+ || geom->length < hfsplus_get_min_size (fs))
-+ return 0;
-+
-+ if (priv_data->wrapper) {
-+ PedSector red, hgee;
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+
-+ /* There is a wrapper so we must calculate the new geometry
-+ of the embedded HFS+ volume */
-+ red = ( (fs->geom->length - geom->length + hfs_sect_block - 1)
-+ / hfs_sect_block ) * hfs_sect_block;
-+ /* Can't we shrink the hfs+ volume by the desired size ? */
-+ if ( red > priv_data->plus_geom->length
-+ - (hgee = hfsplus_get_empty_end (fs))) {
-+ /* No, shrink hfs+ by the greatest possible value */
-+ hgee = ((hgee + hfs_sect_block - 1) / hfs_sect_block)
-+ * hfs_sect_block;
-+ red = priv_data->plus_geom->length - hgee;
-+ }
-+ embedded_geom = ped_geometry_new (geom->dev,
-+ priv_data->plus_geom->start,
-+ priv_data->plus_geom->length
-+ - red);
-+
-+ /* There is a wrapper so the resize process is a two stages
-+ process (embedded resizing then wrapper resizing) :
-+ we create a sub timer */
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name (timer,
-+ _("shrinking embedded HFS+ volume"));
-+ ped_timer_update(timer, 0.0);
-+ timer_plus = ped_timer_new_nested (timer, 0.98);
-+ } else {
-+ /* No wrapper : the desired geometry is the desired
-+ HFS+ volume geometry */
-+ embedded_geom = geom;
-+ timer_plus = timer;
-+ }
-+
-+ /* Resize the HFS+ volume */
-+ if (!hfsplus_volume_resize (fs, embedded_geom, timer_plus)) {
-+ if (timer_plus != timer) ped_timer_destroy_nested (timer_plus);
-+ return 0;
-+ }
-+
-+ if (priv_data->wrapper) {
-+ ped_geometry_destroy (embedded_geom);
-+ ped_timer_destroy_nested (timer_plus);
-+ ped_timer_set_state_name(timer, _("shrinking HFS wrapper"));
-+ timer_plus = ped_timer_new_nested (timer, 0.02);
-+ /* There's a wrapper : second stage = resizing it */
-+ if (!hfsplus_wrapper_update (fs)
-+ || !hfs_resize (priv_data->wrapper, geom, timer_plus)) {
-+ ped_timer_destroy_nested (timer_plus);
-+ return 0;
-+ }
-+ ped_timer_destroy_nested (timer_plus);
-+ }
-+ ped_timer_update(timer, 1.0);
-+
-+ return 1;
- }
- #endif /* !DISCOVER_ONLY */
-
-@@ -64,9 +2976,44 @@
- probe: hfs_probe,
- #ifndef DISCOVER_ONLY
- clobber: hfs_clobber,
-+ open: hfs_open,
-+ create: NULL,
-+ close: hfs_close,
-+ check: NULL,
-+ copy: NULL,
-+ resize: hfs_resize,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: hfs_get_resize_constraint,
-+ get_copy_constraint: NULL,
- #else
- clobber: NULL,
-+ open: NULL,
-+ create: NULL,
-+ close: NULL,
-+ check: NULL,
-+ copy: NULL,
-+ resize: NULL,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: NULL,
-+ get_copy_constraint: NULL,
- #endif
-+};
-+
-+static PedFileSystemOps hfsplus_ops = {
-+ probe: hfsplus_probe,
-+#ifndef DISCOVER_ONLY
-+ clobber: hfsplus_clobber,
-+ open: hfsplus_open,
-+ create: NULL,
-+ close: hfsplus_close,
-+ check: NULL,
-+ copy: NULL,
-+ resize: hfsplus_resize,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: hfsplus_get_resize_constraint,
-+ get_copy_constraint: NULL,
-+#else
-+ clobber: NULL,
- open: NULL,
- create: NULL,
- close: NULL,
-@@ -76,23 +3023,32 @@
- get_create_constraint: NULL,
- get_resize_constraint: NULL,
- get_copy_constraint: NULL,
-+#endif
- };
-
-+
- static PedFileSystemType hfs_type = {
- next: NULL,
- ops: &hfs_ops,
- name: "hfs"
- };
-
-+static PedFileSystemType hfsplus_type = {
-+ next: NULL,
-+ ops: &hfsplus_ops,
-+ name: "hfs+"
-+};
-+
- void
- ped_file_system_hfs_init ()
- {
- ped_file_system_type_register (&hfs_type);
-+ ped_file_system_type_register (&hfsplus_type);
- }
-
- void
- ped_file_system_hfs_done ()
- {
- ped_file_system_type_unregister (&hfs_type);
-+ ped_file_system_type_unregister (&hfsplus_type);
- }
--
-diff -u -r -N parted-1.6.5/libparted/fs_hfs/hfs.h parted-1.6.5-hfs/libparted/fs_hfs/hfs.h
---- parted-1.6.5/libparted/fs_hfs/hfs.h Thu Jan 1 01:00:00 1970
-+++ parted-1.6.5-hfs/libparted/fs_hfs/hfs.h Tue Apr 29 05:48:04 2003
-@@ -0,0 +1,543 @@
-+/*
-+ libparted - a library for manipulating disk partitions
-+ Copyright (C) 2003 Free Software Foundation, Inc.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+#ifndef _HFS_H
-+#define _HFS_H
-+
-+
-+#undef HFS_DEBUG
-+
-+#define HFS_SIGNATURE 0x4244
-+#define HFSP_SIGNATURE 0x482B
-+
-+#define HFS_HARD_LOCK 7
-+#define HFS_UNMOUNTED 8
-+#define HFS_BAD_SPARED 9
-+#define HFS_SOFT_LOCK 15
-+#define HFSP_NO_CACHE 10
-+#define HFSP_INCONSISTENT 11
-+
-+#define HFS_IDX_NODE 0x00
-+#define HFS_HDR_NODE 0x01
-+#define HFS_MAP_NODE 0x02
-+#define HFS_LEAF_NODE 0xFF
-+
-+#define HFS_FIRST_REC 0x0E
-+#define HFS_NSD_HD_REC 0x78
-+#define HFS_MAP_REC 0xF8
-+
-+#define HFS_DATA_FORK 0x00
-+#define HFS_RES_FORK 0xFF
-+
-+#define HFS_CAT_DIR 0x01
-+#define HFS_CAT_FILE 0x02
-+#define HFS_CAT_DIR_TH 0x03
-+#define HFS_CAT_FILE_TH 0x04
-+
-+#define HFSP_ATTR_INLINE 0x10
-+#define HFSP_ATTR_FORK 0x20
-+#define HFSP_ATTR_EXTENTS 0x30
-+
-+#define HFS_ROOT_PAR_ID 0x01
-+#define HFS_ROOT_DIR_ID 0x02
-+#define HFS_XTENT_ID 0x03
-+#define HFS_CATALOG_ID 0x04
-+#define HFS_BAD_BLOCK_ID 0x05
-+#define HFSP_ALLOC_ID 0x06
-+#define HFSP_STARTUP_ID 0x07
-+#define HFSP_ATTRIB_ID 0x08
-+#define HFSP_BOGUS_ID 0x0F
-+#define HFSP_FIRST_AV_ID 0x10
-+
-+#define HFS_EXT_NB 3
-+#define HFSP_EXT_NB 8
-+
-+static PedFileSystemType hfs_type;
-+static PedFileSystemType hfsplus_type;
-+
-+
-+
-+/* ----------------------------------- */
-+/* -- HFS DATA STRUCTURES -- */
-+/* ----------------------------------- */
-+
-+/* Extent descriptor */
-+struct __attribute__ ((packed)) _HfsExtDescriptor {
-+ uint16_t start_block;
-+ uint16_t block_count;
-+};
-+typedef struct _HfsExtDescriptor HfsExtDescriptor;
-+typedef HfsExtDescriptor HfsExtDataRec[HFS_EXT_NB];
-+
-+/* Volume header */
-+struct __attribute__ ((packed)) _HfsMasterDirectoryBlock {
-+ uint16_t signature;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint16_t volume_attributes;
-+ uint16_t files_in_root;
-+ uint16_t volume_bitmap_block; /* in sectors */
-+ uint16_t next_allocation;
-+ uint16_t total_blocks;
-+ uint32_t block_size; /* in bytes */
-+ uint32_t def_clump_size; /* in bytes */
-+ uint16_t start_block; /* in sectors */
-+ uint32_t next_free_node;
-+ uint16_t free_blocks;
-+ uint8_t name_length;
-+ char name[27];
-+ uint32_t backup_date;
-+ uint16_t backup_number;
-+ uint32_t write_count;
-+ uint32_t extents_clump;
-+ uint32_t catalog_clump;
-+ uint16_t dirs_in_root;
-+ uint32_t file_count;
-+ uint32_t dir_count;
-+ uint32_t finder_info[8];
-+ union __attribute__ ((packed)) {
-+ struct __attribute__ ((packed)) {
-+ uint16_t volume_cache_size; /* in blocks */
-+ uint16_t bitmap_cache_size; /* in blocks */
-+ uint16_t common_cache_size; /* in blocks */
-+ } legacy;
-+ struct __attribute__ ((packed)) {
-+ uint16_t signature;
-+ HfsExtDescriptor location;
-+ } embedded;
-+ } old_new;
-+ uint32_t extents_file_size; /* in bytes, block size multiple */
-+ HfsExtDataRec extents_file_rec;
-+ uint32_t catalog_file_size; /* in bytes, block size multiple */
-+ HfsExtDataRec catalog_file_rec;
-+};
-+typedef struct _HfsMasterDirectoryBlock HfsMasterDirectoryBlock;
-+
-+/* B*-Tree Node Descriptor */
-+struct __attribute__ ((packed)) _HfsNodeDescriptor {
-+ uint32_t next;
-+ uint32_t previous;
-+ int8_t type;
-+ uint8_t height;
-+ uint16_t rec_nb;
-+ uint16_t reserved;
-+};
-+typedef struct _HfsNodeDescriptor HfsNodeDescriptor;
-+
-+/* Header record of a whole B*-Tree */
-+struct __attribute__ ((packed)) _HfsHeaderRecord {
-+ uint16_t depth;
-+ uint32_t root_node;
-+ uint32_t leaf_records;
-+ uint32_t first_leaf_node;
-+ uint32_t last_leaf_node;
-+ uint16_t node_size;
-+ uint16_t max_key_len;
-+ uint32_t total_nodes;
-+ uint32_t free_nodes;
-+ int8_t reserved[76];
-+};
-+typedef struct _HfsHeaderRecord HfsHeaderRecord;
-+
-+/* Catalog key for B*-Tree lookup in the catalog file */
-+struct __attribute__ ((packed)) _HfsCatalogKey {
-+ int8_t key_length; /* length of the key without key_length */
-+ int8_t reserved;
-+ uint32_t parent_ID;
-+ int8_t name_length;
-+ char name[31]; /* in fact physicaly 1 upto 31 */
-+};
-+typedef struct _HfsCatalogKey HfsCatalogKey;
-+
-+/* Extents overflow key for B*-Tree lookup */
-+struct __attribute__ ((packed)) _HfsExtentKey {
-+ int8_t key_length; /* length of the key without key_length */
-+ int8_t type; /* data or ressource fork */
-+ uint32_t file_ID;
-+ uint16_t start;
-+};
-+typedef struct _HfsExtentKey HfsExtentKey;
-+
-+/* Catalog subdata case directory */
-+struct __attribute__ ((packed)) _HfsDir {
-+ uint16_t flags;
-+ uint16_t valence; /* number of files in this directory */
-+ uint32_t dir_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ int8_t DInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t DXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t reserved[4];
-+};
-+typedef struct _HfsDir HfsDir;
-+
-+/* Catalog subdata case file */
-+struct __attribute__ ((packed)) _HfsFile {
-+ int8_t flags;
-+ int8_t type; /* should be 0 */
-+ int8_t FInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t file_ID;
-+ uint16_t data_start_block;
-+ uint32_t data_sz_byte;
-+ uint32_t data_sz_block;
-+ uint16_t res_start_block;
-+ uint32_t res_sz_byte;
-+ uint32_t res_sz_block;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ int8_t FXInfo[16]; /* used by Finder, handle as reserved */
-+ uint16_t clump_size;
-+ HfsExtDataRec extents_data;
-+ HfsExtDataRec extents_res;
-+ uint32_t reserved;
-+};
-+typedef struct _HfsFile HfsFile;
-+
-+/* Catalog subdata case directory thread */
-+struct __attribute__ ((packed)) _HfsDirTh {
-+ uint32_t reserved[2];
-+ uint32_t parent_ID;
-+ int8_t name_length;
-+ char name[31];
-+};
-+typedef struct _HfsDirTh HfsDirTh;
-+
-+/* Catalog subdata case file thread */
-+typedef struct _HfsDirTh HfsFileTh; /* same as directory thread */
-+
-+/* Catalog data */
-+struct __attribute__ ((packed)) _HfsCatalog {
-+ int8_t type;
-+ int8_t reserved;
-+ union {
-+ HfsDir dir;
-+ HfsFile file;
-+ HfsDirTh dir_th;
-+ HfsFileTh file_th;
-+ } sel;
-+};
-+typedef struct _HfsCatalog HfsCatalog;
-+
-+
-+
-+/* ------------------------------------ */
-+/* -- HFS+ DATA STRUCTURES -- */
-+/* ------------------------------------ */
-+
-+/* Permission struct is reserved in HFS+ official specification */
-+/* May be it could be used in unix implementations of HFS+ */
-+struct __attribute__ ((packed)) _HfsPPerms {
-+ uint32_t owner_ID; /* reserved */
-+ uint32_t group_ID; /* reserved */
-+ uint32_t permissions; /* reserved */
-+ uint32_t special_devices; /* reserved */
-+};
-+typedef struct _HfsPPerms HfsPPerms;
-+
-+/* HFS+ extent descriptor*/
-+struct __attribute__ ((packed)) _HfsPExtDescriptor {
-+ uint32_t start_block;
-+ uint32_t block_count;
-+};
-+typedef struct _HfsPExtDescriptor HfsPExtDescriptor;
-+typedef HfsPExtDescriptor HfsPExtDataRec[HFSP_EXT_NB];
-+
-+/* HFS+ fork data structure */
-+struct __attribute__ ((packed)) _HfsPForkData {
-+ uint64_t logical_size;
-+ uint32_t clump_size;
-+ uint32_t total_blocks;
-+ HfsPExtDataRec extents;
-+};
-+typedef struct _HfsPForkData HfsPForkData;
-+
-+/* HFS+ catalog node ID */
-+typedef uint32_t HfsPNodeID;
-+
-+/* HFS+ file names */
-+typedef uint16_t unichar;
-+struct __attribute__ ((packed)) _HfsPUniStr255 {
-+ uint16_t length;
-+ unichar unicode[255]; /* 1 upto 255 */
-+};
-+typedef struct _HfsPUniStr255 HfsPUniStr255;
-+
-+/* HFS+ volume header */
-+struct __attribute__ ((packed)) _HfsPVolumeHeader {
-+ uint16_t signature;
-+ uint16_t version;
-+ uint32_t attributes;
-+ uint32_t last_mounted_version;
-+ uint32_t reserved;
-+
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ uint32_t checked_date;
-+
-+ uint32_t file_count;
-+ uint32_t dir_count;
-+
-+ uint32_t block_size;
-+ uint32_t total_blocks;
-+ uint32_t free_blocks;
-+
-+ uint32_t next_allocation;
-+ uint32_t res_clump_size;
-+ uint32_t data_clump_size;
-+ HfsPNodeID next_catalog_ID;
-+
-+ uint32_t write_count;
-+ uint64_t encodings_bitmap;
-+
-+ uint8_t finder_info[32];
-+
-+ HfsPForkData allocation_file;
-+ HfsPForkData extents_file;
-+ HfsPForkData catalog_file;
-+ HfsPForkData attributes_file;
-+ HfsPForkData startup_file;
-+};
-+typedef struct _HfsPVolumeHeader HfsPVolumeHeader;
-+
-+/* HFS+ B-Tree Node Descriptor */ /* same as HFS btree */
-+struct __attribute__ ((packed)) _HfsPNodeDescriptor {
-+ uint32_t next;
-+ uint32_t previous;
-+ int8_t type;
-+ uint8_t height;
-+ uint16_t rec_nb;
-+ uint16_t reserved;
-+};
-+typedef struct _HfsPNodeDescriptor HfsPNodeDescriptor;
-+
-+/* Header record of a whole HFS+ B-Tree */
-+struct __attribute__ ((packed)) _HfsPHeaderRecord {
-+ uint16_t depth;
-+ uint32_t root_node;
-+ uint32_t leaf_records;
-+ uint32_t first_leaf_node;
-+ uint32_t last_leaf_node;
-+ uint16_t node_size;
-+ uint16_t max_key_len;
-+ uint32_t total_nodes;
-+ uint32_t free_nodes; /* same as hfs btree until here */
-+ uint16_t reserved1;
-+
-+ uint32_t clump_size;
-+ uint8_t btree_type; /* must be 0 for HFS+ B-Tree */
-+ uint8_t reserved2;
-+ uint32_t attributes;
-+ uint32_t reserved3[16];
-+};
-+typedef struct _HfsPHeaderRecord HfsPHeaderRecord;
-+
-+/* Catalog key for B-Tree lookup in the HFS+ catalog file */
-+struct __attribute__ ((packed)) _HfsPCatalogKey {
-+ uint16_t key_length;
-+ HfsPNodeID parent_ID;
-+ HfsPUniStr255 node_name;
-+};
-+typedef struct _HfsPCatalogKey HfsPCatalogKey;
-+
-+/* HFS+ catalog subdata case dir */
-+struct __attribute__ ((packed)) _HfsPDir {
-+ uint16_t flags;
-+ uint32_t valence;
-+ HfsPNodeID dir_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t attrib_mod_date;
-+ uint32_t access_date;
-+ uint32_t backup_date;
-+ HfsPPerms permissions;
-+ int8_t DInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t DXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t text_encoding;
-+ uint32_t reserved;
-+};
-+typedef struct _HfsPDir HfsPDir;
-+
-+/* HFS+ catalog subdata case file */
-+struct __attribute__ ((packed)) _HfsPFile {
-+ uint16_t flags;
-+ uint32_t reserved1;
-+ HfsPNodeID file_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t attrib_mod_date;
-+ uint32_t access_date;
-+ uint32_t backup_date;
-+ HfsPPerms permissions;
-+ int8_t FInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t FXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t text_encoding;
-+ uint32_t reserved2;
-+
-+ HfsPForkData data_fork;
-+ HfsPForkData res_fork;
-+};
-+typedef struct _HfsPFile HfsPFile;
-+
-+/* HFS+ catalog subdata case thread */
-+struct __attribute__ ((packed)) _HfsPThread {
-+ int16_t reserved;
-+ HfsPNodeID parent_ID;
-+ HfsPUniStr255 node_name;
-+};
-+typedef struct _HfsPThread HfsPDirTh;
-+typedef struct _HfsPThread HfsPFileTh;
-+
-+/* HFS+ Catalog leaf data */
-+struct __attribute__ ((packed)) _HfsPCatalog {
-+ int16_t type;
-+ union {
-+ HfsPDir dir;
-+ HfsPFile file;
-+ HfsPDirTh dir_th;
-+ HfsPFileTh file_th;
-+ } sel;
-+};
-+typedef struct _HfsPCatalog HfsPCatalog;
-+
-+/* HFS+ extents file key */
-+struct __attribute__ ((packed)) _HfsPExtentKey {
-+ uint16_t key_length;
-+ uint8_t type;
-+ uint8_t pad;
-+ HfsPNodeID file_ID;
-+ uint32_t start;
-+};
-+typedef struct _HfsPExtentKey HfsPExtentKey;
-+
-+/* extent file data is HfsPExtDataRec */
-+
-+/* Fork data attribute file */
-+struct __attribute__ ((packed)) _HfsPForkDataAttr {
-+ uint32_t record_type;
-+ uint32_t reserved;
-+ union __attribute__ ((packed)) {
-+ HfsPForkData fork;
-+ HfsPExtDataRec extents;
-+ } fork_res;
-+};
-+typedef struct _HfsPForkDataAttr HfsPForkDataAttr;
-+
-+
-+
-+/* ---------------------------------------- */
-+/* -- INTERNAL DATA STRUCTURES -- */
-+/* ---------------------------------------- */
-+
-+/* Data of an opened HFS file */
-+struct _HfsPrivateFile {
-+ PedSector sect_nb;
-+ PedFileSystem* fs;
-+ uint32_t CNID; /* disk order (BE) */
-+ HfsExtDataRec first; /* disk order (BE) */
-+ HfsExtDataRec cache; /* disk order (BE) */
-+ uint16_t start_cache; /* CPU order */
-+};
-+typedef struct _HfsPrivateFile HfsPrivateFile;
-+
-+/* To store bad block list */
-+struct _HfsPrivateLinkExtent {
-+ HfsExtDescriptor extent;
-+ struct _HfsPrivateLinkExtent* next;
-+};
-+typedef struct _HfsPrivateLinkExtent HfsPrivateLinkExtent;
-+
-+/* HFS Filesystem specific data */
-+struct _HfsPrivateFSData {
-+ uint8_t alloc_map[(1<<16) / 8];
-+ HfsMasterDirectoryBlock* mdb;
-+ HfsPrivateFile* extent_file;
-+ HfsPrivateFile* catalog_file;
-+ char bad_blocks_loaded;
-+ unsigned int bad_blocks_xtent_nb;
-+ HfsPrivateLinkExtent* bad_blocks_xtent_list;
-+};
-+typedef struct _HfsPrivateFSData HfsPrivateFSData;
-+
-+/* Generic btree key */
-+struct __attribute__ ((packed)) _HfsPrivateGenericKey {
-+ int8_t key_length;
-+ uint8_t key_content[1]; /* we use 1 as a minimum size */
-+};
-+typedef struct _HfsPrivateGenericKey HfsPrivateGenericKey;
-+
-+/* ----- HFS+ ----- */
-+
-+/* Data of an opened HFS file */
-+struct _HfsPPrivateFile {
-+ PedSector sect_nb;
-+ PedFileSystem* fs;
-+ HfsPNodeID CNID; /* disk order (BE) */
-+ HfsPExtDataRec first; /* disk order (BE) */
-+ HfsPExtDataRec cache; /* disk order (BE) */
-+ uint32_t start_cache; /* CPU order */
-+};
-+typedef struct _HfsPPrivateFile HfsPPrivateFile;
-+
-+/* To store bad block list */
-+struct _HfsPPrivateLinkExtent {
-+ HfsPExtDescriptor extent;
-+ struct _HfsPPrivateLinkExtent* next;
-+};
-+typedef struct _HfsPPrivateLinkExtent HfsPPrivateLinkExtent;
-+
-+/* HFS+ filesystem specific data */
-+struct _HfsPPrivateFSData {
-+ PedFileSystem* wrapper; /* NULL if hfs+ is not embedded */
-+ PedGeometry* plus_geom; /* Geometry of HFS+ _volume_ */
-+ char free_geom; /* 1 = plus_geom must be freed */
-+ uint8_t* alloc_map;
-+ HfsPVolumeHeader* vh;
-+ HfsPPrivateFile* extents_file;
-+ HfsPPrivateFile* catalog_file;
-+ HfsPPrivateFile* attributes_file;
-+ char bad_blocks_loaded;
-+ unsigned int bad_blocks_xtent_nb;
-+ HfsPPrivateLinkExtent* bad_blocks_xtent_list;
-+};
-+typedef struct _HfsPPrivateFSData HfsPPrivateFSData;
-+
-+/* Generic + btree key */
-+struct __attribute__ ((packed)) _HfsPPrivateGenericKey {
-+ uint16_t key_length;
-+ uint8_t key_content[1]; /* we use 1 as a minimum size */
-+};
-+typedef struct _HfsPPrivateGenericKey HfsPPrivateGenericKey;
-+
-+/* ---- common ---- */
-+
-+/* node and lead record reference for a BTree search */
-+struct _HfsCPrivateLeafRec {
-+ unsigned int node_size; /* in sectors */
-+ unsigned int node_number;
-+ unsigned int record_pos;
-+ unsigned int record_number;
-+};
-+typedef struct _HfsCPrivateLeafRec HfsCPrivateLeafRec;
-+
-+
-+
-+#endif /* _HFS_H */
diff --git a/sys-apps/parted/files/parted-1.6.6-hfs-9.patch b/sys-apps/parted/files/parted-1.6.6-hfs-9.patch
deleted file mode 100644
index 58d9b2c9c42f..000000000000
--- a/sys-apps/parted/files/parted-1.6.6-hfs-9.patch
+++ /dev/null
@@ -1,3887 +0,0 @@
-diff -Nru parted-1.6.6/AUTHORS parted-1.6.6-hfs/AUTHORS
---- parted-1.6.6/AUTHORS Sun Jul 6 06:47:07 2003
-+++ parted-1.6.6-hfs/AUTHORS Mon Oct 27 23:25:18 2003
-@@ -142,3 +142,7 @@
-
- Miloslav Trmac <mitr@volny.cz>
- * Czech translations
-+
-+Guillaume Knispel <k_guillaume@libertysurf.fr>
-+ * nearly all hfs and hfs+ code (libparted/fs_hfs)
-+ * hfs+ support for mac partitions (libparted/disk_mac.c)
-diff -Nru parted-1.6.6/libparted/disk_mac.c parted-1.6.6-hfs/libparted/disk_mac.c
---- parted-1.6.6/libparted/disk_mac.c Mon Jun 30 02:47:58 2003
-+++ parted-1.6.6-hfs/libparted/disk_mac.c Mon Oct 27 23:25:18 2003
-@@ -1068,7 +1068,8 @@
- return 1;
- }
-
-- if (fs_type && !strcmp (fs_type->name, "hfs")) {
-+ if (fs_type && (!strcmp (fs_type->name, "hfs")
-+ || !strcmp (fs_type->name, "hfs+"))) {
- strcpy (mac_data->system_name, "Apple_HFS");
- mac_data->status |= 0x7f;
- } else {
-diff -Nru parted-1.6.6/libparted/fs_hfs/hfs.c parted-1.6.6-hfs/libparted/fs_hfs/hfs.c
---- parted-1.6.6/libparted/fs_hfs/hfs.c Mon Apr 8 12:10:25 2002
-+++ parted-1.6.6-hfs/libparted/fs_hfs/hfs.c Mon Oct 27 23:25:18 2003
-@@ -1,6 +1,6 @@
- /*
- libparted - a library for manipulating disk partitions
-- Copyright (C) 2000 Free Software Foundation, Inc.
-+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
-
- 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
-@@ -17,10 +17,67 @@
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-+/*
-+ Author : Guillaume Knispel <k_guillaume@libertysurf.fr>
-+ Report bug to <bug-parted@gnu.org>
-+*/
-+
-+/*
-+ Technical doc about Apple HFS and HFS+ file systems is available at :
-+ * For HFS, section "Data Organization on Volumes",
-+ "Chapter 2 - File Manager"
-+ of the book "Inside Macintosh: Files"
-+ http://developer.apple.com/techpubs/mac/Files/Files-99.html#HEADING99-0
-+ * For HFS+, "Technical Note TN1150", "HFS Plus Volume Format"
-+ http://developer.apple.com/technotes/tn/tn1150.html
-+
-+ Some useful HFS precisions concerning alignement and bit ordering
-+ are in the HFS+ TN
-+*/
-+
-+/* HISTORY :
-+## modifications dd-mm-yyyy
-+---------------------- PATCH FOR PARTED 1.6.5 ----------------------------
-+ 1 initial revision 07-04-2003
-+ 2 one pass resizing, removal of debug info 08-04-2003
-+ 3 safe abort if resize failed, code cleanups, timer, 10-04-2003
-+ source file split, won't resize if not unmounted,
-+ only relocate data if needed, minimize disk operations
-+ 4 memory leaks removal, code cleanups, resize hfs+ code, 17-04-2003
-+ more checks, minor hfs resize bugfix, probe code
-+ returns real geometry
-+ 5 hfs+ resize bugfixes : 19-04-2003
-+ * fragmented fs could be corrupted
-+ * VH wasn't written on error during alloc map writing
-+ * attributes file could be corrupted
-+ 6 Use PedSector to be able to use > 2 To HD 23-04-2003
-+ Minor probe bugfix, Cleanups, HFS+ Timer tuning,
-+ 7 80 columns indentation 23-04-2003
-+ 8 Bugfix free blocks calculation in wrapper
-+ (makes Mac OS boot !) 28-04-2003
-+---------------------- PATCH FOR PARTED 1.6.6 ----------------------------
-+ 9 Don't destroy the file being worked on in case of
-+ interruption of Parted 28-10-2003
-+*/
-+
-+/* TODO :
-+ * Think about a mean to do more allocation bitmap
-+ saves when shrinking hfs+ -- not too hard, necessary ?
-+ * what's said in #9 :) -- DONE, but may sometime makes fail the process
-+ * write lots of error message display to be able to have
-+ usefull bug reports -- Urgent, put in 10 maximum !
-+ * rewrite *_search_move_* because they're becoming unmaintainable
-+ (use of goto, etc...) -- Can wait patch 10 or later
-+ * Change the relocation algorithm for a better one -- #42 :) */
-+
- #include "config.h"
-
-+#include <stdlib.h>
-+#include <string.h>
- #include <parted/parted.h>
- #include <parted/endian.h>
-+#include <parted/debug.h>
-+#include <stdint.h>
-
- #if ENABLE_NLS
- # include <libintl.h>
-@@ -29,34 +86,3145 @@
- # define _(String) (String)
- #endif /* ENABLE_NLS */
-
--#include <string.h>
-+#include "hfs.h"
-
--#define HFS_SIGNATURE 0x4244
-+#define MAX_BUFF 256 /* in blocks */
-+
-+/* -------------------- */
-+/* -- CODE -- */
-+/* -------------------- */
-+
-+/* Probe an HFS volume, detecting it even if
-+it is in fact a wrapper to an HFS+ volume */
-+/* Used by hfsplus_probe and hfs_probe */
-+static PedGeometry*
-+hfs_and_wrapper_probe (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ HfsMasterDirectoryBlock *mdb;
-+ PedGeometry* geom_ret;
-+ PedSector search, max;
-+
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if ((geom->length < 5)
-+ || (!ped_geometry_read (geom, buf, 2, 1))
-+ || (PED_BE16_TO_CPU (mdb->signature) != HFS_SIGNATURE) )
-+ return NULL;
-+
-+ search = ((PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + ((PedSector) PED_BE16_TO_CPU (mdb->total_blocks)
-+ * (PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE )));
-+ max = search + ( PED_BE32_TO_CPU (mdb->block_size) / PED_SECTOR_SIZE );
-+ if (!(geom_ret = ped_geometry_new (geom->dev, geom->start, search + 2)))
-+ return NULL;
-+
-+ for (; search < max; search++) {
-+ if (!ped_geometry_set (geom_ret, geom_ret->start, search + 2)
-+ || !ped_geometry_read (geom_ret, buf, search, 1))
-+ break;
-+ if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE)
-+ return geom_ret;
-+ }
-+
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+}
-+
-+static PedGeometry*
-+hfsplus_probe (PedGeometry* geom)
-+{
-+ PedGeometry* geom_ret;
-+ uint8_t buf[PED_SECTOR_SIZE];
-+
-+ if ((geom_ret = hfs_and_wrapper_probe(geom))) {
-+ /* HFS+ is embedded in an HFS volume ? */
-+ HfsMasterDirectoryBlock *mdb;
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1)
-+ || (PED_BE16_TO_CPU (mdb->old_new.embedded.signature)
-+ != HFSP_SIGNATURE)) {
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+ } else
-+ return geom_ret;
-+ } else {
-+ /* This is a standalone HFS+ volume ? */
-+ PedSector search, max;
-+ HfsPVolumeHeader *vh;
-+ vh = (HfsPVolumeHeader *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1)
-+ || (PED_BE16_TO_CPU (vh->signature) != HFSP_SIGNATURE))
-+ return NULL;
-+
-+ max = (PedSector) PED_BE32_TO_CPU (vh->total_blocks)
-+ * ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE );
-+ search = max - ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) - 1;
-+ if (!(geom_ret = ped_geometry_new (geom->dev, geom->start,
-+ search + 2)))
-+ return NULL;
-+
-+ for (; search < max; search++) {
-+ if (!ped_geometry_set (geom_ret, geom_ret->start,
-+ search + 2)
-+ || !ped_geometry_read (geom_ret, buf, search, 1))
-+ break;
-+ if (PED_BE16_TO_CPU (vh->signature) == HFSP_SIGNATURE)
-+ return geom_ret;
-+ }
-+
-+ ped_geometry_destroy (geom_ret);
-+ return NULL;
-+ }
-+}
-
- static PedGeometry*
- hfs_probe (PedGeometry* geom)
- {
-- char buf[512];
-+ PedGeometry* geom_base;
-+ PedGeometry* geom_plus = NULL;
-+
-+ if ((geom_base = hfs_and_wrapper_probe(geom))
-+ && (!(geom_plus = hfsplus_probe(geom_base))))
-+ return geom_base;
-+ else {
-+ if (geom_base) ped_geometry_destroy (geom_base);
-+ if (geom_plus) ped_geometry_destroy (geom_plus);
-+ return NULL;
-+ }
-+}
-+
-+#ifndef DISCOVER_ONLY
-+/* declaration used by hfs_btree_search (indirect recursion) */
-+static int
-+hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector);
-
-- if (geom->length < 2)
-+/* This is a very unundoable operation :p */
-+/* Maybe I shouldn't touch the alternate MDB ? */
-+/* Anyway clobber is call before other fs creation */
-+/* So this must be a non-issue */
-+static int
-+hfs_clobber (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+
-+ memset (buf, 0, PED_SECTOR_SIZE);
-+
-+ /* destroy boot blocks, mdb, alternate mdb ... */
-+ return ped_geometry_write (geom, buf, 0, 1) &
-+ ped_geometry_write (geom, buf, 1, 1) &
-+ ped_geometry_write (geom, buf, 2, 1) &
-+ ped_geometry_write (geom, buf, geom->length - 2, 1) &
-+ ped_geometry_write (geom, buf, geom->length - 1, 1);
-+}
-+
-+static int
-+hfsplus_clobber (PedGeometry* geom)
-+{
-+ unsigned int i = 1;
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ HfsMasterDirectoryBlock *mdb;
-+
-+ mdb = (HfsMasterDirectoryBlock *) buf;
-+
-+ if (!ped_geometry_read (geom, buf, 2, 1))
- return 0;
-+
-+
-+ if (PED_BE16_TO_CPU (mdb->signature) == HFS_SIGNATURE) {
-+ /* embedded hfs+ */
-+ PedGeometry *embedded;
-+
-+ i = (PED_BE32_TO_CPU(mdb->block_size) / PED_SECTOR_SIZE);
-+ embedded = ped_geometry_new (
-+ geom->dev,
-+ (PedSector) geom->start
-+ + PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) PED_BE16_TO_CPU (
-+ mdb->old_new.embedded.location.start_block ) * i,
-+ (PedSector) PED_BE16_TO_CPU (
-+ mdb->old_new.embedded.location.block_count ) * i );
-+ i = hfs_clobber (embedded);
-+ ped_geometry_destroy (embedded);
-+ }
-+
-+ /* non-embedded or envelop destroy as hfs */
-+ return ( hfs_clobber (geom) && i );
-+}
-+
-+/* Open the data fork of a file with its first three extents and its CNID */
-+static HfsPrivateFile*
-+hfs_file_open (PedFileSystem *fs, uint32_t CNID,
-+ HfsExtDataRec ext_desc, PedSector sect_nb)
-+{
-+ HfsPrivateFile* file;
-+
-+ file = (HfsPrivateFile*) ped_malloc (sizeof (HfsPrivateFile));
-+
-+ file->fs = fs;
-+ file->sect_nb = sect_nb;
-+ file->CNID = CNID;
-+ memcpy(file->first, ext_desc, sizeof (HfsExtDataRec));
-+ memcpy(file->cache, ext_desc, sizeof (HfsExtDataRec));
-+ file->start_cache = 0;
-+
-+ return file;
-+}
-+
-+/* Close an HFS file */
-+static void
-+hfs_file_close (HfsPrivateFile* file)
-+{
-+ ped_free (file);
-+}
-+
-+/* do a B-Tree lookup */
-+/* read the first record immediatly inferior or egal to the given key */
-+/* return 0 on error */
-+/* record_out _must_ be large enough to receive record_size bytes */
-+static int
-+hfs_btree_search (HfsPrivateFile* b_tree_file, HfsPrivateGenericKey* key,
-+ void *record_out, unsigned int record_size,
-+ HfsCPrivateLeafRec* record_ref)
-+{
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsPrivateGenericKey* record_key = NULL;
-+ unsigned int node_number, record_number;
-+ int i;
-+
-+ /* Read the header node */
-+ if (!hfs_file_read_sector(b_tree_file, node, 0))
-+ return 0;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+
-+ /* Get the node number of the root */
-+ node_number = PED_BE32_TO_CPU(header->root_node);
-+
-+ /* Read the root node */
-+ if (!hfs_file_read_sector(b_tree_file, node, node_number))
-+ return 0;
-+
-+ /* Follow the white rabbit */
-+ while (1) {
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = record_number; i; i--) {
-+ int cmp, min_length;
-+
-+ record_key = (HfsPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*i)))));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)record_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)record_key - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return 0;
-+ min_length = ( (key->key_length
-+ > record_key->key_length) ?
-+ (record_key->key_length) :
-+ (key->key_length) );
-+ cmp = memcmp (record_key->key_content,
-+ key->key_content, min_length);
-+ if (cmp < 0 || ( cmp == 0 && record_key->key_length
-+ <= key->key_length))
-+ break;
-+ }
-+ if (!i) return 0;
-+ if (desc->type == HFS_IDX_NODE) {
-+ unsigned int skip;
-+
-+ skip = (1 + record_key->key_length + 1) & ~1;
-+ node_number = PED_BE32_TO_CPU (*((uint32_t *)
-+ (((uint8_t *) record_key) + skip)));
-+ if (!hfs_file_read_sector(b_tree_file, node,
-+ node_number))
-+ return 0;
-+ } else
-+ break;
-+ }
-+
-+ /* copy the result if needed */
-+ if (record_size)
-+ memcpy (record_out, record_key, record_size);
-+
-+ /* send record reference if needed */
-+ if (record_ref) {
-+ record_ref->node_size = 1; /* in sectors */
-+ record_ref->node_number = node_number;
-+ record_ref->record_pos = (uint8_t*)record_key - node;
-+ record_ref->record_number = i;
-+ }
-+
-+ /* success */
-+ return 1;
-+}
-+
-+static int
-+hfs_get_extent_containing (HfsPrivateFile* file, unsigned int block,
-+ HfsExtDataRec cache, uint16_t* ptr_start_cache)
-+{
-+ uint8_t record[sizeof (HfsExtentKey)
-+ + sizeof (HfsExtDataRec)];
-+ HfsExtentKey search;
-+ HfsExtentKey* ret_key = (HfsExtentKey*) record;
-+ HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
-+ (record + sizeof (HfsExtentKey));
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ file->fs->type_specific;
-+
-+
-+ search.key_length = sizeof (HfsExtentKey) - 1;
-+ search.type = HFS_DATA_FORK;
-+ search.file_ID = file->CNID;
-+ search.start = PED_CPU_TO_BE16 (block);
-+
-+ if (!hfs_btree_search (priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL))
-+ return 0;
-+
-+ if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
-+ return 0;
-+
-+ memcpy (cache, ret_cache, sizeof(HfsExtDataRec));
-+ *ptr_start_cache = PED_BE16_TO_CPU (ret_key->start);
-+
-+ return 1;
-+}
-+
-+/* find and return the nth sector of a file */
-+/* return 0 on error */
-+static PedSector
-+hfs_file_find_sector (HfsPrivateFile* file, PedSector sector)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ file->fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ unsigned int i, s, vol_block;
-+ unsigned int block = sector
-+ / (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ unsigned int offset = sector
-+ % (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+
-+ /* in the three first extent */
-+ for (s = 0, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->first[i].block_count)) {
-+ if ((block >= s) && ( block < s + PED_BE16_TO_CPU (
-+ file->first[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->first[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE16_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->cache[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ /* update cache */
-+ if (!hfs_get_extent_containing (file, block, file->cache,
-+ &(file->start_cache)))
-+ return 0;
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0; i < HFS_EXT_NB; i++,
-+ s += PED_BE16_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE16_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s) + PED_BE16_TO_CPU (
-+ file->cache[i].start_block);
-+ goto sector_found;
-+ }
-+ }
-+
-+ return 0;
-+
-+ sector_found:
-+ return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) vol_block * (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE)
-+ + offset;
-+}
-+
-+/* Read the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfs_file_read_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-+{
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfs_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_read (file->fs->geom, buf,
-+ abs_sector, 1);
-+}
-+
-+/* Write the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfs_file_write_sector (HfsPrivateFile* file, void *buf, PedSector sector)
-+{
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfs_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_write (file->fs->geom, buf,
-+ abs_sector, 1);
-+}
-+
-+/* This function reads bad blocks extents in the extents file
-+ and store it in f.s. specific data of fs */
-+static int
-+hfs_read_bad_blocks (const PedFileSystem *fs)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (!priv_data->bad_blocks_loaded) {
-+ uint8_t record[sizeof (HfsExtentKey)
-+ + sizeof (HfsExtDataRec)];
-+ HfsExtentKey search;
-+ HfsExtentKey* ret_key = (HfsExtentKey*) record;
-+ HfsExtDescriptor* ret_cache = (HfsExtDescriptor*)
-+ (record
-+ + sizeof (HfsExtentKey));
-+ unsigned int block, last_start, first_pass = 1;
-+
-+ search.key_length = sizeof (HfsExtentKey) - 1;
-+ search.type = HFS_DATA_FORK;
-+ search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+
-+ last_start = -1; block = 0;
-+ while (1) {
-+ int i;
-+
-+ search.start = PED_CPU_TO_BE16 (block);
-+ if (!hfs_btree_search (priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL)) {
-+ if (first_pass)
-+ break;
-+ else
-+ return 0;
-+ }
-+ if (ret_key->file_ID != search.file_ID
-+ || ret_key->type != search.type)
-+ break;
-+ if (PED_BE16_TO_CPU (ret_key->start) == last_start)
-+ break;
-+
-+ last_start = PED_BE16_TO_CPU (ret_key->start);
-+ for (i = 0; i < HFS_EXT_NB; i++) {
-+ if (ret_cache[i].block_count) {
-+ HfsPrivateLinkExtent* new_xt =
-+ (HfsPrivateLinkExtent*) ped_malloc (
-+ sizeof (HfsPrivateLinkExtent));
-+ new_xt->next =
-+ priv_data->bad_blocks_xtent_list;
-+ memcpy(&(new_xt->extent), ret_cache+i,
-+ sizeof (HfsExtDescriptor));
-+ priv_data->bad_blocks_xtent_list =
-+ new_xt;
-+ priv_data->bad_blocks_xtent_nb++;
-+ block += PED_BE16_TO_CPU (
-+ ret_cache[i].block_count);
-+ }
-+ }
-+ first_pass = 0;
-+ }
-+
-+ priv_data->bad_blocks_loaded = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+/* free the bad blocks linked list */
-+static void
-+hfs_free_bad_blocks_list(HfsPrivateLinkExtent* first)
-+{
-+ HfsPrivateLinkExtent* next;
-+
-+ while (first) {
-+ next = first->next;
-+ ped_free (first);
-+ first = next;
-+ }
-+}
-+
-+/* This function check if fblock is a bad block */
-+static int
-+hfs_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsPrivateLinkExtent* walk;
-+
-+ for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
-+ /* Won't compile without the strange cast ! gcc bug ? */
-+ /* or maybe C subtilties... */
-+ if ((fblock >= PED_BE16_TO_CPU (walk->extent.start_block)) &&
-+ (fblock < (unsigned int) (PED_BE16_TO_CPU (
-+ walk->extent.start_block)
-+ + PED_BE16_TO_CPU (
-+ walk->extent.block_count))))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves data of size blocks starting
-+ at block *ptr_fblock to block *ptr_to_fblock */
-+/* return new start or -1 on failure */
-+static int
-+hfs_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock, unsigned int size)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t* block;
-+ unsigned int i;
-+ unsigned int new_start;
-+ unsigned int next_to_fblock = 0;
-+ unsigned int start = 0, stop = 0;
-+ int ok = 0;
-+
-+#if 0
-+
-+ /* try to find enough room to fit the extent */
-+ for (i = *ptr_to_fblock;
-+ i < *ptr_to_fblock + size && i < *ptr_fblock;
-+ i++) {
-+ if (hfs_is_bad_block (fs, i))
-+ *ptr_to_fblock = i+1;
-+ }
-+
-+#else
-+
-+ /* try to find enough room to fit the extent in a non overlapping way */
-+
-+ /* special case of next if, keep it only if it increases speed in a
-+ significant way */
-+ if (*ptr_to_fblock + size <= *ptr_fblock) {
-+ ok = 1;
-+ for (i = *ptr_to_fblock; ok && i < *ptr_to_fblock; i++)
-+ if ((priv_data->alloc_map[i/8] & (1<<(7-(i&7))))) ok = 0;
-+ next_to_fblock = *ptr_to_fblock + size;
-+ start = *ptr_to_fblock;
-+ }
-+
-+ /* back search */
-+ if (!ok && *ptr_fblock != *ptr_to_fblock) {
-+ start = stop = *ptr_fblock;
-+ while (start && stop-start != size) {
-+ --start;
-+ if ((priv_data->alloc_map[start/8] & (1<<(7-(start&7)))))
-+ stop = start;
-+ }
-+ if (stop-start == size) {
-+ if (stop > *ptr_to_fblock)
-+ next_to_fblock = stop;
-+ else
-+ next_to_fblock = *ptr_to_fblock;
-+ ok = 1;
-+ } else ok = 0;
-+ }
-+
-+ /* forward search for 2 pass relocation */
-+ if (!ok && *ptr_fblock != *ptr_to_fblock) {
-+ start = stop = *ptr_fblock;
-+ while (stop < PED_BE16_TO_CPU(priv_data->mdb->total_blocks)
-+ && stop-start != size) {
-+ if ((priv_data->alloc_map[stop/8] & (1<<(7-(stop&7)))))
-+ start = stop + 1;
-+ ++stop;
-+ }
-+ ok = (stop-start == size);
-+ next_to_fblock = *ptr_to_fblock;
-+ }
-+
-+#endif
-+
-+ /* new non overlapping room has been found ? */
-+ if (ok) {
-+ /* enough room */
-+ unsigned int j;
-+
-+ block = (uint8_t*) ped_malloc(PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ * ((size<MAX_BUFF)?size:MAX_BUFF));
-+
-+ new_start = start;
-+
-+ /* move blocks */
-+ for (i = 0; i < size; /*i+=j*/) {
-+ PedSector abs_sector;
-+ unsigned int bit, byte;
-+ unsigned int to_bit, to_byte;
-+ unsigned int ai;
-+
-+ j = size - i; j = ((j < MAX_BUFF) ? j : MAX_BUFF);
-+ abs_sector = (PedSector) PED_BE16_TO_CPU (
-+ priv_data->mdb->start_block)
-+ + (PedSector) (*ptr_fblock + i)
-+ * (PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ if (!ped_geometry_read (fs->geom, block, abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE * j))
-+ return -1;
-+
-+ abs_sector = (PedSector) PED_BE16_TO_CPU (
-+ priv_data->mdb->start_block)
-+ + (PedSector) (new_start + i)
-+ * (PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+ if (!ped_geometry_write (fs->geom, block, abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE * j))
-+ return -1;
-+
-+ for (ai = i+j; i < ai; i++) {
-+ bit = 7 - ((*ptr_fblock + i) & 7);
-+ byte = (*ptr_fblock + i) / 8;
-+
-+ to_bit = 7 - ((new_start + i) & 7);
-+ to_byte = (new_start + i) / 8;
-+
-+ /* free source block */
-+ priv_data->alloc_map[byte] &= ~(1 << bit);
-+
-+ /* set dest block */
-+ priv_data->alloc_map[to_byte] |= (1 << to_bit);
-+ }
-+ }
-+
-+ /* save the allocation map */
-+ if (!ped_geometry_write(fs->geom, priv_data->alloc_map,
-+ PED_BE16_TO_CPU (
-+ priv_data->mdb->volume_bitmap_block),
-+ ( PED_BE16_TO_CPU (
-+ priv_data->mdb->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1)
-+ / (PED_SECTOR_SIZE * 8)))
-+ return -1;
-+
-+ ped_free (block);
-+
-+ *ptr_fblock += size;
-+ *ptr_to_fblock = next_to_fblock;
-+ } else {
-+ /* not enough room, but try to continue */
-+ new_start = *ptr_fblock;
-+ *ptr_fblock = *ptr_to_fblock = new_start + size;
-+ }
-+
-+ return new_start;
-+}
-+
-+/* Search an extent in the catalog file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_catalog (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsCatalogKey* catalog_key;
-+ HfsCatalog* catalog_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfs_file_read_sector (priv_data->catalog_file, node, 0))
-+ return -1;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfs_file_read_sector (priv_data->catalog_file, node,
-+ leaf_node))
-+ return -1;
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ /* fucking undocumented alignement powered by apple :p */
-+ unsigned int skip;
-+ catalog_key = (HfsCatalogKey*) (node + PED_BE16_TO_CPU(
-+ *((uint16_t *)(node+(PED_SECTOR_SIZE - 2*i)))));
-+ skip = (1 + catalog_key->key_length + 1) & ~1;
-+ catalog_data = (HfsCatalog*)(((uint8_t*)catalog_key)
-+ + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)catalog_data - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return -1;
-+ if (catalog_data->type != HFS_CAT_FILE) continue;
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (catalog_data
-+ ->sel.file.extents_data[j].block_count
-+ && PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_data[j].start_block)
-+ == (*ptr_fblock))
-+ goto catalog_data_found;
-+ if (catalog_data
-+ ->sel.file.extents_res[j].block_count
-+ && PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_res[j].start_block)
-+ == (*ptr_fblock))
-+ goto catalog_res_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ return 0;
-+
-+
-+ /* an extent part of a data fork has been found in the catalog file */
-+ catalog_data_found:
-+ new_start = hfs_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = PED_BE16_TO_CPU(catalog_data->sel.file
-+ .extents_data[j].start_block);
-+ catalog_data->sel.file.extents_data[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ /* write if any changes */
-+ if ((old_start != new_start)
-+ && !hfs_file_write_sector (priv_data->catalog_file,
-+ node, leaf_node))
-+ return -1;
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if (new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto catalog_data_found;
-+ }
-+ return 1;
-+ } else
-+ return -1;
-+
-+ /* an extent part of a resource fork has been found in the catalog file */
-+ catalog_res_found:
-+ new_start = hfs_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (catalog_data
-+ ->sel.file.extents_res[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = PED_BE16_TO_CPU(catalog_data->sel.file
-+ .extents_res[j].start_block);
-+ catalog_data->sel.file.extents_res[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ /* write if any changes */
-+ if ((old_start != new_start)
-+ && !hfs_file_write_sector (priv_data->catalog_file,
-+ node, leaf_node))
-+ return -1;
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if (new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto catalog_res_found;
-+ }
-+ return 1;
-+ } else
-+ return -1;
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsHeaderRecord* header;
-+ HfsNodeDescriptor* desc = (HfsNodeDescriptor*) node;
-+ HfsExtentKey* extent_key;
-+ HfsExtDescriptor* extent_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0;
-+
-+ /* Search the extent in the extent file */
-+ if (!hfs_file_read_sector (priv_data->extent_file, node, 0))
-+ return -1;
-+ header = ((HfsHeaderRecord*) (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE-2))))));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfs_file_read_sector (priv_data->extent_file, node,
-+ leaf_node))
-+ return -1;
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ extent_key = (HfsExtentKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*i)))));
-+ extent_data = (HfsExtDescriptor*)(((uint8_t*)extent_key)
-+ + sizeof (HfsExtentKey));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)extent_data - node
-+ >= PED_SECTOR_SIZE
-+ - 2 * (signed)(record_number+1)))
-+ return -1;
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (extent_data[j].block_count
-+ && PED_BE16_TO_CPU (
-+ extent_data[j].start_block)
-+ == (*ptr_fblock))
-+ goto extent_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the extents file */
-+ return 0;
-+
-+ /* an extent has been found in the extents file */
-+ extent_found:
-+ new_start = hfs_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (extent_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ int old_start;
-+ old_start = PED_BE16_TO_CPU(extent_data[j].start_block);
-+ extent_data[j].start_block = PED_CPU_TO_BE16 (new_start);
-+ /* This extent might have been cached into the file structure
-+ of the extent or catalog file */
-+ if (priv_data->catalog_file->cache[j].start_block ==
-+ PED_CPU_TO_BE16(old_start))
-+ memcpy (priv_data->catalog_file->cache, extent_data,
-+ sizeof (HfsExtDataRec));
-+ if (priv_data->extent_file->cache[j].start_block ==
-+ PED_CPU_TO_BE16(old_start))
-+ memcpy (priv_data->extent_file->cache, extent_data,
-+ sizeof (HfsExtDataRec));
-+ /* write if any changes */
-+ if ((old_start != new_start)
-+ && !hfs_file_write_sector (priv_data->extent_file, node,
-+ leaf_node))
-+ return -1;
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if (new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto extent_found;
-+ }
-+ return 1;
-+ } else
-+ return -1;
-+}
-+
-+/* Search an extent in the mdb and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_search_move_primary (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ unsigned int j;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0, from;
-+ int old_start;
-+
-+ /* Search an extent in the MDB */
-+ for (j = 0; j < HFS_EXT_NB; j++) {
-+ if (priv_data->mdb->extents_file_rec[j].block_count
-+ && PED_BE16_TO_CPU (priv_data->mdb->extents_file_rec[j]
-+ .start_block)
-+ == (*ptr_fblock))
-+ goto ext_file_found;
-+ if (priv_data->mdb->catalog_file_rec[j].block_count
-+ && PED_BE16_TO_CPU (priv_data->mdb->catalog_file_rec[j]
-+ .start_block)
-+ == (*ptr_fblock))
-+ goto cat_file_found;
-+ }
-+ return 0;
-+
-+ ext_file_found:
-+ new_start = hfs_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (priv_data->mdb
-+ ->extents_file_rec[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE16_TO_CPU(priv_data->mdb
-+ ->extents_file_rec[j].start_block);
-+ priv_data->mdb->extents_file_rec[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ memcpy (priv_data->extent_file->first,
-+ priv_data->mdb->extents_file_rec,
-+ sizeof (HfsExtDataRec));
-+ if (!priv_data->extent_file->start_cache)
-+ memcpy (priv_data->extent_file->cache,
-+ priv_data->extent_file->first,
-+ sizeof (HfsExtDataRec));
-+ from = 0;
-+ goto update_mdb;
-+ } else
-+ return -1;
-+
-+
-+ cat_file_found:
-+ new_start = hfs_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE16_TO_CPU (priv_data->mdb
-+ ->catalog_file_rec[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE16_TO_CPU(priv_data->mdb
-+ ->catalog_file_rec[j].start_block);
-+ priv_data->mdb->catalog_file_rec[j].start_block =
-+ PED_CPU_TO_BE16 (new_start);
-+ memcpy (priv_data->catalog_file->first,
-+ priv_data->mdb->catalog_file_rec,
-+ sizeof (HfsExtDataRec));
-+ if (!priv_data->catalog_file->start_cache)
-+ memcpy (priv_data->catalog_file->cache,
-+ priv_data->catalog_file->first,
-+ sizeof (HfsExtDataRec));
-+ from = 1;
-+ goto update_mdb;
-+ } else
-+ return -1;
-+
-+ update_mdb:
-+ if (!ped_geometry_read (fs->geom, node, 2, 1))
-+ return -1;
-+ memcpy (node, priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, node, 2, 1))
-+ return -1;
-+ if (!ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1))
-+ return -1;
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if (new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ if (from) goto cat_file_found; else goto ext_file_found;
-+ }
-+ return 1;
-+}
-+
-+/* This function moves an extent starting at block fblock to block to_fblock
-+ if there's enough room */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfs_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ int ret;
-+
-+ /* order = decreasing probability to be found */
-+ if ((ret = hfs_search_move_catalog (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfs_search_move_extent (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfs_search_move_primary (fs, ptr_fblock, ptr_to_fblock))) {
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves file's data to compact used and free space,
-+ starting at fblock block */
-+/* return 0 on error */
-+static int
-+hfs_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
-+ PedTimer* timer, unsigned int to_free)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ unsigned int to_fblock = fblock;
-+ unsigned int start = fblock;
-+ unsigned int div = PED_BE16_TO_CPU (mdb->total_blocks)
-+ + 1 - start - to_free;
-+ int byte, bit, ret;
-+ int to_byte, to_bit;
-+
-+ to_byte = byte = fblock / 8;
-+ to_bit = bit = 7 - (fblock & 7);
-+
-+ if (!hfs_read_bad_blocks (fs))
-+ return 0;
-+
-+ while (fblock < PED_BE16_TO_CPU (mdb->total_blocks)) {
-+ if (((priv_data->alloc_map[byte] >> bit) & 1)
-+ && (!hfs_is_bad_block (fs, fblock))) {
-+ if (!(ret = hfs_move_extent_starting_at (fs, &fblock,
-+ &to_fblock)))
-+ to_fblock = ++fblock;
-+ else if (ret == -1)
-+ return 0;
-+ } else {
-+ fblock++;
-+ }
-+
-+ byte = fblock / 8;
-+ bit = 7 - (fblock & 7);
-+
-+ to_byte = to_fblock / 8;
-+ to_bit = 7 - (to_fblock & 7);
-+
-+ ped_timer_update(timer, (float)(to_fblock - start)/div);
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function returns the first sector of the last free block of an
-+ HFS volume we can get after a hfs_pack_free_space_from_block call */
-+static PedSector
-+hfs_get_empty_end (const PedFileSystem *fs)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ HfsPrivateLinkExtent* link;
-+ unsigned int block, last_bad, end_free_blocks;
-+ int byte, bit;
-+
-+ /* find the next block to the last bad block of the volume */
-+ if (!hfs_read_bad_blocks (fs))
-+ return 0;
-+
-+ last_bad = 0;
-+ for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
-+ if ((unsigned int) PED_BE16_TO_CPU (link->extent.start_block)
-+ + PED_BE16_TO_CPU (link->extent.block_count) > last_bad)
-+ last_bad = PED_BE16_TO_CPU (link->extent.start_block)
-+ + PED_BE16_TO_CPU (link->extent.block_count);
-+ }
-+
-+ /* Count the free blocks from last_bad to the end of the volume */
-+ end_free_blocks = 0;
-+ for (block = last_bad;
-+ block < PED_BE16_TO_CPU (mdb->total_blocks);
-+ block++) {
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if (!((priv_data->alloc_map[byte]>>bit)&1))
-+ end_free_blocks++;
-+ }
-+
-+ /* Calculate the block that will by the first free at the
-+ end of the volume */
-+ block = PED_BE16_TO_CPU (mdb->total_blocks) - end_free_blocks;
-+
-+ return (PedSector) PED_BE16_TO_CPU (mdb->start_block)
-+ + (PedSector) block * (PED_BE32_TO_CPU (mdb->block_size)
-+ / PED_SECTOR_SIZE);
-+}
-+
-+/* return the block which should be used to pack data to have at
-+ least free fblock blocks at the end of the volume */
-+static unsigned int
-+hfs_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ unsigned int block;
-+
-+ for (block = PED_BE16_TO_CPU (priv_data->mdb->total_blocks) - 1;
-+ block && fblock;
-+ block--) {
-+ if (!((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ fblock--;
-+ }
-+
-+ while (block && !((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ block--;
-+ if ((priv_data->alloc_map[block / 8] >> (7 - (block & 7))) & 1)
-+ block++;
-+
-+ return block;
-+}
-+
-+static PedFileSystem*
-+hfs_open (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ PedFileSystem* fs;
-+ HfsMasterDirectoryBlock* mdb;
-+ HfsPrivateFSData* priv_data;
-+
-+ /* Read MDB */
- if (!ped_geometry_read (geom, buf, 2, 1))
-+ return NULL;
-+
-+ /* Allocate memory */
-+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
-+ mdb = (HfsMasterDirectoryBlock*) ped_malloc (
-+ sizeof (HfsMasterDirectoryBlock));
-+ priv_data = (HfsPrivateFSData*) ped_malloc (
-+ sizeof (HfsPrivateFSData));
-+
-+ memcpy (mdb, buf, sizeof (HfsMasterDirectoryBlock));
-+
-+ /* init structures */
-+ priv_data->mdb = mdb;
-+ priv_data->bad_blocks_loaded = 0;
-+ priv_data->bad_blocks_xtent_nb = 0;
-+ priv_data->bad_blocks_xtent_list = NULL;
-+ priv_data->extent_file =
-+ hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
-+ mdb->extents_file_rec,
-+ PED_CPU_TO_BE32 (mdb->extents_file_size)
-+ / PED_SECTOR_SIZE);
-+ priv_data->catalog_file =
-+ hfs_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
-+ mdb->catalog_file_rec,
-+ PED_CPU_TO_BE32 (mdb->catalog_file_size)
-+ / PED_SECTOR_SIZE);
-+
-+ /* Read allocation blocks */
-+ if (!ped_geometry_read(geom, priv_data->alloc_map,
-+ PED_BE16_TO_CPU (mdb->volume_bitmap_block),
-+ ( PED_BE16_TO_CPU (mdb->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 )
-+ / (PED_SECTOR_SIZE * 8) ) ) {
-+ hfs_file_close (priv_data->extent_file);
-+ hfs_file_close (priv_data->catalog_file);
-+ ped_free(fs); ped_free(mdb); ped_free(priv_data);
-+ return NULL;
-+ }
-+
-+ fs->type = &hfs_type;
-+ fs->geom = ped_geometry_duplicate (geom);
-+ fs->type_specific = (void*) priv_data;
-+ fs->checked = ( PED_BE16_TO_CPU (mdb->volume_attributes)
-+ >> HFS_UNMOUNTED ) & 1;
-+
-+ return fs;
-+}
-+
-+static int
-+hfs_close (PedFileSystem *fs)
-+{
-+ hfs_file_close (((HfsPrivateFSData*)(fs->type_specific))->extent_file);
-+ hfs_file_close (((HfsPrivateFSData*)(fs->type_specific))->catalog_file);
-+ if (((HfsPrivateFSData*)(fs->type_specific))->bad_blocks_loaded)
-+ hfs_free_bad_blocks_list (
-+ ((HfsPrivateFSData*)(fs->type_specific))
-+ ->bad_blocks_xtent_list);
-+ ped_free (((HfsPrivateFSData*)(fs->type_specific))->mdb);
-+ ped_free (fs->type_specific);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+
-+ return 1;
-+}
-+
-+static PedConstraint*
-+hfs_get_resize_constraint (const PedFileSystem *fs)
-+{
-+ PedDevice* dev = fs->geom->dev;
-+ PedAlignment start_align;
-+ PedGeometry start_sector;
-+ PedGeometry full_dev;
-+ PedSector min_size;
-+
-+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
-+ return NULL;
-+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
-+ return NULL;
-+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
-+ return NULL;
-+ /* 2 = last two sectors (alternate MDB and unused sector) */
-+ min_size = hfs_get_empty_end(fs) + 2;
-+
-+ return ped_constraint_new (&start_align, ped_alignment_any,
-+ &start_sector, &full_dev, min_size,
-+ fs->geom->length);
-+}
-+
-+static int
-+hfs_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ unsigned int nblock, nfree;
-+ unsigned int block, to_free;
-+ HfsPrivateFSData* priv_data = (HfsPrivateFSData*)
-+ fs->type_specific;
-+ HfsMasterDirectoryBlock* mdb = priv_data->mdb;
-+ int resize = 1;
-+ unsigned int hfs_sect_block = ( PED_BE32_TO_CPU (
-+ mdb->block_size)
-+ / PED_SECTOR_SIZE );
-+
-+
-+ /* check preconditions */
-+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
-+
-+ if (fs->geom->start != geom->start)
-+ {
-+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
-+ PED_EXCEPTION_CANCEL,
-+ _("Sorry, can't move the start of hfs partitions yet!"));
-+ return 0;
-+ }
-+
-+ if (geom->length > fs->geom->length
-+ || geom->length < hfs_get_empty_end(fs) + 2)
-+ return 0;
-+
-+ /* Clear the unmounted bit */
-+ mdb->volume_attributes &= PED_CPU_TO_BE16 (~( 1 << HFS_UNMOUNTED ));
-+ if (!ped_geometry_read (fs->geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, buf, 2, 1))
-+ return 0;
-+
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name(timer, _("shrinking"));
-+ ped_timer_update(timer, 0.0);
-+ /* relocate data */
-+ block = hfs_find_start_pack (fs, to_free =
-+ ( fs->geom->length - geom->length
-+ + hfs_sect_block - 1 )
-+ / hfs_sect_block );
-+ if (!hfs_pack_free_space_from_block (fs, block, timer, to_free)) {
-+ resize = 0;
-+ goto write_MDB;
-+ }
-+
-+ /* Calculate new block number and other MDB field */
-+ nblock = ( geom->length - (PED_BE16_TO_CPU (mdb->start_block) + 2) )
-+ / hfs_sect_block;
-+ nfree = PED_BE16_TO_CPU (mdb->free_blocks)
-+ - ( PED_BE16_TO_CPU (mdb->total_blocks) - nblock );
-+
-+ /* Check that all block after future end are really free */
-+ for (block = nblock;
-+ block < PED_BE16_TO_CPU (mdb->total_blocks);
-+ block++) {
-+ int byte, bit;
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if ((priv_data->alloc_map[byte]>>bit)&1) {
-+ resize = 0;
-+ goto write_MDB;
-+ }
-+ }
-+
-+ /* Update geometry */
-+ if (resize) {
-+ /* update in fs structure */
-+ if (PED_BE16_TO_CPU (mdb->next_allocation) >= nblock)
-+ mdb->next_allocation = PED_CPU_TO_BE16 (0);
-+ mdb->total_blocks = PED_CPU_TO_BE16 (nblock);
-+ mdb->free_blocks = PED_CPU_TO_BE16 (nfree);
-+ /* update parted structure */
-+ fs->geom->length = geom->length;
-+ fs->geom->end = fs->geom->start + geom->length - 1;
-+ }
-+
-+ /* Set the unmounted bit */
-+ mdb->volume_attributes |= PED_CPU_TO_BE16 ( 1 << HFS_UNMOUNTED );
-+
-+ /* Effective write */
-+ write_MDB:
-+ ped_timer_set_state_name(timer,_("writing HFS Master Directory Block"));
-+ if (!ped_geometry_read (fs->geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, buf, 2, 1))
-+ return 0;
-+ if (!ped_geometry_write (fs->geom, buf, fs->geom->length - 2, 1))
-+ return 0;
-+ ped_timer_update(timer, 1.0);
-+
-+ return (resize);
-+}
-+
-+/* ----- HFS+ ----- */
-+
-+/* Open the data fork of a file with its first eight extents and its CNID */
-+static HfsPPrivateFile*
-+hfsplus_file_open (PedFileSystem *fs, HfsPNodeID CNID,
-+ HfsPExtDataRec ext_desc, PedSector sect_nb)
-+{
-+ HfsPPrivateFile* file;
-+
-+ file = (HfsPPrivateFile*) ped_malloc (sizeof (HfsPPrivateFile));
-+
-+ file->fs = fs;
-+ file->sect_nb = sect_nb;
-+ file->CNID = CNID;
-+ memcpy(file->first, ext_desc, sizeof (HfsPExtDataRec));
-+ memcpy(file->cache, ext_desc, sizeof (HfsPExtDataRec));
-+ file->start_cache = 0;
-+
-+ return file;
-+}
-+
-+/* Close an HFS+ file */
-+static void
-+hfsplus_file_close (HfsPPrivateFile* file)
-+{
-+ ped_free (file);
-+}
-+
-+/* declaration of hfsplus_file_read(_sector)
-+ because it's used by hfsplus_btree_search (indirect recursion) */
-+static int
-+hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector);
-+static int
-+hfsplus_file_read(HfsPPrivateFile* file, void *buf,
-+ PedSector sector, unsigned int nb);
-+
-+/* do a B-Tree lookup */
-+/* read the first record immediatly inferior or egal to the given key */
-+/* return 0 on error */
-+/* record_out _must_ be large enough to receive the whole record (key + data) */
-+static int
-+hfsplus_btree_search (HfsPPrivateFile* b_tree_file, HfsPPrivateGenericKey* key,
-+ void *record_out, unsigned int record_size,
-+ HfsCPrivateLeafRec* record_ref)
-+{
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPPrivateGenericKey* record_key = NULL;
-+ unsigned int node_number, record_number, size, bsize;
-+ int i;
-+
-+ /* Read the header node */
-+ if (!hfsplus_file_read_sector(b_tree_file, node_1, 0))
-+ return 0;
-+ header = (HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC);
-+
-+ /* Get the node number of the root */
-+ node_number = PED_BE32_TO_CPU (header->root_node);
-+
-+ /* Get the size of a node in sectors and allocate buffer */
-+ size = (bsize = PED_BE16_TO_CPU (header->node_size)) / PED_SECTOR_SIZE;
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ /* Read the root node */
-+ if (!hfsplus_file_read (b_tree_file, node,
-+ (PedSector) node_number * size, size))
-+ return 0;
-+
-+ /* Follow the white rabbit */
-+ while (1) {
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = record_number; i; i--) {
-+ int cmp, min_length;
-+
-+ record_key = (HfsPPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)record_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)record_key - node
-+ >= (signed)bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return 0;
-+ }
-+ min_length = ((PED_BE16_TO_CPU(key->key_length)
-+ >PED_BE16_TO_CPU(record_key->key_length))?
-+ PED_BE16_TO_CPU(record_key->key_length) :
-+ PED_BE16_TO_CPU(key->key_length) );
-+ cmp = memcmp (record_key->key_content, key->key_content,
-+ min_length);
-+ if (cmp < 0 || ( cmp == 0 && PED_BE16_TO_CPU (
-+ record_key->key_length)
-+ <= PED_BE16_TO_CPU (
-+ key->key_length)))
-+ break;
-+ }
-+ if (!i) { ped_free (node); return 0; }
-+ if (desc->type == HFS_IDX_NODE) {
-+ unsigned int skip;
-+
-+ skip = ( 2 + PED_BE16_TO_CPU (record_key->key_length)
-+ + 1 ) & ~1;
-+ node_number = PED_BE32_TO_CPU (*((uint32_t *)
-+ (((uint8_t *) record_key) + skip)));
-+ if (!hfsplus_file_read(b_tree_file, node,
-+ (PedSector) node_number * size,
-+ size)) {
-+ ped_free (node);
-+ return 0;
-+ }
-+ } else
-+ break;
-+ }
-+
-+ /* copy the result if needed */
-+ if (record_size)
-+ memcpy (record_out, record_key, record_size);
-+
-+ /* send record reference if needed */
-+ if (record_ref) {
-+ record_ref->node_size = size; /* in sectors */
-+ record_ref->node_number = node_number;
-+ record_ref->record_pos = (uint8_t*)record_key - node;
-+ record_ref->record_number = i;
-+ }
-+
-+ /* success */
-+ ped_free (node);
-+ return 1;
-+}
-+
-+static int
-+hfsplus_get_extent_containing (HfsPPrivateFile* file, unsigned int block,
-+ HfsPExtDataRec cache, uint32_t* ptr_start_cache)
-+{
-+ uint8_t record[sizeof (HfsPExtentKey)
-+ + sizeof (HfsPExtDataRec)];
-+ HfsPExtentKey search;
-+ HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
-+ HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
-+ (record + sizeof (HfsPExtentKey));
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+
-+
-+ search.key_length = PED_CPU_TO_BE16 (sizeof (HfsPExtentKey) - 2);
-+ search.type = HFS_DATA_FORK;
-+ search.pad = 0;
-+ search.file_ID = file->CNID;
-+ search.start = PED_CPU_TO_BE32 (block);
-+
-+ if (!hfsplus_btree_search (priv_data->extents_file,
-+ (HfsPPrivateGenericKey*) &search,
-+ record, sizeof (record), NULL))
-+ return 0;
-+
-+ if (ret_key->file_ID != search.file_ID || ret_key->type != search.type)
-+ return 0;
-+
-+ memcpy (cache, ret_cache, sizeof(HfsPExtDataRec));
-+ *ptr_start_cache = PED_BE32_TO_CPU (ret_key->start);
-+
-+ return 1;
-+}
-+
-+/* find the nth sector of a file */
-+/* return 0 on error */
-+static PedSector
-+hfsplus_file_find_sector (HfsPPrivateFile* file, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data-> vh;
-+ unsigned int i, s, vol_block;
-+ unsigned int block = sector
-+ / ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ unsigned int offset = sector
-+ % ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+
-+ /* in the three first extent */
-+ for (s = 0, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->first[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->first[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->first[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->cache[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ /* update cache */
-+ if (!hfsplus_get_extent_containing (file, block, file->cache,
-+ &(file->start_cache)))
- return 0;
-
-- if (PED_BE16_TO_CPU (*(uint16_t*) buf) == HFS_SIGNATURE)
-- return ped_geometry_duplicate (geom);
-- else
-+ /* in the three cached extent */
-+ for (s = file->start_cache, i = 0;
-+ i < HFSP_EXT_NB;
-+ i++, s += PED_BE32_TO_CPU (file->cache[i].block_count)) {
-+ if ((block >= s) && (block < s + PED_BE32_TO_CPU (
-+ file->cache[i].block_count))) {
-+ vol_block = (block - s)
-+ + PED_BE32_TO_CPU (file->cache[i]
-+ .start_block);
-+ goto plus_sector_found;
-+ }
-+ }
-+
-+ return 0;
-+
-+ plus_sector_found:
-+ return (PedSector) vol_block * ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) + offset;
-+}
-+
-+/* Read the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfsplus_file_read_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfsplus_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_read (priv_data->plus_geom, buf,
-+ abs_sector, 1);
-+}
-+
-+static int
-+hfsplus_file_read(HfsPPrivateFile* file, void *buf, PedSector sector,
-+ unsigned int nb)
-+{
-+ while (nb) {
-+ if (!hfsplus_file_read_sector (file, buf, sector))
-+ return 0;
-+
-+ buf += PED_SECTOR_SIZE;
-+ nb--;
-+ sector++;
-+ }
-+
-+ return 1;
-+}
-+
-+/* Write the nth sector of a file */
-+/* return 0 on error */
-+static int
-+hfsplus_file_write_sector (HfsPPrivateFile* file, void *buf, PedSector sector)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ file->fs->type_specific;
-+ PedSector abs_sector;
-+
-+ if (sector >= file->sect_nb)
-+ return 0;
-+
-+ abs_sector = hfsplus_file_find_sector (file, sector);
-+ return abs_sector && ped_geometry_write (priv_data->plus_geom, buf,
-+ abs_sector, 1);
-+}
-+
-+static int
-+hfsplus_file_write (HfsPPrivateFile* file, void *buf, PedSector sector,
-+ unsigned int nb)
-+{
-+ while (nb) {
-+ if (!hfsplus_file_write_sector (file, buf, sector))
-+ return 0;
-+
-+ buf += PED_SECTOR_SIZE;
-+ nb--;
-+ sector++;
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function reads bad blocks extents in the extents file
-+ and store it in f.s. specific data of fs */
-+static int
-+hfsplus_read_bad_blocks (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (!priv_data->bad_blocks_loaded) {
-+ uint8_t record[sizeof (HfsPExtentKey)
-+ + sizeof (HfsPExtDataRec)];
-+ HfsPExtentKey search;
-+ HfsPExtentKey* ret_key = (HfsPExtentKey*) record;
-+ HfsPExtDescriptor* ret_cache = (HfsPExtDescriptor*)
-+ (record + sizeof (HfsPExtentKey));
-+ int block, first_pass = 1;
-+ unsigned int last_start;
-+
-+ search.key_length = sizeof (HfsExtentKey) - 2;
-+ search.type = HFS_DATA_FORK;
-+ search.pad = 0;
-+ search.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+
-+ last_start = -1; block = 0;
-+ while (1) {
-+ int i;
-+
-+ search.start = PED_CPU_TO_BE32 (block);
-+ if (!hfsplus_btree_search (priv_data->extents_file,
-+ (HfsPPrivateGenericKey*)
-+ &search,
-+ record, sizeof (record),
-+ NULL)) {
-+ if (first_pass)
-+ break;
-+ else
-+ return 0;
-+ }
-+ if (ret_key->file_ID != search.file_ID
-+ || ret_key->type != search.type)
-+ break;
-+ if (PED_BE32_TO_CPU (ret_key->start) == last_start)
-+ break;
-+
-+ last_start = PED_BE32_TO_CPU (ret_key->start);
-+ for (i = 0; i < HFSP_EXT_NB; i++) {
-+ if (ret_cache[i].block_count) {
-+ HfsPPrivateLinkExtent* new_xt =
-+ (HfsPPrivateLinkExtent*) ped_malloc (
-+ sizeof (HfsPPrivateLinkExtent));
-+ new_xt->next =
-+ priv_data->bad_blocks_xtent_list;
-+ memcpy (&(new_xt->extent), ret_cache+i,
-+ sizeof (HfsPExtDescriptor));
-+ priv_data->bad_blocks_xtent_list =
-+ new_xt;
-+ priv_data->bad_blocks_xtent_nb++;
-+ block += PED_BE32_TO_CPU (ret_cache[i]
-+ .block_count);
-+ }
-+ }
-+ first_pass = 0;
-+ }
-+
-+ priv_data->bad_blocks_loaded = 1;
-+ }
-+
-+ return 1;
-+}
-+
-+/* free the bad blocks linked list */
-+static void
-+hfsplus_free_bad_blocks_list(HfsPPrivateLinkExtent* first)
-+{
-+ HfsPPrivateLinkExtent* next;
-+
-+ while (first) {
-+ next = first->next;
-+ ped_free (first);
-+ first = next;
-+ }
-+}
-+
-+/* This function check if fblock is a bad block */
-+static int
-+hfsplus_is_bad_block (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPPrivateLinkExtent* walk;
-+
-+ for (walk = priv_data->bad_blocks_xtent_list; walk; walk = walk->next) {
-+ /* Won't compile without the strange cast ! gcc bug ? */
-+ /* or maybe C subtilties... */
-+ if ((fblock >= PED_BE32_TO_CPU (walk->extent.start_block)) &&
-+ (fblock < (unsigned int)(PED_BE32_TO_CPU (
-+ walk->extent.start_block)
-+ + PED_BE32_TO_CPU (walk->extent.block_count))))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+hfsplus_close (PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+
-+ if (priv_data->wrapper) hfs_close(priv_data->wrapper);
-+ if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
-+ ped_free(priv_data->alloc_map);
-+ hfsplus_file_close (priv_data->extents_file);
-+ hfsplus_file_close (priv_data->catalog_file);
-+ hfsplus_file_close (priv_data->attributes_file);
-+ if (priv_data->bad_blocks_loaded)
-+ hfsplus_free_bad_blocks_list(priv_data->bad_blocks_xtent_list);
-+ ped_free (priv_data->vh);
-+ ped_free (priv_data);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+
-+ return 1;
-+}
-+
-+static PedFileSystem*
-+hfsplus_open (PedGeometry* geom)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ PedFileSystem* fs;
-+ HfsPVolumeHeader* vh;
-+ HfsPPrivateFSData* priv_data;
-+ PedGeometry* wrapper_geom;
-+ HfsPPrivateFile* allocation_file;
-+ unsigned int map_sectors;
-+
-+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
-+ vh = (HfsPVolumeHeader*) ped_malloc (sizeof (HfsPVolumeHeader));
-+ priv_data = (HfsPPrivateFSData*)ped_malloc (sizeof (HfsPPrivateFSData));
-+
-+ fs->geom = ped_geometry_duplicate (geom);
-+ fs->type_specific = (void*) priv_data;
-+
-+ if ((wrapper_geom = hfs_and_wrapper_probe (geom))) {
-+ HfsPrivateFSData* hfs_priv_data;
-+ PedSector abs_sect, length;
-+ unsigned int bs;
-+
-+ ped_geometry_destroy (wrapper_geom);
-+ priv_data->wrapper = hfs_open(geom);
-+ hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ bs = PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+ abs_sect = (PedSector) geom->start
-+ + (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->start_block)
-+ + (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.start_block )
-+ * bs;
-+ length = (PedSector) PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count)
-+ * bs;
-+ priv_data->plus_geom = ped_geometry_new (geom->dev, abs_sect,
-+ length);
-+ priv_data->free_geom = 1;
-+ } else {
-+ priv_data->wrapper = NULL;
-+ priv_data->plus_geom = fs->geom;
-+ priv_data->free_geom = 0;
-+ }
-+
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1)) {
-+ if (priv_data->wrapper)
-+ hfs_close(priv_data->wrapper);
-+ if (priv_data->free_geom)
-+ ped_geometry_destroy (priv_data->plus_geom);
-+ ped_free (vh);
-+ ped_free (priv_data);
-+ ped_geometry_destroy (fs->geom);
-+ ped_free (fs);
-+ return NULL;
-+ }
-+
-+ memcpy (vh, buf, sizeof (HfsPVolumeHeader));
-+
-+ priv_data->vh = vh;
-+ priv_data->bad_blocks_loaded = 0;
-+ priv_data->bad_blocks_xtent_nb = 0;
-+ priv_data->bad_blocks_xtent_list = NULL;
-+ priv_data->extents_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
-+ vh->extents_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->extents_file.logical_size )
-+ / PED_SECTOR_SIZE);
-+ priv_data->catalog_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
-+ vh->catalog_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->catalog_file.logical_size )
-+ / PED_SECTOR_SIZE);
-+ priv_data->attributes_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ATTRIB_ID),
-+ vh->attributes_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->attributes_file.logical_size)
-+ / PED_SECTOR_SIZE);
-+ map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 ) / (PED_SECTOR_SIZE * 8);
-+ priv_data->alloc_map = (uint8_t*)
-+ ped_malloc (map_sectors * PED_SECTOR_SIZE);
-+
-+ allocation_file =
-+ hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
-+ vh->allocation_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->allocation_file.logical_size)
-+ / PED_SECTOR_SIZE);
-+ if (!hfsplus_file_read (allocation_file, priv_data->alloc_map, 0,
-+ map_sectors)) {
-+ hfsplus_file_close (allocation_file);
-+ hfsplus_close(fs);
- return NULL;
-+ }
-+ hfsplus_file_close (allocation_file);
-+
-+ fs->type = &hfsplus_type;
-+ fs->checked = ((PED_BE32_TO_CPU (vh->attributes) >> HFS_UNMOUNTED) & 1)
-+ && !((PED_BE32_TO_CPU (vh->attributes) >> HFSP_INCONSISTENT) & 1);
-+
-+ return fs;
- }
-
--#ifndef DISCOVER_ONLY
-+/* This function moves data of size blocks starting at block *ptr_fblock
-+ to block *ptr_to_fblock */
-+/* return new start or -1 on failure */
- static int
--hfs_clobber (PedGeometry* geom)
-+hfsplus_effect_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock, unsigned int size)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t* block;
-+ unsigned int i;
-+ unsigned int new_start;
-+ unsigned int next_to_fblock = 0;
-+ unsigned int start = 0, stop = 0;
-+ int ok = 0;
-+
-+#if 0
-+
-+ /* try to find enough room to fit the extent */
-+ /* TODO : without overwriting some data */
-+ for (i = *ptr_to_fblock;
-+ i < *ptr_to_fblock + size && i < *ptr_fblock;
-+ i++) {
-+ if (hfsplus_is_bad_block (fs, i))
-+ *ptr_to_fblock = i+1;
-+ }
-+
-+#else
-+
-+ /* try to find enough room to fit the extent in a non overlapping way */
-+
-+ /* special case of next if, keep it only if it increases speed in a
-+ significant way */
-+ if (*ptr_to_fblock + size <= *ptr_fblock) {
-+ ok = 1;
-+ for (i = *ptr_to_fblock; ok && i < *ptr_to_fblock; i++)
-+ if ((priv_data->alloc_map[i/8] & (1<<(7-(i&7))))) ok = 0;
-+ next_to_fblock = *ptr_to_fblock + size;
-+ start = *ptr_to_fblock;
-+ }
-+
-+ /* back search */
-+ if (!ok && *ptr_fblock != *ptr_to_fblock) {
-+ start = stop = *ptr_fblock;
-+ while (start && stop-start != size) {
-+ --start;
-+ if ((priv_data->alloc_map[start/8] & (1<<(7-(start&7)))))
-+ stop = start;
-+ }
-+ if (stop-start == size) {
-+ if (stop > *ptr_to_fblock)
-+ next_to_fblock = stop;
-+ else
-+ next_to_fblock = *ptr_to_fblock;
-+ ok = 1;
-+ } else ok = 0;
-+ }
-+
-+ /* forward search for 2 pass relocation */
-+ if (!ok && *ptr_fblock != *ptr_to_fblock) {
-+ start = stop = *ptr_fblock;
-+ while (stop < PED_BE32_TO_CPU(priv_data->vh->total_blocks)
-+ && stop-start != size) {
-+ if ((priv_data->alloc_map[stop/8] & (1<<(7-(stop&7)))))
-+ start = stop + 1;
-+ ++stop;
-+ }
-+ ok = (stop-start == size);
-+ next_to_fblock = *ptr_to_fblock;
-+ }
-+
-+#endif
-+
-+ if (ok) {
-+ /* enough room */
-+ unsigned int j;
-+
-+ block = (uint8_t*) ped_malloc(PED_BE32_TO_CPU (
-+ priv_data->vh->block_size)
-+ *((size<MAX_BUFF)?size:MAX_BUFF));
-+
-+ new_start = start;
-+
-+ /* move blocks */
-+ for (i = 0; i < size; /*i++*/) {
-+ PedSector abs_sector;
-+ unsigned int bit, byte;
-+ unsigned int to_bit, to_byte;
-+ unsigned int ai;
-+
-+ j = size - i; j = ((j < MAX_BUFF) ? j : MAX_BUFF);
-+ abs_sector = (PedSector) (*ptr_fblock + i)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ if (!ped_geometry_read (priv_data->plus_geom, block,
-+ abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->block_size )
-+ / PED_SECTOR_SIZE * j))
-+ return -1;
-+
-+ abs_sector = (PedSector) (new_start + i)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ if (!ped_geometry_write (priv_data->plus_geom, block,
-+ abs_sector,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->block_size )
-+ / PED_SECTOR_SIZE * j))
-+ return -1;
-+
-+ for (ai = i+j; i < ai; i++) {
-+ bit = 7 - ((*ptr_fblock + i) & 7);
-+ byte = (*ptr_fblock + i) / 8;
-+
-+ to_bit = 7 - ((new_start + i) & 7);
-+ to_byte = (new_start + i) / 8;
-+
-+ /* free source block */
-+ priv_data->alloc_map[byte] &= ~(1 << bit);
-+
-+ /* set dest block */
-+ priv_data->alloc_map[to_byte] |= (1 << to_bit);
-+ }
-+ }
-+
-+/* TODO : a better handling of allocation map saving process */
-+#if 0
-+ /* save the allocation map */
-+ if (!ped_geometry_write(fs->geom, priv_data->alloc_map, PED_BE16_TO_CPU (priv_data->mdb->volume_bitmap_block),
-+ (PED_BE16_TO_CPU (priv_data->mdb->total_blocks) + PED_SECTOR_SIZE * 8 - 1) / (PED_SECTOR_SIZE * 8)))
-+ return -1;
-+#endif
-+
-+ ped_free (block);
-+
-+ *ptr_fblock += size;
-+ *ptr_to_fblock = next_to_fblock;
-+ } else {
-+ /* not enough room */
-+ new_start = *ptr_fblock;
-+ *ptr_fblock = *ptr_to_fblock = new_start + size;
-+ }
-+
-+ return new_start;
-+}
-+
-+/* Search an extent in the catalog file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_catalog (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPCatalogKey* catalog_key;
-+ HfsPCatalog* catalog_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfsplus_file_read_sector (priv_data->catalog_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ unsigned int skip;
-+ catalog_key = (HfsPCatalogKey*)
-+ ( node + PED_BE16_TO_CPU (*((uint16_t *)
-+ (node+(bsize - 2*i)))) );
-+ skip = ( 2 + PED_BE16_TO_CPU (catalog_key->key_length)
-+ + 1) & ~1;
-+ catalog_data = (HfsPCatalog*)
-+ (((uint8_t*)catalog_key) + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)catalog_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)catalog_data - node
-+ >= (signed) bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ if (PED_BE16_TO_CPU(catalog_data->type)!=HFS_CAT_FILE)
-+ continue;
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( catalog_data->sel.file
-+ .data_fork.extents[j].block_count
-+ && PED_BE32_TO_CPU (catalog_data->sel
-+ .file.data_fork.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_catalog_data_found;
-+ if ( catalog_data->sel.file.res_fork
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (catalog_data->sel
-+ .file.res_fork.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_catalog_res_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ ped_free (node);
-+ return 0;
-+
-+
-+ /* an extent part of a data fork has been found in the catalog file */
-+ plus_catalog_data_found:
-+ new_start = hfsplus_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ catalog_data->sel.file
-+ .data_fork.extents[j]
-+ .block_count ));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = PED_BE32_TO_CPU (catalog_data->sel.file.data_fork
-+ .extents[j].start_block);
-+ catalog_data->sel.file.data_fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned int) new_start)
-+ && !hfsplus_file_write (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if ((unsigned) new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto plus_catalog_data_found;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+
-+ /* an extent part of a resource fork has been found
-+ in the catalog file */
-+ plus_catalog_res_found:
-+ new_start = hfsplus_effect_move_extent (fs, src_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ catalog_data->sel.file
-+ .res_fork.extents[j]
-+ .block_count ));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = PED_BE32_TO_CPU (catalog_data->sel.file.res_fork
-+ .extents[j].start_block);
-+ catalog_data->sel.file.res_fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned int) new_start)
-+ && !hfsplus_file_write (priv_data->catalog_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if ((unsigned) new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto plus_catalog_res_found;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the attributes file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_attributes (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node_1;
-+ HfsPPrivateGenericKey* generic_key;
-+ HfsPForkDataAttr* fork_ext_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0;
-+
-+ /* attributes file is facultative */
-+ if (!priv_data->attributes_file->sect_nb)
-+ return 0;
-+
-+ /* Search the extent starting at *ptr_block in the catalog file */
-+ if (!hfsplus_file_read_sector (priv_data->attributes_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-+
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ unsigned int skip;
-+ generic_key = (HfsPPrivateGenericKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ skip = ( 2 + PED_BE16_TO_CPU (generic_key->key_length)
-+ + 1 ) & ~1;
-+ fork_ext_data = (HfsPForkDataAttr*)
-+ (((uint8_t*)generic_key) + skip);
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)generic_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)fork_ext_data - node
-+ >= (signed) bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ if ( PED_BE32_TO_CPU (fork_ext_data->record_type )
-+ == HFSP_ATTR_FORK) {
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( fork_ext_data->fork_res.fork
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .fork.extents[j].start_block )
-+ == (*ptr_fblock) )
-+ goto plus_attr_fork_found;
-+ }
-+ } else if ( PED_BE32_TO_CPU (fork_ext_data->record_type)
-+ == HFSP_ATTR_EXTENTS ) {
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( fork_ext_data->fork_res
-+ .extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_attr_ext_found;
-+ }
-+ } else continue;
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the catalog file */
-+ ped_free (node);
-+ return 0;
-+
-+
-+ /* an extent part of a attr fork has been found in the catalog file */
-+ plus_attr_fork_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .fork.extents[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = PED_BE32_TO_CPU (fork_ext_data->fork_res.fork.
-+ extents[j].start_block);
-+ fork_ext_data->fork_res.fork.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) new_start)
-+ && !hfsplus_file_write (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if ((unsigned) new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto plus_attr_fork_found;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+
-+ /* an extent part of a attr ext has been found in the catalog file */
-+ plus_attr_ext_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ fork_ext_data->fork_res
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = PED_BE32_TO_CPU(fork_ext_data->fork_res
-+ .extents[j].start_block);
-+ fork_ext_data->fork_res.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ /* write if any changes */
-+ if ((old_start != (unsigned) new_start)
-+ && !hfsplus_file_write (priv_data->attributes_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if ((unsigned) new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto plus_attr_ext_found;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the extent file and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_extent (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
- {
-- char buf[512];
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node_1[PED_SECTOR_SIZE];
-+ uint8_t* node;
-+ HfsPHeaderRecord* header;
-+ HfsPNodeDescriptor* desc = (HfsPNodeDescriptor*) node;
-+ HfsPExtentKey* extent_key;
-+ HfsPExtDescriptor* extent_data;
-+ unsigned int leaf_node, record_number;
-+ unsigned int i, j, size, bsize;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0;
-+
-+ /* Search the extent in the extent file */
-+ if (!hfsplus_file_read_sector (priv_data->extents_file, node_1, 0))
-+ return -1;
-+ header = ((HfsPHeaderRecord*) (node_1 + HFS_FIRST_REC));
-+ leaf_node = PED_BE32_TO_CPU (header->first_leaf_node);
-+ bsize = PED_BE16_TO_CPU (header->node_size);
-+ size = bsize / PED_SECTOR_SIZE;
-
-- memset (buf, 0, 512);
-- return ped_geometry_write (geom, buf, 2, 1);
-+ node = (uint8_t*) ped_malloc (bsize);
-+ desc = (HfsPNodeDescriptor*) node;
-+
-+ for (; leaf_node; leaf_node = PED_BE32_TO_CPU (desc->next)) {
-+ if (!hfsplus_file_read (priv_data->extents_file, node,
-+ (PedSector) leaf_node * size, size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ record_number = PED_BE16_TO_CPU (desc->rec_nb);
-+ for (i = 1; i <= record_number; i++) {
-+ extent_key = (HfsPExtentKey*)
-+ (node + PED_BE16_TO_CPU(*((uint16_t *)
-+ (node+(bsize - 2*i)))));
-+ extent_data = (HfsPExtDescriptor*)
-+ (((uint8_t*)extent_key) + sizeof (HfsPExtentKey));
-+ /* check for obvious error in FS */
-+ if (((uint8_t*)extent_key - node < HFS_FIRST_REC)
-+ || ((uint8_t*)extent_data - node
-+ >= (signed)bsize
-+ - 2 * (signed)(record_number+1))) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( extent_data[j].block_count
-+ && PED_BE32_TO_CPU (
-+ extent_data[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_extent_found;
-+ }
-+ }
-+ }
-+ /* no extent starting a *ptr_block has been found in the extents file */
-+ ped_free (node);
-+ return 0;
-+
-+ /* an extent has been found in the extents file */
-+ plus_extent_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ extent_data[j]
-+ .block_count));
-+ if (new_start != -1) {
-+ unsigned int old_start;
-+ old_start = PED_BE32_TO_CPU(extent_data[j].start_block);
-+ extent_data[j].start_block = PED_CPU_TO_BE32 (new_start);
-+ /* This extent might have been cached into the file structure
-+ of the extent or catalog file */
-+ if (priv_data->catalog_file->cache[j].start_block
-+ == PED_CPU_TO_BE32(old_start))
-+ memcpy (priv_data->catalog_file->cache, extent_data,
-+ sizeof (HfsPExtDataRec));
-+ if (priv_data->extents_file->cache[j].start_block
-+ == PED_CPU_TO_BE32(old_start))
-+ memcpy (priv_data->extents_file->cache, extent_data,
-+ sizeof (HfsPExtDataRec));
-+ if (priv_data->attributes_file->cache[j].start_block
-+ == PED_CPU_TO_BE32(old_start))
-+ memcpy (priv_data->attributes_file->cache,
-+ extent_data, sizeof (HfsPExtDataRec));
-+ /* write if any changes */
-+ if ((old_start != (unsigned) new_start)
-+ && !hfsplus_file_write (priv_data->extents_file, node,
-+ (PedSector) leaf_node * size,
-+ size)) {
-+ ped_free (node);
-+ return -1;
-+ }
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if ((unsigned) new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ goto plus_extent_found;
-+ }
-+ ped_free (node);
-+ return 1;
-+ } else {
-+ ped_free (node);
-+ return -1;
-+ }
-+}
-+
-+/* Search an extent in the VH and move it if found */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_search_move_primary (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ uint8_t node[PED_SECTOR_SIZE];
-+ unsigned int j;
-+ unsigned int* src_fblock = ptr_fblock;
-+ int new_start, pass2 = 0;
-+ unsigned int old_start, from;
-+
-+ /* Search an extent in the VH */
-+ for (j = 0; j < HFSP_EXT_NB; j++) {
-+ if ( priv_data->vh->extents_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->extents_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_ext_file_found;
-+ if ( priv_data->vh->catalog_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->catalog_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_cat_file_found;
-+ if ( priv_data->vh->allocation_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->allocation_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_alloc_file_found;
-+ if ( priv_data->vh->attributes_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->attributes_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_attrib_file_found;
-+ if ( priv_data->vh->startup_file.extents[j].block_count
-+ && PED_BE32_TO_CPU (
-+ priv_data->vh->startup_file.extents[j].start_block)
-+ == (*ptr_fblock) )
-+ goto plus_start_file_found;
-+ }
-+ return 0;
-+
-+ plus_start_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->startup_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE32_TO_CPU(priv_data->vh->startup_file
-+ .extents[j].start_block);
-+ priv_data->vh->startup_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+#if 0
-+ memcpy (priv_data->startup_file->first, priv_data->vh->startup_file.extents, sizeof (HfsPExtDataRec));
-+ if (!priv_data->startup_file->start_cache)
-+ memcpy (priv_data->startup_file->cache, priv_data->startup_file->first, sizeof (HfsPExtDataRec));
-+#endif
-+ from = 0; goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_attrib_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh
-+ ->attributes_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE32_TO_CPU(priv_data->vh->attributes_file
-+ .extents[j].start_block);
-+ priv_data->vh->attributes_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->attributes_file->first,
-+ priv_data->vh->attributes_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->attributes_file->start_cache)
-+ memcpy (priv_data->attributes_file->cache,
-+ priv_data->attributes_file->first,
-+ sizeof (HfsPExtDataRec));
-+ from = 1; goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_alloc_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh
-+ ->allocation_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE32_TO_CPU(priv_data->vh->allocation_file
-+ .extents[j].start_block);
-+ priv_data->vh->allocation_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+#if 0
-+ memcpy (priv_data->allocation_file->first, priv_data->vh->allocation_file.extents, sizeof (HfsPExtDataRec));
-+ if (!priv_data->allocation_file->start_cache)
-+ memcpy (priv_data->allocation_file->cache, priv_data->allocation_file->first, sizeof (HfsPExtDataRec));
-+#endif
-+ from = 2; goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_ext_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->extents_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE32_TO_CPU(priv_data->vh->extents_file
-+ .extents[j].start_block);
-+ priv_data->vh->extents_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->extents_file->first,
-+ priv_data->vh->extents_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->extents_file->start_cache)
-+ memcpy (priv_data->extents_file->cache,
-+ priv_data->extents_file->first,
-+ sizeof (HfsPExtDataRec));
-+ from = 3; goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_cat_file_found:
-+ new_start = hfsplus_effect_move_extent (fs, ptr_fblock, ptr_to_fblock,
-+ PED_BE32_TO_CPU (
-+ priv_data->vh->catalog_file
-+ .extents[j].block_count));
-+ if (new_start != -1) {
-+ old_start = PED_BE32_TO_CPU(priv_data->vh->catalog_file
-+ .extents[j].start_block);
-+ priv_data->vh->catalog_file.extents[j].start_block =
-+ PED_CPU_TO_BE32 (new_start);
-+ memcpy (priv_data->catalog_file->first,
-+ priv_data->vh->catalog_file.extents,
-+ sizeof (HfsPExtDataRec));
-+ if (!priv_data->catalog_file->start_cache)
-+ memcpy (priv_data->catalog_file->cache,
-+ priv_data->catalog_file->first,
-+ sizeof (HfsPExtDataRec));
-+ from = 4; goto plus_update_vh;
-+ } else
-+ return -1;
-+
-+ plus_update_vh:
-+ if (!ped_geometry_read (priv_data->plus_geom, node, 2, 1))
-+ return -1;
-+ memcpy (node, priv_data->vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, node, 2, 1))
-+ return -1;
-+ if (!ped_geometry_write (priv_data->plus_geom, node,
-+ priv_data->plus_geom->length - 2, 1))
-+ return -1;
-+ /* !!!!!!!!!!!!!!!!! */
-+ /* This "if" by itself makes the need to rewrite the whole function */
-+ /* !!!!!!!!!!!!!!!!! */
-+ if ((unsigned) new_start > old_start) {
-+ if (pass2) return -1;
-+ pass2 = 1; src_fblock = &new_start;
-+ switch (from) {
-+ case 0: goto plus_start_file_found;
-+ case 1: goto plus_attrib_file_found;
-+ case 2: goto plus_alloc_file_found;
-+ case 3: goto plus_ext_file_found;
-+ case 4: goto plus_cat_file_found;
-+ }
-+ }
-+ return 1;
-+}
-+
-+/* This function moves an extent starting at block fblock
-+ to block to_fblock if there's enough room */
-+/* Return 1 if everything was fine */
-+/* Return -1 if an error occured */
-+/* Return 0 if no extent was found */
-+static int
-+hfsplus_move_extent_starting_at (PedFileSystem *fs, unsigned int *ptr_fblock,
-+ unsigned int *ptr_to_fblock)
-+{
-+ int ret;
-+
-+ /* order = decreasing probability to be found */
-+ if ((ret = hfsplus_search_move_catalog (fs, ptr_fblock, ptr_to_fblock))
-+ || (ret = hfsplus_search_move_extent (fs, ptr_fblock,
-+ ptr_to_fblock))
-+ || (ret = hfsplus_search_move_primary (fs, ptr_fblock,
-+ ptr_to_fblock))
-+ || (ret = hfsplus_search_move_attributes (fs, ptr_fblock,
-+ ptr_to_fblock))) {
-+ return ret;
-+ }
-+
-+ return 0;
-+}
-+
-+/* This function moves file's data to compact used and free space,
-+ starting at fblock block */
-+/* return 0 on error */
-+static int
-+hfsplus_pack_free_space_from_block (PedFileSystem *fs, unsigned int fblock,
-+ PedTimer* timer, unsigned int to_free)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ unsigned int to_fblock = fblock;
-+ int byte, bit, ret;
-+ int to_byte, to_bit;
-+ unsigned int start = fblock;
-+ unsigned int div = PED_BE32_TO_CPU (vh->total_blocks)
-+ + 1 - start - to_free;
-+
-+ to_byte = byte = fblock / 8;
-+ to_bit = bit = 7 - (fblock & 7);
-+
-+ if (!hfsplus_read_bad_blocks (fs))
-+ return 0;
-+
-+ while ( fblock < ( priv_data->plus_geom->length - 2 )
-+ / ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE ) ) {
-+ if (((priv_data->alloc_map[byte] >> bit) & 1)
-+ && (!hfsplus_is_bad_block (fs, fblock))) {
-+ if (!(ret = hfsplus_move_extent_starting_at (fs,
-+ &fblock,
-+ &to_fblock)))
-+ to_fblock = ++fblock;
-+ else if (ret == -1)
-+ return 0;
-+ } else {
-+ fblock++;
-+ }
-+
-+ byte = fblock / 8;
-+ bit = 7 - (fblock & 7);
-+
-+ to_byte = to_fblock / 8;
-+ to_bit = 7 - (to_fblock & 7);
-+
-+ ped_timer_update(timer, (float)(to_fblock - start) / div);
-+ }
-+
-+ return 1;
-+}
-+
-+/* This function returns the first sector of the last free block of
-+ an HFS+ volume we can get after a hfsplus_pack_free_space_from_block call */
-+static PedSector
-+hfsplus_get_empty_end (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ HfsPPrivateLinkExtent* link;
-+ unsigned int block, last_bad, end_free_blocks;
-+ int byte, bit;
-+
-+ /* find the next block to the last bad block of the volume */
-+ if (!hfsplus_read_bad_blocks (fs))
-+ return 0;
-+
-+ last_bad = 0;
-+ for (link = priv_data->bad_blocks_xtent_list; link; link = link->next) {
-+ if ((unsigned int) PED_BE32_TO_CPU (link->extent.start_block)
-+ + PED_BE32_TO_CPU (link->extent.block_count) > last_bad)
-+ last_bad = PED_BE32_TO_CPU (link->extent.start_block)
-+ + PED_BE32_TO_CPU (link->extent.block_count);
-+ }
-+
-+ /* Count the free blocks from last_bad to the end of the volume */
-+ end_free_blocks = 0;
-+ for (block = last_bad;
-+ block < PED_BE32_TO_CPU (vh->total_blocks);
-+ block++) {
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if (!((priv_data->alloc_map[byte]>>bit)&1))
-+ end_free_blocks++;
-+ }
-+
-+ /* Calculate the block that will by the first free at
-+ the end of the volume */
-+ block = PED_BE32_TO_CPU (vh->total_blocks) - end_free_blocks;
-+
-+ return (PedSector) block * ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+}
-+
-+static PedSector
-+hfsplus_get_min_size (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedSector min_size;
-+
-+ /* don't need to add anything because every sector
-+ is part of allocation blocks in HFS+ */
-+ min_size = hfsplus_get_empty_end(fs);
-+
-+ if (priv_data->wrapper) {
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block;
-+ hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+ /*
-+ * if hfs+ is embedded in an hfs wrapper then the new size is :
-+ * the new size of the hfs+ volume rounded up to the size
-+ * of hfs blocks
-+ * + the minimum size of the hfs wrapper without any hfs+
-+ * modification
-+ * - the current size of the hfs+ volume in the hfs wrapper
-+ */
-+ min_size = ((min_size + hfs_sect_block - 1) / hfs_sect_block)
-+ * hfs_sect_block
-+ + hfs_get_empty_end(priv_data->wrapper) + 2
-+ - (PedSector) PED_BE16_TO_CPU ( hfs_priv_data->mdb
-+ ->old_new.embedded
-+ .location.block_count )
-+ * hfs_sect_block;
-+ }
-+
-+ return min_size;
-+}
-+
-+static PedConstraint*
-+hfsplus_get_resize_constraint (const PedFileSystem *fs)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedDevice* dev = fs->geom->dev;
-+ PedAlignment start_align;
-+ PedGeometry start_sector;
-+ PedGeometry full_dev;
-+ PedSector min_size;
-+
-+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
-+ return NULL;
-+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
-+ return NULL;
-+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
-+ return NULL;
-+
-+ min_size = hfsplus_get_min_size (fs);
-+
-+ return ped_constraint_new (&start_align, ped_alignment_any,
-+ &start_sector, &full_dev, min_size,
-+ fs->geom->length);
-+}
-+
-+/* return the block which should be used to pack data to have
-+ at least free fblock blocks at the end of the volume */
-+static unsigned int
-+hfsplus_find_start_pack (const PedFileSystem *fs, unsigned int fblock)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ unsigned int block;
-+
-+ for (block = PED_BE32_TO_CPU (priv_data->vh->total_blocks) - 1;
-+ block && fblock;
-+ block--) {
-+ if (!((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ fblock--;
-+ }
-+
-+ while (block && !((priv_data->alloc_map[block / 8]
-+ >> (7 - (block & 7))) & 1))
-+ block--;
-+ if ((priv_data->alloc_map[block / 8] >> (7 - (block & 7))) & 1)
-+ block++;
-+
-+ return block;
-+}
-+
-+static int
-+hfsplus_volume_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ uint8_t buf[PED_SECTOR_SIZE];
-+ unsigned int nblock, nfree;
-+ unsigned int block, to_free;
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPVolumeHeader* vh = priv_data->vh;
-+ int resize = 1;
-+ unsigned int hfsp_sect_block =
-+ ( PED_BE32_TO_CPU (vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ HfsPPrivateFile* allocation_file;
-+ unsigned int map_sectors;
-+
-+ /* Clear the unmounted bit */
-+ vh->attributes &= PED_CPU_TO_BE32 (~( 1 << HFS_UNMOUNTED ));
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1))
-+ return 0;
-+ memcpy (buf, vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, buf, 2, 1))
-+ return 0;
-+
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name(timer, _("shrinking"));
-+ ped_timer_update(timer, 0.0);
-+ /* relocate data */
-+ block = hfsplus_find_start_pack (fs, to_free =
-+ ( priv_data->plus_geom->length
-+ - geom->length + hfsp_sect_block
-+ - 1 ) / hfsp_sect_block );
-+ if (!hfsplus_pack_free_space_from_block (fs, block, timer, to_free)) {
-+ resize = 0;
-+ goto write_VH;
-+ }
-+
-+ /* Calculate new block number and other VH field */
-+ nblock = (geom->length + hfsp_sect_block - 1) / hfsp_sect_block;
-+ nfree = PED_BE32_TO_CPU (vh->free_blocks)
-+ - (PED_BE32_TO_CPU (vh->total_blocks) - nblock);
-+ if (priv_data->plus_geom->length % hfsp_sect_block == 1)
-+ nfree++;
-+ if (geom->length % hfsp_sect_block == 1)
-+ nfree--;
-+
-+ /* Check that all block after future end are really free */
-+ for ( block = nblock;
-+ block < ( priv_data->plus_geom->length - 2 )
-+ / ( PED_BE32_TO_CPU (vh->block_size) / PED_SECTOR_SIZE );
-+ block++ ) {
-+ int byte, bit;
-+ byte = block / 8;
-+ bit = 7 - (block & 7);
-+ if ((priv_data->alloc_map[byte]>>bit)&1) {
-+ resize = 0;
-+ goto write_VH;
-+ }
-+ }
-+
-+ /* Update geometry */
-+ if (resize) {
-+ /* update in fs structure */
-+ if (PED_BE32_TO_CPU (vh->next_allocation) >= nblock)
-+ vh->next_allocation = PED_CPU_TO_BE32 (0);
-+ vh->total_blocks = PED_CPU_TO_BE32 (nblock);
-+ vh->free_blocks = PED_CPU_TO_BE32 (nfree);
-+ /* update parted structure */
-+ priv_data->plus_geom->length = geom->length;
-+ priv_data->plus_geom->end = priv_data->plus_geom->start
-+ + geom->length - 1;
-+ }
-+
-+ /* Effective write */
-+ write_VH:
-+ /* lasts two sectors are allocated by the alternate VH
-+ and a reserved sector */
-+ block = (priv_data->plus_geom->length - 1) / hfsp_sect_block;
-+ priv_data->alloc_map[block / 8] |= 1 << (7 - (block & 7));
-+ block = (priv_data->plus_geom->length - 2) / hfsp_sect_block;
-+ priv_data->alloc_map[block / 8] |= 1 << (7 - (block & 7));
-+ map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
-+ + PED_SECTOR_SIZE * 8 - 1 ) / (PED_SECTOR_SIZE * 8);
-+ allocation_file =
-+ hfsplus_file_open ( fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
-+ vh->allocation_file.extents,
-+ PED_BE64_TO_CPU (
-+ vh->allocation_file.logical_size )
-+ / PED_SECTOR_SIZE );
-+ if (!hfsplus_file_write (allocation_file, priv_data->alloc_map,
-+ 0, map_sectors))
-+ resize = 0;
-+ hfsplus_file_close (allocation_file);
-+
-+ if (resize) {
-+ /* Set the unmounted bit and clear the inconsistent bit */
-+ vh->attributes |= PED_CPU_TO_BE32 ( 1 << HFS_UNMOUNTED );
-+ vh->attributes &= ~ PED_CPU_TO_BE32 ( 1 << HFSP_INCONSISTENT );
-+ }
-+
-+ ped_timer_set_state_name(timer, _("writing HFS+ Volume Header"));
-+ if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1 ))
-+ return 0;
-+ memcpy (buf, vh, sizeof (HfsPVolumeHeader));
-+ if (!ped_geometry_write (priv_data->plus_geom, buf, 2, 1 ))
-+ return 0;
-+ if (!ped_geometry_write ( priv_data->plus_geom, buf,
-+ priv_data->plus_geom->length - 2, 1 ))
-+ return 0;
-+ ped_timer_update(timer, 1.0);
-+
-+ return (resize);
-+}
-+
-+/* Update the HFS wrapper mdb and bad blocks file to reflect
-+ the new geometry of the embedded HFS+ volume */
-+static int
-+hfsplus_wrapper_update (PedFileSystem* fs)
-+{
-+ uint8_t node[PED_SECTOR_SIZE];
-+ HfsCPrivateLeafRec ref;
-+ HfsExtentKey key;
-+ HfsNodeDescriptor* node_desc = (HfsNodeDescriptor*) node;
-+ HfsExtentKey* ret_key;
-+ HfsExtDescriptor* ret_data;
-+ unsigned int i, j;
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE ;
-+ PedSector hfsplus_sect = (PedSector)
-+ PED_BE32_TO_CPU (priv_data->vh->total_blocks)
-+ * ( PED_BE32_TO_CPU (priv_data->vh->block_size)
-+ / PED_SECTOR_SIZE );
-+ unsigned int hfs_blocks_embedded =
-+ (hfsplus_sect + hfs_sect_block - 1)
-+ / hfs_sect_block;
-+ unsigned int hfs_blocks_embedded_old;
-+
-+ /* update HFS wrapper MDB */
-+ hfs_blocks_embedded_old = PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count );
-+ hfs_priv_data->mdb->old_new.embedded.location.block_count =
-+ PED_CPU_TO_BE16 (hfs_blocks_embedded);
-+ /* maybe macOS will boot with this */
-+ hfs_priv_data->mdb->free_blocks =
-+ PED_CPU_TO_BE16 ( PED_BE16_TO_CPU (hfs_priv_data->mdb->free_blocks)
-+ + hfs_blocks_embedded_old
-+ - hfs_blocks_embedded );
-+
-+ if (!ped_geometry_read (fs->geom, node, 2, 1))
-+ return 0;
-+ memcpy (node, hfs_priv_data->mdb, sizeof (HfsMasterDirectoryBlock));
-+ if (!ped_geometry_write (fs->geom, node, 2, 1))
-+ return 0;
-+ if (!ped_geometry_write (fs->geom, node, fs->geom->length - 2, 1))
-+ return 0;
-+
-+ /* force reload bad block list */
-+ if (hfs_priv_data->bad_blocks_loaded) {
-+ hfs_free_bad_blocks_list (hfs_priv_data->bad_blocks_xtent_list);
-+ hfs_priv_data->bad_blocks_xtent_list = NULL;
-+ hfs_priv_data->bad_blocks_xtent_nb = 0;
-+ hfs_priv_data->bad_blocks_loaded = 0;
-+ }
-+
-+ /* clean HFS wrapper allocation map */
-+ for (i = PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new.embedded
-+ .location.start_block )
-+ + hfs_blocks_embedded;
-+ i < PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->old_new.embedded
-+ .location.start_block )
-+ + hfs_blocks_embedded_old;
-+ i++ ) {
-+ hfs_priv_data->alloc_map[i/8] &= ~(1 << (7 - (i & 7)));
-+ }
-+ /* and save it */
-+ if (!ped_geometry_write (fs->geom, hfs_priv_data->alloc_map,
-+ PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->volume_bitmap_block ),
-+ ( PED_BE16_TO_CPU (
-+ hfs_priv_data->mdb->total_blocks )
-+ + PED_SECTOR_SIZE * 8 - 1 )
-+ / (PED_SECTOR_SIZE * 8)))
-+ return 0;
-+
-+
-+ /* search and update the bad blocks file */
-+ key.key_length = sizeof(key) - 1;
-+ key.type = HFS_DATA_FORK;
-+ key.file_ID = PED_CPU_TO_BE32 (HFS_BAD_BLOCK_ID);
-+ key.start = 0;
-+ if (!hfs_btree_search (hfs_priv_data->extent_file,
-+ (HfsPrivateGenericKey*) &key, NULL, 0, &ref))
-+ return 0;
-+ if (!hfs_file_read_sector (hfs_priv_data->extent_file, node,
-+ ref.node_number))
-+ return 0;
-+ ret_key = (HfsExtentKey*) (node + ref.record_pos);
-+ ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
-+ + sizeof (HfsExtentKey) );
-+
-+ while (ret_key->type == key.type && ret_key->file_ID == key.file_ID) {
-+ for (i = 0; i < HFS_EXT_NB; i++) {
-+ if ( ret_data[i].start_block
-+ == hfs_priv_data->mdb->old_new
-+ .embedded.location.start_block) {
-+ ret_data[i].block_count =
-+ hfs_priv_data->mdb->old_new
-+ .embedded.location.block_count;
-+ /* found ! : update */
-+ if (!hfs_file_write_sector (
-+ hfs_priv_data->extent_file,
-+ node, ref.node_number))
-+ return 0;
-+ return 1;
-+ }
-+ }
-+
-+ if (ref.record_number < PED_BE16_TO_CPU (node_desc->rec_nb)) {
-+ ref.record_number++;
-+ } else {
-+ ref.node_number = PED_BE32_TO_CPU (node_desc->next);
-+ if (!ref.node_number
-+ || !hfs_file_read_sector(hfs_priv_data->extent_file,
-+ node, ref.node_number))
-+ return 0;
-+ ref.record_number = 1;
-+ }
-+
-+ ref.record_pos = PED_BE16_TO_CPU (*((uint16_t *)
-+ (node+(PED_SECTOR_SIZE - 2*ref.record_number))));
-+ ret_key = (HfsExtentKey*) (node + ref.record_pos);
-+ ret_data = (HfsExtDescriptor*) ( node + ref.record_pos
-+ + sizeof (HfsExtentKey) );
-+ }
-+
-+ /* not found : not a valid hfs+ wrapper : failure */
-+ return 0;
-+}
-+
-+static int
-+hfsplus_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
-+{
-+ HfsPPrivateFSData* priv_data = (HfsPPrivateFSData*)
-+ fs->type_specific;
-+ PedTimer* timer_plus;
-+ PedGeometry* embedded_geom;
-+
-+ /* check preconditions */
-+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
-+
-+ if (fs->geom->start != geom->start)
-+ {
-+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
-+ PED_EXCEPTION_CANCEL,
-+ _("Sorry, can't move the start of hfs partitions yet!"));
-+ return 0;
-+ }
-+
-+ if (geom->length > fs->geom->length
-+ || geom->length < hfsplus_get_min_size (fs))
-+ return 0;
-+
-+ if (priv_data->wrapper) {
-+ PedSector red, hgee;
-+ HfsPrivateFSData* hfs_priv_data = (HfsPrivateFSData*)
-+ priv_data->wrapper->type_specific;
-+ unsigned int hfs_sect_block =
-+ PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
-+ / PED_SECTOR_SIZE;
-+
-+ /* There is a wrapper so we must calculate the new geometry
-+ of the embedded HFS+ volume */
-+ red = ( (fs->geom->length - geom->length + hfs_sect_block - 1)
-+ / hfs_sect_block ) * hfs_sect_block;
-+ /* Can't we shrink the hfs+ volume by the desired size ? */
-+ if ( red > priv_data->plus_geom->length
-+ - (hgee = hfsplus_get_empty_end (fs))) {
-+ /* No, shrink hfs+ by the greatest possible value */
-+ hgee = ((hgee + hfs_sect_block - 1) / hfs_sect_block)
-+ * hfs_sect_block;
-+ red = priv_data->plus_geom->length - hgee;
-+ }
-+ embedded_geom = ped_geometry_new (geom->dev,
-+ priv_data->plus_geom->start,
-+ priv_data->plus_geom->length
-+ - red);
-+
-+ /* There is a wrapper so the resize process is a two stages
-+ process (embedded resizing then wrapper resizing) :
-+ we create a sub timer */
-+ ped_timer_reset (timer);
-+ ped_timer_set_state_name (timer,
-+ _("shrinking embedded HFS+ volume"));
-+ ped_timer_update(timer, 0.0);
-+ timer_plus = ped_timer_new_nested (timer, 0.98);
-+ } else {
-+ /* No wrapper : the desired geometry is the desired
-+ HFS+ volume geometry */
-+ embedded_geom = geom;
-+ timer_plus = timer;
-+ }
-+
-+ /* Resize the HFS+ volume */
-+ if (!hfsplus_volume_resize (fs, embedded_geom, timer_plus)) {
-+ if (timer_plus != timer) ped_timer_destroy_nested (timer_plus);
-+ return 0;
-+ }
-+
-+ if (priv_data->wrapper) {
-+ ped_geometry_destroy (embedded_geom);
-+ ped_timer_destroy_nested (timer_plus);
-+ ped_timer_set_state_name(timer, _("shrinking HFS wrapper"));
-+ timer_plus = ped_timer_new_nested (timer, 0.02);
-+ /* There's a wrapper : second stage = resizing it */
-+ if (!hfsplus_wrapper_update (fs)
-+ || !hfs_resize (priv_data->wrapper, geom, timer_plus)) {
-+ ped_timer_destroy_nested (timer_plus);
-+ return 0;
-+ }
-+ ped_timer_destroy_nested (timer_plus);
-+ }
-+ ped_timer_update(timer, 1.0);
-+
-+ return 1;
- }
- #endif /* !DISCOVER_ONLY */
-
-@@ -64,9 +3232,44 @@
- probe: hfs_probe,
- #ifndef DISCOVER_ONLY
- clobber: hfs_clobber,
-+ open: hfs_open,
-+ create: NULL,
-+ close: hfs_close,
-+ check: NULL,
-+ copy: NULL,
-+ resize: hfs_resize,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: hfs_get_resize_constraint,
-+ get_copy_constraint: NULL,
- #else
- clobber: NULL,
-+ open: NULL,
-+ create: NULL,
-+ close: NULL,
-+ check: NULL,
-+ copy: NULL,
-+ resize: NULL,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: NULL,
-+ get_copy_constraint: NULL,
- #endif
-+};
-+
-+static PedFileSystemOps hfsplus_ops = {
-+ probe: hfsplus_probe,
-+#ifndef DISCOVER_ONLY
-+ clobber: hfsplus_clobber,
-+ open: hfsplus_open,
-+ create: NULL,
-+ close: hfsplus_close,
-+ check: NULL,
-+ copy: NULL,
-+ resize: hfsplus_resize,
-+ get_create_constraint: NULL,
-+ get_resize_constraint: hfsplus_get_resize_constraint,
-+ get_copy_constraint: NULL,
-+#else
-+ clobber: NULL,
- open: NULL,
- create: NULL,
- close: NULL,
-@@ -76,23 +3279,32 @@
- get_create_constraint: NULL,
- get_resize_constraint: NULL,
- get_copy_constraint: NULL,
-+#endif
- };
-
-+
- static PedFileSystemType hfs_type = {
- next: NULL,
- ops: &hfs_ops,
- name: "hfs"
- };
-
-+static PedFileSystemType hfsplus_type = {
-+ next: NULL,
-+ ops: &hfsplus_ops,
-+ name: "hfs+"
-+};
-+
- void
- ped_file_system_hfs_init ()
- {
- ped_file_system_type_register (&hfs_type);
-+ ped_file_system_type_register (&hfsplus_type);
- }
-
- void
- ped_file_system_hfs_done ()
- {
- ped_file_system_type_unregister (&hfs_type);
-+ ped_file_system_type_unregister (&hfsplus_type);
- }
--
-diff -Nru parted-1.6.6/libparted/fs_hfs/hfs.h parted-1.6.6-hfs/libparted/fs_hfs/hfs.h
---- parted-1.6.6/libparted/fs_hfs/hfs.h Thu Jan 1 01:00:00 1970
-+++ parted-1.6.6-hfs/libparted/fs_hfs/hfs.h Mon Oct 27 23:25:18 2003
-@@ -0,0 +1,543 @@
-+/*
-+ libparted - a library for manipulating disk partitions
-+ Copyright (C) 2003 Free Software Foundation, Inc.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+#ifndef _HFS_H
-+#define _HFS_H
-+
-+
-+#undef HFS_DEBUG
-+
-+#define HFS_SIGNATURE 0x4244
-+#define HFSP_SIGNATURE 0x482B
-+
-+#define HFS_HARD_LOCK 7
-+#define HFS_UNMOUNTED 8
-+#define HFS_BAD_SPARED 9
-+#define HFS_SOFT_LOCK 15
-+#define HFSP_NO_CACHE 10
-+#define HFSP_INCONSISTENT 11
-+
-+#define HFS_IDX_NODE 0x00
-+#define HFS_HDR_NODE 0x01
-+#define HFS_MAP_NODE 0x02
-+#define HFS_LEAF_NODE 0xFF
-+
-+#define HFS_FIRST_REC 0x0E
-+#define HFS_NSD_HD_REC 0x78
-+#define HFS_MAP_REC 0xF8
-+
-+#define HFS_DATA_FORK 0x00
-+#define HFS_RES_FORK 0xFF
-+
-+#define HFS_CAT_DIR 0x01
-+#define HFS_CAT_FILE 0x02
-+#define HFS_CAT_DIR_TH 0x03
-+#define HFS_CAT_FILE_TH 0x04
-+
-+#define HFSP_ATTR_INLINE 0x10
-+#define HFSP_ATTR_FORK 0x20
-+#define HFSP_ATTR_EXTENTS 0x30
-+
-+#define HFS_ROOT_PAR_ID 0x01
-+#define HFS_ROOT_DIR_ID 0x02
-+#define HFS_XTENT_ID 0x03
-+#define HFS_CATALOG_ID 0x04
-+#define HFS_BAD_BLOCK_ID 0x05
-+#define HFSP_ALLOC_ID 0x06
-+#define HFSP_STARTUP_ID 0x07
-+#define HFSP_ATTRIB_ID 0x08
-+#define HFSP_BOGUS_ID 0x0F
-+#define HFSP_FIRST_AV_ID 0x10
-+
-+#define HFS_EXT_NB 3
-+#define HFSP_EXT_NB 8
-+
-+static PedFileSystemType hfs_type;
-+static PedFileSystemType hfsplus_type;
-+
-+
-+
-+/* ----------------------------------- */
-+/* -- HFS DATA STRUCTURES -- */
-+/* ----------------------------------- */
-+
-+/* Extent descriptor */
-+struct __attribute__ ((packed)) _HfsExtDescriptor {
-+ uint16_t start_block;
-+ uint16_t block_count;
-+};
-+typedef struct _HfsExtDescriptor HfsExtDescriptor;
-+typedef HfsExtDescriptor HfsExtDataRec[HFS_EXT_NB];
-+
-+/* Volume header */
-+struct __attribute__ ((packed)) _HfsMasterDirectoryBlock {
-+ uint16_t signature;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint16_t volume_attributes;
-+ uint16_t files_in_root;
-+ uint16_t volume_bitmap_block; /* in sectors */
-+ uint16_t next_allocation;
-+ uint16_t total_blocks;
-+ uint32_t block_size; /* in bytes */
-+ uint32_t def_clump_size; /* in bytes */
-+ uint16_t start_block; /* in sectors */
-+ uint32_t next_free_node;
-+ uint16_t free_blocks;
-+ uint8_t name_length;
-+ char name[27];
-+ uint32_t backup_date;
-+ uint16_t backup_number;
-+ uint32_t write_count;
-+ uint32_t extents_clump;
-+ uint32_t catalog_clump;
-+ uint16_t dirs_in_root;
-+ uint32_t file_count;
-+ uint32_t dir_count;
-+ uint32_t finder_info[8];
-+ union __attribute__ ((packed)) {
-+ struct __attribute__ ((packed)) {
-+ uint16_t volume_cache_size; /* in blocks */
-+ uint16_t bitmap_cache_size; /* in blocks */
-+ uint16_t common_cache_size; /* in blocks */
-+ } legacy;
-+ struct __attribute__ ((packed)) {
-+ uint16_t signature;
-+ HfsExtDescriptor location;
-+ } embedded;
-+ } old_new;
-+ uint32_t extents_file_size; /* in bytes, block size multiple */
-+ HfsExtDataRec extents_file_rec;
-+ uint32_t catalog_file_size; /* in bytes, block size multiple */
-+ HfsExtDataRec catalog_file_rec;
-+};
-+typedef struct _HfsMasterDirectoryBlock HfsMasterDirectoryBlock;
-+
-+/* B*-Tree Node Descriptor */
-+struct __attribute__ ((packed)) _HfsNodeDescriptor {
-+ uint32_t next;
-+ uint32_t previous;
-+ int8_t type;
-+ uint8_t height;
-+ uint16_t rec_nb;
-+ uint16_t reserved;
-+};
-+typedef struct _HfsNodeDescriptor HfsNodeDescriptor;
-+
-+/* Header record of a whole B*-Tree */
-+struct __attribute__ ((packed)) _HfsHeaderRecord {
-+ uint16_t depth;
-+ uint32_t root_node;
-+ uint32_t leaf_records;
-+ uint32_t first_leaf_node;
-+ uint32_t last_leaf_node;
-+ uint16_t node_size;
-+ uint16_t max_key_len;
-+ uint32_t total_nodes;
-+ uint32_t free_nodes;
-+ int8_t reserved[76];
-+};
-+typedef struct _HfsHeaderRecord HfsHeaderRecord;
-+
-+/* Catalog key for B*-Tree lookup in the catalog file */
-+struct __attribute__ ((packed)) _HfsCatalogKey {
-+ int8_t key_length; /* length of the key without key_length */
-+ int8_t reserved;
-+ uint32_t parent_ID;
-+ int8_t name_length;
-+ char name[31]; /* in fact physicaly 1 upto 31 */
-+};
-+typedef struct _HfsCatalogKey HfsCatalogKey;
-+
-+/* Extents overflow key for B*-Tree lookup */
-+struct __attribute__ ((packed)) _HfsExtentKey {
-+ int8_t key_length; /* length of the key without key_length */
-+ int8_t type; /* data or ressource fork */
-+ uint32_t file_ID;
-+ uint16_t start;
-+};
-+typedef struct _HfsExtentKey HfsExtentKey;
-+
-+/* Catalog subdata case directory */
-+struct __attribute__ ((packed)) _HfsDir {
-+ uint16_t flags;
-+ uint16_t valence; /* number of files in this directory */
-+ uint32_t dir_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ int8_t DInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t DXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t reserved[4];
-+};
-+typedef struct _HfsDir HfsDir;
-+
-+/* Catalog subdata case file */
-+struct __attribute__ ((packed)) _HfsFile {
-+ int8_t flags;
-+ int8_t type; /* should be 0 */
-+ int8_t FInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t file_ID;
-+ uint16_t data_start_block;
-+ uint32_t data_sz_byte;
-+ uint32_t data_sz_block;
-+ uint16_t res_start_block;
-+ uint32_t res_sz_byte;
-+ uint32_t res_sz_block;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ int8_t FXInfo[16]; /* used by Finder, handle as reserved */
-+ uint16_t clump_size;
-+ HfsExtDataRec extents_data;
-+ HfsExtDataRec extents_res;
-+ uint32_t reserved;
-+};
-+typedef struct _HfsFile HfsFile;
-+
-+/* Catalog subdata case directory thread */
-+struct __attribute__ ((packed)) _HfsDirTh {
-+ uint32_t reserved[2];
-+ uint32_t parent_ID;
-+ int8_t name_length;
-+ char name[31];
-+};
-+typedef struct _HfsDirTh HfsDirTh;
-+
-+/* Catalog subdata case file thread */
-+typedef struct _HfsDirTh HfsFileTh; /* same as directory thread */
-+
-+/* Catalog data */
-+struct __attribute__ ((packed)) _HfsCatalog {
-+ int8_t type;
-+ int8_t reserved;
-+ union {
-+ HfsDir dir;
-+ HfsFile file;
-+ HfsDirTh dir_th;
-+ HfsFileTh file_th;
-+ } sel;
-+};
-+typedef struct _HfsCatalog HfsCatalog;
-+
-+
-+
-+/* ------------------------------------ */
-+/* -- HFS+ DATA STRUCTURES -- */
-+/* ------------------------------------ */
-+
-+/* Permission struct is reserved in HFS+ official specification */
-+/* May be it could be used in unix implementations of HFS+ */
-+struct __attribute__ ((packed)) _HfsPPerms {
-+ uint32_t owner_ID; /* reserved */
-+ uint32_t group_ID; /* reserved */
-+ uint32_t permissions; /* reserved */
-+ uint32_t special_devices; /* reserved */
-+};
-+typedef struct _HfsPPerms HfsPPerms;
-+
-+/* HFS+ extent descriptor*/
-+struct __attribute__ ((packed)) _HfsPExtDescriptor {
-+ uint32_t start_block;
-+ uint32_t block_count;
-+};
-+typedef struct _HfsPExtDescriptor HfsPExtDescriptor;
-+typedef HfsPExtDescriptor HfsPExtDataRec[HFSP_EXT_NB];
-+
-+/* HFS+ fork data structure */
-+struct __attribute__ ((packed)) _HfsPForkData {
-+ uint64_t logical_size;
-+ uint32_t clump_size;
-+ uint32_t total_blocks;
-+ HfsPExtDataRec extents;
-+};
-+typedef struct _HfsPForkData HfsPForkData;
-+
-+/* HFS+ catalog node ID */
-+typedef uint32_t HfsPNodeID;
-+
-+/* HFS+ file names */
-+typedef uint16_t unichar;
-+struct __attribute__ ((packed)) _HfsPUniStr255 {
-+ uint16_t length;
-+ unichar unicode[255]; /* 1 upto 255 */
-+};
-+typedef struct _HfsPUniStr255 HfsPUniStr255;
-+
-+/* HFS+ volume header */
-+struct __attribute__ ((packed)) _HfsPVolumeHeader {
-+ uint16_t signature;
-+ uint16_t version;
-+ uint32_t attributes;
-+ uint32_t last_mounted_version;
-+ uint32_t reserved;
-+
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t backup_date;
-+ uint32_t checked_date;
-+
-+ uint32_t file_count;
-+ uint32_t dir_count;
-+
-+ uint32_t block_size;
-+ uint32_t total_blocks;
-+ uint32_t free_blocks;
-+
-+ uint32_t next_allocation;
-+ uint32_t res_clump_size;
-+ uint32_t data_clump_size;
-+ HfsPNodeID next_catalog_ID;
-+
-+ uint32_t write_count;
-+ uint64_t encodings_bitmap;
-+
-+ uint8_t finder_info[32];
-+
-+ HfsPForkData allocation_file;
-+ HfsPForkData extents_file;
-+ HfsPForkData catalog_file;
-+ HfsPForkData attributes_file;
-+ HfsPForkData startup_file;
-+};
-+typedef struct _HfsPVolumeHeader HfsPVolumeHeader;
-+
-+/* HFS+ B-Tree Node Descriptor */ /* same as HFS btree */
-+struct __attribute__ ((packed)) _HfsPNodeDescriptor {
-+ uint32_t next;
-+ uint32_t previous;
-+ int8_t type;
-+ uint8_t height;
-+ uint16_t rec_nb;
-+ uint16_t reserved;
-+};
-+typedef struct _HfsPNodeDescriptor HfsPNodeDescriptor;
-+
-+/* Header record of a whole HFS+ B-Tree */
-+struct __attribute__ ((packed)) _HfsPHeaderRecord {
-+ uint16_t depth;
-+ uint32_t root_node;
-+ uint32_t leaf_records;
-+ uint32_t first_leaf_node;
-+ uint32_t last_leaf_node;
-+ uint16_t node_size;
-+ uint16_t max_key_len;
-+ uint32_t total_nodes;
-+ uint32_t free_nodes; /* same as hfs btree until here */
-+ uint16_t reserved1;
-+
-+ uint32_t clump_size;
-+ uint8_t btree_type; /* must be 0 for HFS+ B-Tree */
-+ uint8_t reserved2;
-+ uint32_t attributes;
-+ uint32_t reserved3[16];
-+};
-+typedef struct _HfsPHeaderRecord HfsPHeaderRecord;
-+
-+/* Catalog key for B-Tree lookup in the HFS+ catalog file */
-+struct __attribute__ ((packed)) _HfsPCatalogKey {
-+ uint16_t key_length;
-+ HfsPNodeID parent_ID;
-+ HfsPUniStr255 node_name;
-+};
-+typedef struct _HfsPCatalogKey HfsPCatalogKey;
-+
-+/* HFS+ catalog subdata case dir */
-+struct __attribute__ ((packed)) _HfsPDir {
-+ uint16_t flags;
-+ uint32_t valence;
-+ HfsPNodeID dir_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t attrib_mod_date;
-+ uint32_t access_date;
-+ uint32_t backup_date;
-+ HfsPPerms permissions;
-+ int8_t DInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t DXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t text_encoding;
-+ uint32_t reserved;
-+};
-+typedef struct _HfsPDir HfsPDir;
-+
-+/* HFS+ catalog subdata case file */
-+struct __attribute__ ((packed)) _HfsPFile {
-+ uint16_t flags;
-+ uint32_t reserved1;
-+ HfsPNodeID file_ID;
-+ uint32_t create_date;
-+ uint32_t modify_date;
-+ uint32_t attrib_mod_date;
-+ uint32_t access_date;
-+ uint32_t backup_date;
-+ HfsPPerms permissions;
-+ int8_t FInfo[16]; /* used by Finder, handle as reserved */
-+ int8_t FXInfo[16]; /* used by Finder, handle as reserved */
-+ uint32_t text_encoding;
-+ uint32_t reserved2;
-+
-+ HfsPForkData data_fork;
-+ HfsPForkData res_fork;
-+};
-+typedef struct _HfsPFile HfsPFile;
-+
-+/* HFS+ catalog subdata case thread */
-+struct __attribute__ ((packed)) _HfsPThread {
-+ int16_t reserved;
-+ HfsPNodeID parent_ID;
-+ HfsPUniStr255 node_name;
-+};
-+typedef struct _HfsPThread HfsPDirTh;
-+typedef struct _HfsPThread HfsPFileTh;
-+
-+/* HFS+ Catalog leaf data */
-+struct __attribute__ ((packed)) _HfsPCatalog {
-+ int16_t type;
-+ union {
-+ HfsPDir dir;
-+ HfsPFile file;
-+ HfsPDirTh dir_th;
-+ HfsPFileTh file_th;
-+ } sel;
-+};
-+typedef struct _HfsPCatalog HfsPCatalog;
-+
-+/* HFS+ extents file key */
-+struct __attribute__ ((packed)) _HfsPExtentKey {
-+ uint16_t key_length;
-+ uint8_t type;
-+ uint8_t pad;
-+ HfsPNodeID file_ID;
-+ uint32_t start;
-+};
-+typedef struct _HfsPExtentKey HfsPExtentKey;
-+
-+/* extent file data is HfsPExtDataRec */
-+
-+/* Fork data attribute file */
-+struct __attribute__ ((packed)) _HfsPForkDataAttr {
-+ uint32_t record_type;
-+ uint32_t reserved;
-+ union __attribute__ ((packed)) {
-+ HfsPForkData fork;
-+ HfsPExtDataRec extents;
-+ } fork_res;
-+};
-+typedef struct _HfsPForkDataAttr HfsPForkDataAttr;
-+
-+
-+
-+/* ---------------------------------------- */
-+/* -- INTERNAL DATA STRUCTURES -- */
-+/* ---------------------------------------- */
-+
-+/* Data of an opened HFS file */
-+struct _HfsPrivateFile {
-+ PedSector sect_nb;
-+ PedFileSystem* fs;
-+ uint32_t CNID; /* disk order (BE) */
-+ HfsExtDataRec first; /* disk order (BE) */
-+ HfsExtDataRec cache; /* disk order (BE) */
-+ uint16_t start_cache; /* CPU order */
-+};
-+typedef struct _HfsPrivateFile HfsPrivateFile;
-+
-+/* To store bad block list */
-+struct _HfsPrivateLinkExtent {
-+ HfsExtDescriptor extent;
-+ struct _HfsPrivateLinkExtent* next;
-+};
-+typedef struct _HfsPrivateLinkExtent HfsPrivateLinkExtent;
-+
-+/* HFS Filesystem specific data */
-+struct _HfsPrivateFSData {
-+ uint8_t alloc_map[(1<<16) / 8];
-+ HfsMasterDirectoryBlock* mdb;
-+ HfsPrivateFile* extent_file;
-+ HfsPrivateFile* catalog_file;
-+ char bad_blocks_loaded;
-+ unsigned int bad_blocks_xtent_nb;
-+ HfsPrivateLinkExtent* bad_blocks_xtent_list;
-+};
-+typedef struct _HfsPrivateFSData HfsPrivateFSData;
-+
-+/* Generic btree key */
-+struct __attribute__ ((packed)) _HfsPrivateGenericKey {
-+ int8_t key_length;
-+ uint8_t key_content[1]; /* we use 1 as a minimum size */
-+};
-+typedef struct _HfsPrivateGenericKey HfsPrivateGenericKey;
-+
-+/* ----- HFS+ ----- */
-+
-+/* Data of an opened HFS file */
-+struct _HfsPPrivateFile {
-+ PedSector sect_nb;
-+ PedFileSystem* fs;
-+ HfsPNodeID CNID; /* disk order (BE) */
-+ HfsPExtDataRec first; /* disk order (BE) */
-+ HfsPExtDataRec cache; /* disk order (BE) */
-+ uint32_t start_cache; /* CPU order */
-+};
-+typedef struct _HfsPPrivateFile HfsPPrivateFile;
-+
-+/* To store bad block list */
-+struct _HfsPPrivateLinkExtent {
-+ HfsPExtDescriptor extent;
-+ struct _HfsPPrivateLinkExtent* next;
-+};
-+typedef struct _HfsPPrivateLinkExtent HfsPPrivateLinkExtent;
-+
-+/* HFS+ filesystem specific data */
-+struct _HfsPPrivateFSData {
-+ PedFileSystem* wrapper; /* NULL if hfs+ is not embedded */
-+ PedGeometry* plus_geom; /* Geometry of HFS+ _volume_ */
-+ char free_geom; /* 1 = plus_geom must be freed */
-+ uint8_t* alloc_map;
-+ HfsPVolumeHeader* vh;
-+ HfsPPrivateFile* extents_file;
-+ HfsPPrivateFile* catalog_file;
-+ HfsPPrivateFile* attributes_file;
-+ char bad_blocks_loaded;
-+ unsigned int bad_blocks_xtent_nb;
-+ HfsPPrivateLinkExtent* bad_blocks_xtent_list;
-+};
-+typedef struct _HfsPPrivateFSData HfsPPrivateFSData;
-+
-+/* Generic + btree key */
-+struct __attribute__ ((packed)) _HfsPPrivateGenericKey {
-+ uint16_t key_length;
-+ uint8_t key_content[1]; /* we use 1 as a minimum size */
-+};
-+typedef struct _HfsPPrivateGenericKey HfsPPrivateGenericKey;
-+
-+/* ---- common ---- */
-+
-+/* node and lead record reference for a BTree search */
-+struct _HfsCPrivateLeafRec {
-+ unsigned int node_size; /* in sectors */
-+ unsigned int node_number;
-+ unsigned int record_pos;
-+ unsigned int record_number;
-+};
-+typedef struct _HfsCPrivateLeafRec HfsCPrivateLeafRec;
-+
-+
-+
-+#endif /* _HFS_H */
diff --git a/sys-apps/parted/parted-1.6.5-r1.ebuild b/sys-apps/parted/parted-1.6.5-r1.ebuild
index e10919b53d42..9a3d4a1f00c9 100644
--- a/sys-apps/parted/parted-1.6.5-r1.ebuild
+++ b/sys-apps/parted/parted-1.6.5-r1.ebuild
@@ -1,11 +1,13 @@
# Copyright 1999-2004 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.5-r1.ebuild,v 1.12 2004/02/02 17:54:50 plasmaroo Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.5-r1.ebuild,v 1.13 2004/03/07 08:19:24 seemant Exp $
DESCRIPTION="Create, destroy, resize, check, copy partitions and file systems"
HOMEPAGE="http://www.gnu.org/software/parted"
-SRC_URI="mirror://gentoo/${P}.tar.gz
- mirror://gnu/${PN}/${P}.tar.gz"
+SRC_URI="mirror://gnu/${PN}/${P}.tar.gz
+ mirror://gentoo/${P}.tar.gz
+ mirror://gentoo/${P}-gentoo.tar.bz2
+ http://dev.gentoo.org/~seemant/extras/${P}-gentoo.tar.bz2"
LICENSE="GPL-2"
SLOT="0"
@@ -16,22 +18,24 @@ DEPEND=">=sys-fs/e2fsprogs-1.27
>=sys-libs/ncurses-5.2
nls? ( sys-devel/gettext )
readline? ( >=sys-libs/readline-4.1-r4 )"
+
RDEPEND="${DEPEND}
!noreiserfs ( =sys-fs/progsreiserfs-0.3.0* )"
+PATCHDIR=${WORKDIR}/patches
+
src_unpack() {
unpack ${A}
- epatch ${FILESDIR}/parted-1.6.5-hfs-8.patch
- epatch ${FILESDIR}/parted-1.6.5-gcc-3.3.patch
+ EPATCH_SUFFIX="patch" epatch ${PATCHDIR}
}
src_compile() {
- local myconf
- use nls || myconf="${myconf} --disable-nls"
- use readline || myconf="${myconf} --without-readline"
- use debug || myconf="${myconf} --disable-debug"
- use static && myconf="${myconf} --enable-all-static"
- econf --target=${CHOST} ${myconf} || die "Configure failed"
+ econf \
+ `use_with readline` \
+ `use_enable nls` \
+ `use_enable debug` \
+ `use_enable static all-static` \
+ --target=${CHOST} || die "Configure failed"
emake || die "Make failed"
}
diff --git a/sys-apps/parted/parted-1.6.5.ebuild b/sys-apps/parted/parted-1.6.5.ebuild
deleted file mode 100644
index b1b1e208f7c8..000000000000
--- a/sys-apps/parted/parted-1.6.5.ebuild
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 1999-2004 Gentoo Technologies, Inc.
-# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.5.ebuild,v 1.11 2004/02/02 17:54:50 plasmaroo Exp $
-
-DESCRIPTION="Create, destroy, resize, check, copy partitions and file systems"
-HOMEPAGE="http://www.gnu.org/software/parted"
-SRC_URI="mirror://gentoo/${P}.tar.gz
- mirror://gnu/${PN}/${P}.tar.gz"
-
-LICENSE="GPL-2"
-SLOT="0"
-KEYWORDS="x86 amd64 ppc sparc hppa alpha"
-IUSE="nls static readline debug noreiserfs"
-
-DEPEND=">=sys-fs/e2fsprogs-1.27
- >=sys-libs/ncurses-5.2
- nls? ( sys-devel/gettext )
- readline? ( >=sys-libs/readline-4.1-r4 )"
-RDEPEND="${DEPEND}
- !noreiserfs? ( =sys-fs/progsreiserfs-0.3.0* )"
-
-src_compile() {
- local myconf
- use nls || myconf="${myconf} --disable-nls"
- use readline || myconf="${myconf} --without-readline"
- use debug || myconf="${myconf} --disable-debug"
- use static && myconf="${myconf} --enable-all-static"
- econf --target=${CHOST} ${myconf} || die "Configure failed"
- emake || die "Make failed"
-}
-
-src_install() {
- einstall || die "Install failed"
- dodoc ABOUT-NLS AUTHORS BUGS COPYING ChangeLog \
- INSTALL NEWS README THANKS TODO
- docinto doc; cd doc
- dodoc API COPYING.DOC FAQ FAT USER USER.jp
-}
diff --git a/sys-apps/parted/parted-1.6.6-r1.ebuild b/sys-apps/parted/parted-1.6.6-r1.ebuild
index 92c3a345e641..1108483d2ed9 100644
--- a/sys-apps/parted/parted-1.6.6-r1.ebuild
+++ b/sys-apps/parted/parted-1.6.6-r1.ebuild
@@ -1,11 +1,13 @@
# Copyright 1999-2004 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.6-r1.ebuild,v 1.3 2004/03/07 01:48:34 iluxa Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.6-r1.ebuild,v 1.4 2004/03/07 08:19:24 seemant Exp $
DESCRIPTION="Create, destroy, resize, check, copy partitions and file systems"
HOMEPAGE="http://www.gnu.org/software/parted"
-SRC_URI="mirror://gentoo/${P}.tar.gz
- mirror://gnu/${PN}/${P}.tar.gz"
+SRC_URI="mirror://gnu/${PN}/${P}.tar.gz
+ mirror://gentoo/${P}.tar.gz
+ mirror://gentoo/${PF}-gentoo.tar.bz2
+ http://dev.gentoo.org/~seemant/extras/${PF}-gentoo.tar.bz2"
LICENSE="GPL-2"
SLOT="0"
@@ -16,25 +18,25 @@ DEPEND=">=sys-fs/e2fsprogs-1.27
>=sys-libs/ncurses-5.2
nls? ( sys-devel/gettext )
readline? ( >=sys-libs/readline-4.1-r4 )"
+
RDEPEND="${DEPEND}
!noreiserfs? ( =sys-fs/progsreiserfs-0.3.0* )"
+PATCHDIR=${WORKDIR}/patches
+
src_unpack() {
unpack ${A}
cd ${S}
- epatch ${FILESDIR}/${P}-assert.patch
- epatch ${FILESDIR}/${P}-hfs-9.patch
- epatch ${FILESDIR}/${P}-gcc-3.3.patch
- epatch ${FILESDIR}/${P}-2-6headers.patch
+ EPATCH_SUFFIX="patch" epatch ${PATCHDIR}
}
src_compile() {
- local myconf
- use nls || myconf="${myconf} --disable-nls"
- use readline || myconf="${myconf} --without-readline"
- use debug || myconf="${myconf} --disable-debug"
- use static && myconf="${myconf} --enable-all-static"
- econf --target=${CHOST} ${myconf} || die "Configure failed"
+ econf \
+ `use_with readline` \
+ `use_enable nls` \
+ `use_enable debug` \
+ `use_enable static all-static` \
+ --target=${CHOST} ${myconf} || die "Configure failed"
emake || die "Make failed"
}
diff --git a/sys-apps/parted/parted-1.6.6.ebuild b/sys-apps/parted/parted-1.6.6.ebuild
index 60ff32c64fbc..59c7d2aedb54 100644
--- a/sys-apps/parted/parted-1.6.6.ebuild
+++ b/sys-apps/parted/parted-1.6.6.ebuild
@@ -1,11 +1,13 @@
# Copyright 1999-2004 Gentoo Technologies, Inc.
# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.6.ebuild,v 1.13 2004/02/02 17:54:50 plasmaroo Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/parted/parted-1.6.6.ebuild,v 1.14 2004/03/07 08:19:24 seemant Exp $
DESCRIPTION="Create, destroy, resize, check, copy partitions and file systems"
HOMEPAGE="http://www.gnu.org/software/parted"
-SRC_URI="mirror://gentoo/${P}.tar.gz
- mirror://gnu/${PN}/${P}.tar.gz"
+SRC_URI="mirror://gnu/${PN}/${P}.tar.gz
+ mirror://gentoo/${P}.tar.gz
+ mirror://gentoo/${PF}-gentoo.tar.bz2
+ http://dev.gentoo.org/~seemant/extras/${PF}-gentoo.tar.bz2"
LICENSE="GPL-2"
SLOT="0"
@@ -16,24 +18,25 @@ DEPEND=">=sys-fs/e2fsprogs-1.27
>=sys-libs/ncurses-5.2
nls? ( sys-devel/gettext )
readline? ( >=sys-libs/readline-4.1-r4 )"
+
RDEPEND="${DEPEND}
!noreiserfs? ( =sys-fs/progsreiserfs-0.3.0* )"
+PATCHDIR=${WORKDIR}/patches
+
src_unpack() {
unpack ${A}
cd ${S}
- epatch ${FILESDIR}/${P}-hfs-8.patch
- epatch ${FILESDIR}/${P}-gcc-3.3.patch
- epatch ${FILESDIR}/${P}-2-6headers.patch
+ EPATCH_SUFFIX="patch" epatch ${PATCHDIR}
}
src_compile() {
- local myconf
- use nls || myconf="${myconf} --disable-nls"
- use readline || myconf="${myconf} --without-readline"
- use debug || myconf="${myconf} --disable-debug"
- use static && myconf="${myconf} --enable-all-static"
- econf --target=${CHOST} ${myconf} || die "Configure failed"
+ econf \
+ `use_with readline` \
+ `use_enable nls` \
+ `use_enable debug` \
+ `use_enable static all-static` \
+ --target=${CHOST} || die "Configure failed"
emake || die "Make failed"
}