/*

/usr/src/ext2ed/file_com.c

A part of the extended file system 2 disk editor.

----------------------------
Commands which handle a file
----------------------------

First written on: April 18 1995

Copyright (C) 1995 Gadi Oxman

*/

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

#include "ext2ed.h"

int init_file_info (void)

{
	struct ext2_inode *ptr;

	ptr=&type_data.u.t_ext2_inode;

	file_info.inode_ptr=ptr;
	file_info.inode_offset=device_offset;

	file_info.global_block_num=ptr->i_block [0];
	file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size;
	file_info.block_num=0;
	file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size;
	file_info.file_offset=0;
	file_info.file_length=ptr->i_size;
	file_info.level=0;
	file_info.offset_in_block=0;

	file_info.display=HEX;

	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);

	return (1);
}


void type_file___inode (char *command_line)

{
	dispatch ("settype ext2_inode");
}

void type_file___show (char *command_line)

{
	if (file_info.display==HEX)
		file_show_hex ();
	if (file_info.display==TEXT)
		file_show_text ();
}

void type_file___nextblock (char *command_line)

{
	long block_offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);

	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		block_offset*=atol (buffer);
	}

	if (file_info.block_num+block_offset >= file_info.blocks_count) {
		wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
		return;
	}

	file_info.block_num+=block_offset;
	file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
	file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
	file_info.file_offset=file_info.block_num*file_system_info.block_size;

	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);

	strcpy (buffer,"show");dispatch (buffer);
}

void type_file___next (char *command_line)

{
	int offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);

	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		offset*=atol (buffer);
	}

	if (file_info.offset_in_block+offset < file_system_info.block_size) {
		file_info.offset_in_block+=offset;
		sprintf (buffer,"show");dispatch (buffer);
	}

	else {
		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
	}
}

void type_file___offset (char *command_line)

{
	unsigned long offset;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);

	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		offset=atol (buffer);
	}
	else {
		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
		return;
	}

	if (offset < file_system_info.block_size) {
		file_info.offset_in_block=offset;
		sprintf (buffer,"show");dispatch (buffer);
	}

	else {
		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
	}
}

void type_file___prev (char *command_line)

{
	int offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);

	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		offset*=atol (buffer);
	}

	if (file_info.offset_in_block-offset >= 0) {
		file_info.offset_in_block-=offset;
		sprintf (buffer,"show");dispatch (buffer);
	}

	else {
		wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
	}
}

void type_file___prevblock (char *command_line)

{
	long block_offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);

	if (*ptr!=0) {
		ptr=parse_word (ptr,buffer);
		block_offset*=atol (buffer);
	}

	if (file_info.block_num-block_offset < 0) {
		wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
		return;
	}

	file_info.block_num-=block_offset;
	file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
	file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
	file_info.file_offset=file_info.block_num*file_system_info.block_size;

	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);

	strcpy (buffer,"show");dispatch (buffer);
}

void type_file___block (char *command_line)

{
	long block_offset=1;
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);

	if (*ptr==0) {
		wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
		return;
	}

	ptr=parse_word (ptr,buffer);
	block_offset=atol (buffer);

	if (block_offset < 0 || block_offset >= file_info.blocks_count) {
		wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
		return;
	}

	file_info.block_num=block_offset;
	file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
	file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
	file_info.file_offset=file_info.block_num*file_system_info.block_size;

	low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);

	strcpy (buffer,"show");dispatch (buffer);
}

void type_file___display (char *command_line)

{
	char *ptr,buffer [80];

	ptr=parse_word (command_line,buffer);
	if (*ptr==0)
		strcpy (buffer,"hex");
	else
		ptr=parse_word (ptr,buffer);

	if (strcasecmp (buffer,"hex")==0) {
		wprintw (command_win,"Display set to hex\n");wrefresh (command_win);
		file_info.display=HEX;
		sprintf (buffer,"show");dispatch (buffer);
	}

	else if (strcasecmp (buffer,"text")==0) {
		wprintw (command_win,"Display set to text\n");wrefresh (command_win);
		file_info.display=TEXT;
		sprintf (buffer,"show");dispatch (buffer);
	}

	else {
		wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
	}
}

void file_show_hex (void)

