/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2004, 2005 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#ifndef DISCOVER_ONLY

#include <config.h>

#include <parted/parted.h>
#include <parted/endian.h>
#include <parted/debug.h>
#include <stdint.h>

#if ENABLE_NLS
#  include <libintl.h>
#  define _(String) dgettext (PACKAGE, String)
#else
#  define _(String) (String)
#endif /* ENABLE_NLS */

#include "hfs.h"
#include "reloc_plus.h"

#include "journal.h"

static int hfsj_vh_replayed = 0;
static int is_le = 0;

static uint32_t
hfsj_calc_checksum(uint8_t *ptr, int len)
{
	int	 i;
	uint32_t cksum=0;

	for (i=0; i < len; i++, ptr++) {
		cksum = (cksum << 8) ^ (cksum + *ptr);
	}

	return (~cksum);
}

int
hfsj_update_jib(PedFileSystem* fs, uint32_t block)
{
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						    fs->type_specific;

	priv_data->vh->journal_info_block = PED_CPU_TO_BE32(block);

	if (!hfsplus_update_vh (fs))
		return 0;

	priv_data->jib_start_block = block;
	return 1;
}

int
hfsj_update_jl(PedFileSystem* fs, uint32_t block)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedSector		sector;
	uint64_t		offset;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						    fs->type_specific;
	HfsJJournalInfoBlock*	jib;
	int			binsect;

	binsect = HFS_32_TO_CPU(priv_data->vh->block_size, is_le) / PED_SECTOR_SIZE_DEFAULT;
	sector = (PedSector) priv_data->jib_start_block * binsect;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jib = (HfsJJournalInfoBlock*) buf;

	offset = (uint64_t)block * PED_SECTOR_SIZE_DEFAULT * binsect;
	jib->offset = HFS_CPU_TO_64(offset, is_le);

	if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
	    || !ped_geometry_sync(priv_data->plus_geom))
		return 0;

	priv_data->jl_start_block = block;
	return 1;
}

/* Return the sector in the journal that is after the area read */
/* or 0 on error */
static PedSector
hfsj_journal_read(PedGeometry* geom, HfsJJournalHeader* jh,
		  PedSector journ_sect, PedSector journ_length,
		  PedSector read_sect, unsigned int nb_sect,
		  void* buf)
{
	int r;

	while (nb_sect--) {
		r = ped_geometry_read(geom, buf, journ_sect + read_sect, 1);
		if (!r) return 0;

		buf = ((uint8_t*)buf) + PED_SECTOR_SIZE_DEFAULT;
		read_sect++;
		if (read_sect == journ_length)
			read_sect = 1; /* skip journal header
					  which is asserted to be 
					  1 sector long */
	}

	return read_sect;
}

