438 lines
11 KiB
C
438 lines
11 KiB
C
/*
|
|
|
|
/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 "config.h"
|
|
#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);
|
|
}
|