diff options
Diffstat (limited to 'ext2ed/disk.c')
-rw-r--r-- | ext2ed/disk.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/ext2ed/disk.c b/ext2ed/disk.c new file mode 100644 index 0000000..4612d00 --- /dev/null +++ b/ext2ed/disk.c @@ -0,0 +1,239 @@ +/* + +/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 *) ¤t_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); +} + |