{
	long offset=0,l,i;
	unsigned char *ch_ptr;

	/* device_offset and type_data points to the inode */

	show_pad_info.line=0;

	wmove (show_pad,0,0);
	ch_ptr=file_info.buffer;
	for (l=0;l<file_system_info.block_size/16;l++) {
		if (file_info.file_offset+offset>file_info.file_length-1) break;
		wprintw (show_pad,"%08ld :  ",offset);
		for (i=0;i<16;i++) {

			if (file_info.file_offset+offset+i>file_info.file_length-1) {
				wprintw (show_pad," ");
			}

			else {
				if (file_info.offset_in_block==offset+i)
					wattrset (show_pad,A_REVERSE);

				if (ch_ptr [i]>=' ' && ch_ptr [i]<='z')
					wprintw (show_pad,"%c",ch_ptr [i]);
				else
					wprintw (show_pad,".");

				if (file_info.offset_in_block==offset+i)
					wattrset (show_pad,A_NORMAL);
			}
		}

		wprintw (show_pad,"   ");
		for (i=0;i<16;i++) {
			if (file_info.file_offset+offset+i>file_info.file_length-1) break;
			if (file_info.offset_in_block==offset+i)
				wattrset (show_pad,A_REVERSE);

			wprintw (show_pad,"%02x",ch_ptr [i]);

			if (file_info.offset_in_block==offset+i) {
				wattrset (show_pad,A_NORMAL);
				show_pad_info.line=l-l % show_pad_info.display_lines;
			}

			wprintw (show_pad," ");

		}

		wprintw (show_pad,"\n");
		offset+=i;
		ch_ptr+=i;
	}

	show_pad_info.max_line=l-1;

	refresh_show_pad ();

	show_status ();
}

void file_show_text (void)

{
	long offset=0,last_offset,l=0,cols=0;
	unsigned char *ch_ptr;

	/* device_offset and type_data points to the inode */

	show_pad_info.line=0;
	wmove (show_pad,0,0);
	ch_ptr=file_info.buffer;

	last_offset=file_system_info.block_size-1;

	if (file_info.file_offset+last_offset > file_info.file_length-1)
		last_offset=file_info.file_length-1-file_info.file_offset;

	while ( (offset <= last_offset) && l<SHOW_PAD_LINES) {

		if (cols==SHOW_PAD_COLS-1) {
			wprintw (show_pad,"\n");
			l++;cols=0;
		}


		if (file_info.offset_in_block==offset)
			wattrset (show_pad,A_REVERSE);

		if (*ch_ptr >= ' ' && *ch_ptr <= 'z')
			wprintw (show_pad,"%c",*ch_ptr);


		else {
			if (*ch_ptr == 0xa) {
				wprintw (show_pad,"\n");
				l++;cols=0;
			}

			else if (*ch_ptr == 0x9)
				wprintw (show_pad,"    ");

			else
				wprintw (show_pad,".");
		}

		if (file_info.offset_in_block==offset) {
			wattrset (show_pad,A_NORMAL);
			show_pad_info.line=l-l % show_pad_info.display_lines;
		}


		offset++;cols++;ch_ptr++;
	}

	wprintw (show_pad,"\n");
	show_pad_info.max_line=l;

	refresh_show_pad ();

	show_status ();
}

void show_status (void)

{
	long inode_num;

	werase (show_win);wmove (show_win,0,0);
	wprintw (show_win,"File contents. Block %ld. ",file_info.global_block_num);
	wprintw (show_win,"File block %ld of %ld. ",file_info.block_num,file_info.blocks_count-1);
	wprintw (show_win,"File Offset %ld of %ld.",file_info.file_offset,file_info.file_length-1);

	wmove (show_win,1,0);
	inode_num=inode_offset_to_inode_num (file_info.inode_offset);
	wprintw (show_win,"File inode %ld. Indirection level %ld.",inode_num,file_info.level);

	refresh_show_win ();
}

void type_file___remember (char *command_line)

