/*

/usr/src/ext2ed/inode_com.c

A part of the extended file system 2 disk editor.

Commands relevant to ext2_inode type.

First written on: April 9 1995

Copyright (C) 1995 Gadi Oxman

*/

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

#include "ext2ed.h"

void type_ext2_inode___prev (char *command_line)

{

	char *ptr,buffer [80];

	long group_num,group_offset,entry_num,block_num,first_entry,last_entry;
	long inode_num,mult=1;
	struct ext2_group_desc desc;

	ptr=parse_word (command_line,buffer);

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

	block_num=device_offset/file_system_info.block_size;

	group_num=inode_offset_to_group_num (device_offset);
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);

	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);

	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);

	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
	inode_num=0;

	if (entry_num-mult+1>0) {
		device_offset-=sizeof (struct ext2_inode)*mult;
		entry_num-=mult;

		sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer);
		strcpy (buffer,"show");dispatch (buffer);
	}

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

	if (entry_num==0) {
		wprintw (command_win,"Reached first inode in current group descriptor\n");
		refresh_command_win ();
	}
}

void type_ext2_inode___next (char *command_line)

{

	char *ptr,buffer [80];

	long group_num,group_offset,entry_num,block_num,first_entry,last_entry;
	long inode_num,mult=1;
	struct ext2_group_desc desc;

	ptr=parse_word (command_line,buffer);

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


	block_num=device_offset/file_system_info.block_size;

	group_num=inode_offset_to_group_num (device_offset);
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);

	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);

	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);

	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
	inode_num=0;

	if (entry_num+mult-1<last_entry) {
		device_offset+=sizeof (struct ext2_inode)*mult;
		entry_num+=mult;

		sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer);
		strcpy (buffer,"show");dispatch (buffer);
	}

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

	if (entry_num==last_entry) {
		wprintw (command_win,"Reached last inode in current group descriptor\n");
		refresh_command_win ();
	}
}


void type_ext2_inode___show (char *command_line)

{
	struct ext2_inode *inode_ptr;

	unsigned short temp;
	int i;

	long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num;
	struct ext2_group_desc desc;

	block_num=device_offset/file_system_info.block_size;

	group_num=inode_offset_to_group_num (device_offset);
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);

	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);

	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
	inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
	inode_num+=entry_num;

	inode_ptr=&type_data.u.t_ext2_inode;

	show (command_line);

	wmove (show_pad,0,40);wprintw (show_pad,"octal = %06o ",inode_ptr->i_mode);
	for (i=6;i>=0;i-=3) {
		temp=inode_ptr->i_mode & 0x1ff;
		temp=temp >> i;
		if (temp & 4)
			wprintw (show_pad,"r");
		else
			wprintw (show_pad,"-");

		if (temp & 2)
			wprintw (show_pad,"w");
		else
			wprintw (show_pad,"-");

		if (temp & 1)
			wprintw (show_pad,"x");
		else
			wprintw (show_pad,"-");
	}
	wmove (show_pad,3,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_atime));
	wmove (show_pad,4,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_ctime));
	wmove (show_pad,5,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_mtime));
	wmove (show_pad,6,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_dtime));

	wmove (show_pad,10,40);
	temp=inode_ptr->i_flags;

	if (temp & EXT2_SECRM_FL)
		wprintw (show_pad,"s");
	else
		wprintw (show_pad,"-");


	if (temp & EXT2_UNRM_FL)
		wprintw (show_pad,"u");
	else
		wprintw (show_pad,"-");

	if (temp & EXT2_COMPR_FL)
		wprintw (show_pad,"c");
	else
		wprintw (show_pad,"-");

	if (temp & EXT2_SYNC_FL)
		wprintw (show_pad,"S");
	else
		wprintw (show_pad,"-");

	if (temp & EXT2_IMMUTABLE_FL)
		wprintw (show_pad,"i");
	else
		wprintw (show_pad,"-");

	if (temp & EXT2_APPEND_FL)
		wprintw (show_pad,"a");
	else
		wprintw (show_pad,"-");

	if (temp & EXT2_NODUMP_FL)
		wprintw (show_pad,"d");
	else
		wprintw (show_pad,"-");

	refresh_show_pad ();

	wmove (show_win,1,0);

	wprintw (show_win,"Inode %ld of %ld. Entry %ld of %ld in group descriptor %ld.\n"
		,inode_num,file_system_info.super_block.s_inodes_count,entry_num,last_entry,group_num);

	wprintw (show_win,"Inode type: ");

	if (inode_num < EXT2_GOOD_OLD_FIRST_INO) {
		switch (inode_num) {
			case EXT2_BAD_INO:
				wprintw (show_win,"Bad blocks inode - ");
				break;
			case EXT2_ROOT_INO:
				wprintw (show_win,"Root inode - ");
				break;
			case EXT4_USR_QUOTA_INO:
				wprintw (show_win,"User quota inode - ");
				break;
			case EXT4_GRP_QUOTA_INO:
				wprintw (show_win,"Group quota inode - ");
				break;
			case EXT2_BOOT_LOADER_INO:
				wprintw (show_win,"Boot loader inode - ");
				break;
			case EXT2_UNDEL_DIR_INO:
				wprintw (show_win,"Undelete directory inode - ");
				break;
			default:
				wprintw (show_win,"Reserved inode - ");
				break;
		}
	}
	if (type_data.u.t_ext2_inode.i_mode==0)
		wprintw (show_win,"Free.            ");

	if (S_ISREG (type_data.u.t_ext2_inode.i_mode))
		wprintw (show_win,"File.            ");

	if (S_ISDIR (type_data.u.t_ext2_inode.i_mode))
		wprintw (show_win,"Directory.       ");

	if (S_ISLNK (type_data.u.t_ext2_inode.i_mode)) {
		wprintw (show_win,"Symbolic link.   ");
		wmove (show_pad,12,40);

		if (inode_ptr->i_size <= 60)
			wprintw (show_pad,"-> %s",(char *) &type_data.u.t_ext2_inode.i_block [0]);
		else
			wprintw (show_pad,"Slow symbolic link\n");
		refresh_show_pad ();
	}

	if (S_ISCHR (type_data.u.t_ext2_inode.i_mode))
		wprintw (show_win,"Character device.");

	if (S_ISBLK (type_data.u.t_ext2_inode.i_mode))
		wprintw (show_win,"Block device.    ");

	wprintw (show_win,"\n");refresh_show_win ();

	if (entry_num==last_entry) {
		wprintw (command_win,"Reached last inode in current group descriptor\n");
		refresh_command_win ();
	}

	if (entry_num==first_entry) {
		wprintw (command_win,"Reached first inode in current group descriptor\n");
		refresh_command_win ();
	}

}