static int
hfsj_replay_transaction(PedFileSystem* fs, HfsJJournalHeader* jh,
			PedSector jsector, PedSector jlength)
{
	PedSector		start, sector;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						fs->type_specific;
	HfsJBlockListHeader*	blhdr;
	uint8_t*		block;
	unsigned int		blhdr_nbsect;
	int			i, r;
	uint32_t		cksum, size;

	blhdr_nbsect = HFS_32_TO_CPU(jh->blhdr_size, is_le) / PED_SECTOR_SIZE_DEFAULT;
	blhdr = (HfsJBlockListHeader*)
		  ped_malloc (blhdr_nbsect * PED_SECTOR_SIZE_DEFAULT);
	if (!blhdr) return 0;

	start = HFS_64_TO_CPU(jh->start, is_le) / PED_SECTOR_SIZE_DEFAULT;
	do {
		start = hfsj_journal_read(priv_data->plus_geom, jh, jsector,
					  jlength, start, blhdr_nbsect, blhdr);
		if (!start) goto err_replay;
		
		cksum = HFS_32_TO_CPU(blhdr->checksum, is_le);
		blhdr->checksum = 0;
		if (cksum!=hfsj_calc_checksum((uint8_t*)blhdr, sizeof(*blhdr))){
			ped_exception_throw (
				PED_EXCEPTION_ERROR,
				PED_EXCEPTION_CANCEL,
				_("Bad block list header checksum."));
			goto err_replay;
		}
		blhdr->checksum = HFS_CPU_TO_32(cksum, is_le);
		
		for (i=1; i < HFS_16_TO_CPU(blhdr->num_blocks, is_le); ++i) {
			size = HFS_32_TO_CPU(blhdr->binfo[i].bsize, is_le);
			sector = HFS_64_TO_CPU(blhdr->binfo[i].bnum, is_le);
			if (!size) continue;
			if (size % PED_SECTOR_SIZE_DEFAULT) {
				ped_exception_throw(
					PED_EXCEPTION_ERROR,
					PED_EXCEPTION_CANCEL,
					_("Invalid size of a transaction "
					  "block while replaying the journal "
					  "(%i bytes)."),
					size);
				goto err_replay;
			}
			block = (uint8_t*) ped_malloc(size);
			if (!block) goto err_replay;
			start = hfsj_journal_read(priv_data->plus_geom, jh,
						  jsector, jlength, start,
						  size / PED_SECTOR_SIZE_DEFAULT,
						  block);
			if (!start) {
				ped_free (block);
				goto err_replay;
			}
			/* the sector stored in the journal seems to be
			   relative to the begin of the block device which
			   contains the hfs+ journaled volume */
			if (sector != ~0LL)
				r = ped_geometry_write (fs->geom, block, sector,
							size / PED_SECTOR_SIZE_DEFAULT);
			else
				r = 1;
			ped_free (block);
			/* check if wrapper mdb or vh with no wrapper has
			   changed */
			if (   (sector != ~0LL)
			    && (2 >= sector)
			    && (2 < sector + size / PED_SECTOR_SIZE_DEFAULT) )
				hfsj_vh_replayed = 1;
			/* check if vh of embedded hfs+ has changed */
			if (   (sector != ~0LL)
			    && (priv_data->plus_geom != fs->geom)
			    && (sector
			        + fs->geom->start
				- priv_data->plus_geom->start <= 2)
			    && (sector
			        + size / PED_SECTOR_SIZE_DEFAULT
				+ fs->geom->start
				- priv_data->plus_geom->start > 2) )
				hfsj_vh_replayed = 1;
			if (!r) goto err_replay;
		}
	} while (blhdr->binfo[0].next);

	jh->start = HFS_CPU_TO_64(start * PED_SECTOR_SIZE_DEFAULT, is_le);

	ped_free (blhdr);
	return (ped_geometry_sync (fs->geom));

err_replay:
	ped_free (blhdr);
	return 0;
}