{
	int found=0;
	long entry_num;
	char *ptr,buffer [80];
	struct struct_descriptor *descriptor_ptr;

	ptr=parse_word (command_line,buffer);

	if (*ptr==0) {
		wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win);
		return;
	}

	ptr=parse_word (ptr,buffer);

	entry_num=remember_lifo.entries_count++;
	if (entry_num>REMEMBER_COUNT-1) {
		entry_num=0;
		remember_lifo.entries_count--;
	}

	descriptor_ptr=first_type;
	while (descriptor_ptr!=NULL && !found) {
		if (strcmp (descriptor_ptr->name,"ext2_inode")==0)
			found=1;
		else
			descriptor_ptr=descriptor_ptr->next;
	}


	remember_lifo.offset [entry_num]=device_offset;
	remember_lifo.type [entry_num]=descriptor_ptr;
	strcpy (remember_lifo.name [entry_num],buffer);

	wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer);
	wrefresh (command_win);
}

void type_file___set (char *command_line)

{
	unsigned char tmp;
	char *ptr,buffer [80],*ch_ptr;
	int mode=HEX;

	ptr=parse_word (command_line,buffer);
	if (*ptr==0) {
		wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return;
	}

	ptr=parse_word (ptr,buffer);

	if (strcasecmp (buffer,"text")==0) {
		mode=TEXT;
		strcpy (buffer,ptr);
	}

	else if (strcasecmp (buffer,"hex")==0) {
		mode=HEX;
		ptr=parse_word (ptr,buffer);
	}

	if (*buffer==0) {
		wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return;
	}

	if (mode==HEX) {
		do {
			tmp=(unsigned char) strtol (buffer,NULL,16);
			file_info.buffer [file_info.offset_in_block]=tmp;
			file_info.offset_in_block++;
			ptr=parse_word (ptr,buffer);
			if (file_info.offset_in_block==file_system_info.block_size) {
				if (*ptr) {
					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
					refresh_command_win ();
				}
				file_info.offset_in_block--;
			}
		} while (*buffer) ;
	}

	else {
		ch_ptr=buffer;
		while (*ch_ptr) {
			tmp=(unsigned char) *ch_ptr++;
			file_info.buffer [file_info.offset_in_block]=tmp;
			file_info.offset_in_block++;
			if (file_info.offset_in_block==file_system_info.block_size) {
				if (*ch_ptr) {
					wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
					refresh_command_win ();
				}
				file_info.offset_in_block--;
			}
		}
	}

	strcpy (buffer,"show");dispatch (buffer);
}

void type_file___writedata (char *command_line)

{
	low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
	return;
}

long file_block_to_global_block (long file_block,struct struct_file_info *file_info_ptr)

{
	long last_direct,last_indirect,last_dindirect;

	last_direct=EXT2_NDIR_BLOCKS-1;
	last_indirect=last_direct+file_system_info.block_size/4;
	last_dindirect=last_indirect+(file_system_info.block_size/4)*(file_system_info.block_size/4);

	if (file_block <= last_direct) {
		file_info_ptr->level=0;
		return (file_info_ptr->inode_ptr->i_block [file_block]);
	}

	if (file_block <= last_indirect) {
		file_info_ptr->level=1;
		file_block=file_block-last_direct-1;
		return (return_indirect (file_info_ptr->inode_ptr->i_block [EXT2_IND_BLOCK],file_block));
	}

	if (file_block <= last_dindirect) {
		file_info_ptr->level=2;
		file_block=file_block-last_indirect-1;
		return (return_dindirect (file_info_ptr->inode_ptr->i_block [EXT2_DIND_BLOCK],file_block));
	}

	file_info_ptr->level=3;
	file_block=file_block-last_dindirect-1;
	return (return_tindirect (file_info_ptr->inode_ptr->i_block [EXT2_TIND_BLOCK],file_block));
}

long return_indirect (long table_block,long block_num)

{
	long block_table [EXT2_MAX_BLOCK_SIZE/4];

	low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size);
	return (block_table [block_num]);
}

long return_dindirect (long table_block,long block_num)

{
	long f_indirect;

	f_indirect=block_num/(file_system_info.block_size/4);
	f_indirect=return_indirect (table_block,f_indirect);
	return (return_indirect (f_indirect,block_num%(file_system_info.block_size/4)));
}

long return_tindirect (long table_block,long block_num)

{
	long s_indirect;

	s_indirect=block_num/((file_system_info.block_size/4)*(file_system_info.block_size/4));
	s_indirect=return_indirect (table_block,s_indirect);
	return (return_dindirect (s_indirect,block_num%((file_system_info.block_size/4)*(file_system_info.block_size/4))));
}