void type_ext2_inode___entry (char *command_line)

{
	char *ptr,buffer [80];

	long group_num,group_offset,entry_num,block_num,wanted_entry;
	struct ext2_group_desc desc;

	ptr=parse_word (command_line,buffer);
	if (*ptr==0) return;
	ptr=parse_word (ptr,buffer);
	wanted_entry=atol (buffer);

	block_num=device_offset/file_system_info.block_size;

	group_num=inode_offset_to_group_num (device_offset);
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);

	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);

	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);

	if (wanted_entry > entry_num) {
		sprintf (buffer,"next %ld",wanted_entry-entry_num);
		dispatch (buffer);
	}

	else if (wanted_entry < entry_num) {
		sprintf (buffer,"prev %ld",entry_num-wanted_entry);
		dispatch (buffer);
	}
}

void type_ext2_inode___group (char *command_line)

{
	char buffer [80];

	long group_num,group_offset;

	group_num=inode_offset_to_group_num (device_offset);
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);

	sprintf (buffer,"setoffset %ld",group_offset);dispatch (buffer);
	sprintf (buffer,"settype ext2_group_desc");dispatch (buffer);
}

void type_ext2_inode___file (char *command_line)

{
	char buffer [80];

	if (!S_ISREG (type_data.u.t_ext2_inode.i_mode)) {
		wprintw (command_win,"Error - Inode type is not file\n");refresh_command_win ();
		return;
	}

	if (!init_file_info ()) {
		wprintw (command_win,"Error - Unable to show file\n");refresh_command_win ();
		return;
	}

	sprintf (buffer,"settype file");dispatch (buffer);
}

void type_ext2_inode___dir (char *command_line)

{
	char buffer [80];

	if (!S_ISDIR (type_data.u.t_ext2_inode.i_mode)) {
		wprintw (command_win,"Error - Inode type is not directory\n");refresh_command_win ();
		return;
	}

/* It is very important to init first_file_info first, as search_dir_entries relies on it */

	if (!init_dir_info (&first_file_info)) {
		wprintw (command_win,"Error - Unable to show directory\n");refresh_command_win ();
		return;
	}

	file_info=first_file_info;

	sprintf (buffer,"settype dir");dispatch (buffer);
}

long inode_offset_to_group_num (long inode_offset)

{
	int found=0;
	struct ext2_group_desc desc;

	long block_num,group_offset,group_num;

	block_num=inode_offset/file_system_info.block_size;

	group_offset=file_system_info.first_group_desc_offset;
	group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc);

	while (!found && group_num>=0 && group_num<file_system_info.groups_count) {
		low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
		if (block_num>=desc.bg_inode_table && block_num<desc.bg_inode_table+file_system_info.blocks_per_group)
			found=1;
		else
			group_offset+=sizeof (struct ext2_group_desc);
		group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc);
	}

	if (!found)
		return (-1);

	return (group_num);
}



long int inode_offset_to_inode_num (long inode_offset)

{
	long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num;
	struct ext2_group_desc desc;

	block_num=inode_offset/file_system_info.block_size;

	group_num=inode_offset_to_group_num (inode_offset);
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);

	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);

	entry_num=(inode_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
	inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
	inode_num+=entry_num;

	return (inode_num);
}

long int inode_num_to_inode_offset (long inode_num)

{
	long group_num,group_offset,inode_offset,inode_entry;
	struct ext2_group_desc desc;

	inode_num--;

	group_num=inode_num/file_system_info.super_block.s_inodes_per_group;
	inode_entry=inode_num%file_system_info.super_block.s_inodes_per_group;
	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);

	inode_offset=desc.bg_inode_table*file_system_info.block_size+inode_entry*sizeof (struct ext2_inode);

	return (inode_offset);
}