/* 0 => Failure, don't continue to open ! */
/* 1 => Success, the journal has been completly replayed, or don't need to */
int
hfsj_replay_journal(PedFileSystem* fs)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedSector		sector, length;
	HfsPPrivateFSData* 	priv_data = (HfsPPrivateFSData*)
						    fs->type_specific;
	HfsJJournalInfoBlock*	jib;
	HfsJJournalHeader*	jh;
	int			binsect;
	uint32_t		cksum;

	binsect = PED_BE32_TO_CPU(priv_data->vh->block_size) / PED_SECTOR_SIZE_DEFAULT;
	priv_data->jib_start_block =
		PED_BE32_TO_CPU(priv_data->vh->journal_info_block);
	sector  = (PedSector) priv_data->jib_start_block * binsect;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jib = (HfsJJournalInfoBlock*) buf;
	
	if (    (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
	    && !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
		priv_data->jl_start_block = HFS_64_TO_CPU(jib->offset, is_le) 
					    / ( PED_SECTOR_SIZE_DEFAULT * binsect );
	}

	if (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_NEED_INIT))
		return 1;

	if (  !(jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_IN_FS))
	    || (jib->flags & PED_CPU_TO_BE32(1 << HFSJ_JOURN_OTHER_DEV)) ) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Journal stored outside of the volume are "
			  "not supported.  Try to desactivate the "
			  "journal and run Parted again."));
		return 0;
	}

	if (   (PED_BE64_TO_CPU(jib->offset) % PED_SECTOR_SIZE_DEFAULT)
	    || (PED_BE64_TO_CPU(jib->size)   % PED_SECTOR_SIZE_DEFAULT) ) {
		ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_CANCEL,
			_("Journal offset or size is not multiple of "
			  "the sector size."));
		return 0;
	}

	sector = PED_BE64_TO_CPU(jib->offset) / PED_SECTOR_SIZE_DEFAULT;
	length = PED_BE64_TO_CPU(jib->size)   / PED_SECTOR_SIZE_DEFAULT;

	jib = NULL;
	if (!ped_geometry_read(priv_data->plus_geom, buf, sector, 1))
		return 0;
	jh = (HfsJJournalHeader*) buf;

	if (jh->endian == PED_LE32_TO_CPU(HFSJ_ENDIAN_MAGIC))
	    is_le = 1;

	if (   (jh->magic  != HFS_32_TO_CPU(HFSJ_HEADER_MAGIC, is_le))
	    || (jh->endian != HFS_32_TO_CPU(HFSJ_ENDIAN_MAGIC, is_le)) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Incorrect magic values in the journal header."));
		return 0;
	}

	if ( (HFS_64_TO_CPU(jh->size, is_le)%PED_SECTOR_SIZE_DEFAULT)
	  || (HFS_64_TO_CPU(jh->size, is_le)/PED_SECTOR_SIZE_DEFAULT
		  != (uint64_t)length) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Journal size mismatch between journal info block "
			  "and journal header."));
		return 0;
	}

	if (   (HFS_64_TO_CPU(jh->start, is_le) % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_64_TO_CPU(jh->end, is_le)   % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_32_TO_CPU(jh->blhdr_size, is_le) % PED_SECTOR_SIZE_DEFAULT)
	    || (HFS_32_TO_CPU(jh->jhdr_size, is_le)  % PED_SECTOR_SIZE_DEFAULT) ) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Some header fields are not multiple of the sector "
			  "size."));
		return 0;
	}

	if (HFS_32_TO_CPU(jh->jhdr_size, is_le) != PED_SECTOR_SIZE_DEFAULT) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("The sector size stored in the journal is not 512 "
			  "bytes.  Parted only supports 512 bytes length "
			  "sectors."));
		return 0;	
	}

	cksum = HFS_32_TO_CPU(jh->checksum, is_le);
	jh->checksum = 0;
	if (cksum != hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh))) {
		ped_exception_throw (
			PED_EXCEPTION_ERROR,
			PED_EXCEPTION_CANCEL,
			_("Bad journal checksum."));
		return 0;
	}
	jh->checksum = HFS_CPU_TO_32(cksum, is_le);

	/* The 2 following test are in the XNU Darwin source code */
	/* so I assume they're needed */
	if (jh->start == jh->size)
		jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);
	if (jh->end   == jh->size)
		jh->start = HFS_CPU_TO_64(PED_SECTOR_SIZE_DEFAULT, is_le);

	if (jh->start == jh->end)
		return 1;

	if (ped_exception_throw (
		PED_EXCEPTION_WARNING,
		PED_EXCEPTION_FIX | PED_EXCEPTION_CANCEL,
		_("The journal is not empty.  Parted must replay the "
		  "transactions before opening the file system.  This will "
		  "modify the file system."))
			!= PED_EXCEPTION_FIX)
		return 0;

	while (jh->start != jh->end) {
		/* Replay one complete transaction */
		if (!hfsj_replay_transaction(fs, jh, sector, length))
			return 0;

		/* Recalculate cksum of the journal header */
		jh->checksum = 0; /* need to be 0 while calculating the cksum */
		cksum = hfsj_calc_checksum((uint8_t*)jh, sizeof(*jh));
		jh->checksum = HFS_CPU_TO_32(cksum, is_le);

		/* Update the Journal Header */
		if (!ped_geometry_write(priv_data->plus_geom, buf, sector, 1)
		    || !ped_geometry_sync(priv_data->plus_geom))
			return 0;
	}

	if (hfsj_vh_replayed) {
		/* probe could have reported incorrect info ! */
		/* is there a way to ask parted to quit ? */
		ped_exception_throw(
			PED_EXCEPTION_WARNING,
			PED_EXCEPTION_OK,
			_("The volume header or the master directory block has "
			  "changed while replaying the journal.  You should "
			  "restart Parted."));
		return 0;
	}

	return 1;
}

#endif /* DISCOVER_ONLY */
