/*

/usr/src/ext2ed/disk.c

A part of the extended file system 2 disk editor.

-------------------------------------------------
The filesystem's disk activity pass through here.
-------------------------------------------------

This file is acting as a filter - Before we pass an actual read or write request to the operating system, we
double check the various permissions and possible errors here.

The major update which needs to be done here is switching to the use of the llseek system call, so that we will
be able to support ext2 filesystems up to 4 TB. Currently, due to the standard fseek usage, we can't handle
filesystems bigger than 4 GB. The limit is actually 2 GB because I used long rather than unsigned long long at too
many places in the program. To conclude - This upgrade needs to be done carefully; There are many places to change.

First written on: April 9 1995

Copyright (C) 1995 Gadi Oxman

*/

#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "ext2ed.h"

int write_access;

int low_read (unsigned char *buffer,unsigned long length,unsigned long offset)

/*

This function is used when we need to read something from the filesystem.

*/

{

#ifdef DEBUG

	char temp [80];

	if (device_handle==NULL) {					/* Check that a device is indeed open */
		internal_error ("No device opened yet read requested","disk","low_read");
		return (0);
	}
	if (offset > file_system_info.file_system_size) {		/* Check that the offset is within limits */
		sprintf (temp,"Seek offset %ld is out of range",offset);
		internal_error (temp,"disk","low_read");
		return (0);
	}

#endif

	if ( (fseek (device_handle,offset,SEEK_SET))==-1) {		/* Seek to the required offset */
		wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",offset,device_name);
		refresh_command_win ();
		return (0);
	};

	if ( (fread (buffer,1,length,device_handle))==-1) {		/* And do the actual reading */
		wprintw (command_win,"Error - Failed to read from offset %ld in device %s\n",offset,device_name);
		refresh_command_win ();return (0);
	};

	return (1);
}

int low_write (unsigned char *buffer,unsigned long length,unsigned long offset)

/*

This is used to change something in the filesystem.
write_access is checked to see if we are allowed to do the actual writing.
As a double safety measure, AllowChanges is rechecked here.
If logging is enabled, we log the change before writing it to the device.

*/
{
	char temp [80];

	if (!write_access) {
		wprintw (command_win,"Error - Write access not available (use enablewrite)\n");
		return (0);
	}

#ifdef DEBUG

	if (!AllowChanges) {
		internal_error ("AllowChanges=0 yet enablewrite succeeded","disk","low_write");
		return (0);
	}

	if (device_handle==NULL) {
		internal_error ("No device opened yet read requested","disk","low_write");
		return (0);
	}

	if (offset > file_system_info.file_system_size) {
		sprintf (temp,"Seek offset %ld is out of range",offset);
		internal_error (temp,"disk","low_write");
		return (0);
	}

#endif

	if (LogChanges)
		if (!log_changes (buffer,length,offset))
			return (0);

	if ( (fseek (device_handle,offset,SEEK_SET))==-1) {
		wprintw (command_win,"Error - Failed to seek to offset %ld in device %s\n",offset,device_name);
		refresh_command_win ();return (0);
	};


	if ( (fwrite (buffer,1,length,device_handle))==-1) {
		wprintw (command_win,"Error - Failed to write to offset %ld in device %s\n",offset,device_name);
		refresh_command_win ();return (0);
	};

	wprintw (command_win,"Data written");refresh_command_win ();
	return (1);
}

int log_changes (unsigned char *buffer,unsigned long length,unsigned long offset)

/*

Log the change in a primitive form - An hex dump of the data before the change and after the change.
The hex bytes are converted to text, so that they will be readable with a standard text editor.

*/

{
	unsigned char *original;

	int i;
	time_t current_time;
	FILE *fp;

	if ((fp=fopen (LogFile,"a+"))==NULL) {
		wprintw (command_win,"Error - Unable to open log file %s\n",LogFile);
		refresh_command_win ();return (0);
	};

	current_time=time (NULL);

	fprintf (fp,"\n----- EXT2ED log begin -----\n\n");
	fprintf (fp,"Time: %s\nDevice: %s\n",ctime ((time_t *) &current_time),device_name);
	fprintf (fp,"Offset: %lu\nLength: %lu\n",offset,length);

	original=(unsigned char *) malloc (length*sizeof (unsigned char));

	if (original==NULL) {
		wprintw (command_win,"Fatal error - Can\'t allocate %lu bytes!");
		refresh_command_win ();fclose (fp);return (0);
	}

	if (!low_read (original,length,offset)) {
		fclose (fp);return (0);
	}

	fprintf (fp,"\nOriginal data:\n\n");

	for (i=0;i<length;i++) {
		if (i%16==0 && i!=0) fprintf (fp,"\n");
		fprintf (fp,"%02x ",original [i]);
	}

	fprintf (fp,"\n\nNew data:\n\n");

	for (i=0;i<length;i++) {
		if (i%16==0 && i!=0) fprintf (fp,"\n");
		fprintf (fp,"%02x ",buffer [i]);
	}

	fprintf (fp,"\n----- EXT2ED log end  -----\n");

	fclose (fp);
	return (1);
}

int load_type_data (void)

/*

Just read from the current position into type data.

*/

{
	if (device_handle==NULL) {
		printf ("Error - No device opened\n");
		return (0);
	}

	if (device_offset==-1) {
		printf ("Error - No offset set\n");
		return (0);
	}

	if (low_read (type_data.u.buffer,EXT2_MAX_BLOCK_SIZE,device_offset)==0)
		return (0);

	if (current_type!=NULL)
		if (strcmp (current_type->name,"ext2_dir_entry")==0)
			current_type->length=type_data.u.t_ext2_dir_entry.rec_len;

	return (1);
}

int write_type_data (void)

{
	if (device_handle==NULL) {
		wprintw (command_win,"Error - No device opened\n");
		refresh_command_win ();
		return (0);
	}

	if (device_offset==-1) {
		wprintw (command_win,"Error - No offset set\n");
		refresh_command_win ();
		return (0);
	}

	if (low_write (type_data.u.buffer,file_system_info.block_size,device_offset)==0)
		return (0);

	return (1);
}

