Home | History | Annotate | Download | only in ext2ed
      1 /*
      2 
      3 /usr/src/ext2ed/inode_com.c
      4 
      5 A part of the extended file system 2 disk editor.
      6 
      7 Commands relevant to ext2_inode type.
      8 
      9 First written on: April 9 1995
     10 
     11 Copyright (C) 1995 Gadi Oxman
     12 
     13 */
     14 
     15 #include "config.h"
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #include <time.h>
     20 
     21 #include "ext2ed.h"
     22 
     23 void type_ext2_inode___prev (char *command_line)
     24 
     25 {
     26 
     27 	char *ptr,buffer [80];
     28 
     29 	long group_num,group_offset,entry_num,block_num,first_entry,last_entry;
     30 	long inode_num,mult=1;
     31 	struct ext2_group_desc desc;
     32 
     33 	ptr=parse_word (command_line,buffer);
     34 
     35 	if (*ptr!=0) {
     36 		ptr=parse_word (ptr,buffer);
     37 		mult=atol (buffer);
     38 	}
     39 
     40 	block_num=device_offset/file_system_info.block_size;
     41 
     42 	group_num=inode_offset_to_group_num (device_offset);
     43 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
     44 
     45 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
     46 
     47 	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
     48 
     49 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
     50 	inode_num=0;
     51 
     52 	if (entry_num-mult+1>0) {
     53 		device_offset-=sizeof (struct ext2_inode)*mult;
     54 		entry_num-=mult;
     55 
     56 		sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer);
     57 		strcpy (buffer,"show");dispatch (buffer);
     58 	}
     59 
     60 	else {
     61 		wprintw (command_win,"Error - Entry out of limits\n");refresh_command_win ();
     62 	}
     63 
     64 	if (entry_num==0) {
     65 		wprintw (command_win,"Reached first inode in current group descriptor\n");
     66 		refresh_command_win ();
     67 	}
     68 }
     69 
     70 void type_ext2_inode___next (char *command_line)
     71 
     72 {
     73 
     74 	char *ptr,buffer [80];
     75 
     76 	long group_num,group_offset,entry_num,block_num,first_entry,last_entry;
     77 	long inode_num,mult=1;
     78 	struct ext2_group_desc desc;
     79 
     80 	ptr=parse_word (command_line,buffer);
     81 
     82 	if (*ptr!=0) {
     83 		ptr=parse_word (ptr,buffer);
     84 		mult=atol (buffer);
     85 	}
     86 
     87 
     88 	block_num=device_offset/file_system_info.block_size;
     89 
     90 	group_num=inode_offset_to_group_num (device_offset);
     91 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
     92 
     93 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
     94 
     95 	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
     96 
     97 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
     98 	inode_num=0;
     99 
    100 	if (entry_num+mult-1<last_entry) {
    101 		device_offset+=sizeof (struct ext2_inode)*mult;
    102 		entry_num+=mult;
    103 
    104 		sprintf (buffer,"setoffset %ld",device_offset);dispatch (buffer);
    105 		strcpy (buffer,"show");dispatch (buffer);
    106 	}
    107 
    108 	else {
    109 		wprintw (command_win,"Error - Entry out of limits\n");refresh_command_win ();
    110 	}
    111 
    112 	if (entry_num==last_entry) {
    113 		wprintw (command_win,"Reached last inode in current group descriptor\n");
    114 		refresh_command_win ();
    115 	}
    116 }
    117 
    118 
    119 void type_ext2_inode___show (char *command_line)
    120 
    121 {
    122 	struct ext2_inode *inode_ptr;
    123 
    124 	unsigned short temp;
    125 	int i;
    126 
    127 	long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num;
    128 	struct ext2_group_desc desc;
    129 
    130 	block_num=device_offset/file_system_info.block_size;
    131 
    132 	group_num=inode_offset_to_group_num (device_offset);
    133 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
    134 
    135 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
    136 
    137 	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
    138 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
    139 	inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
    140 	inode_num+=entry_num;
    141 
    142 	inode_ptr=&type_data.u.t_ext2_inode;
    143 
    144 	show (command_line);
    145 
    146 	wmove (show_pad,0,40);wprintw (show_pad,"octal = %06o ",inode_ptr->i_mode);
    147 	for (i=6;i>=0;i-=3) {
    148 		temp=inode_ptr->i_mode & 0x1ff;
    149 		temp=temp >> i;
    150 		if (temp & 4)
    151 			wprintw (show_pad,"r");
    152 		else
    153 			wprintw (show_pad,"-");
    154 
    155 		if (temp & 2)
    156 			wprintw (show_pad,"w");
    157 		else
    158 			wprintw (show_pad,"-");
    159 
    160 		if (temp & 1)
    161 			wprintw (show_pad,"x");
    162 		else
    163 			wprintw (show_pad,"-");
    164 	}
    165 	wmove (show_pad,3,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_atime));
    166 	wmove (show_pad,4,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_ctime));
    167 	wmove (show_pad,5,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_mtime));
    168 	wmove (show_pad,6,40);wprintw (show_pad,"%s",ctime ((time_t *) &type_data.u.t_ext2_inode.i_dtime));
    169 
    170 	wmove (show_pad,10,40);
    171 	temp=inode_ptr->i_flags;
    172 
    173 	if (temp & EXT2_SECRM_FL)
    174 		wprintw (show_pad,"s");
    175 	else
    176 		wprintw (show_pad,"-");
    177 
    178 
    179 	if (temp & EXT2_UNRM_FL)
    180 		wprintw (show_pad,"u");
    181 	else
    182 		wprintw (show_pad,"-");
    183 
    184 	if (temp & EXT2_COMPR_FL)
    185 		wprintw (show_pad,"c");
    186 	else
    187 		wprintw (show_pad,"-");
    188 
    189 	if (temp & EXT2_SYNC_FL)
    190 		wprintw (show_pad,"S");
    191 	else
    192 		wprintw (show_pad,"-");
    193 
    194 	if (temp & EXT2_IMMUTABLE_FL)
    195 		wprintw (show_pad,"i");
    196 	else
    197 		wprintw (show_pad,"-");
    198 
    199 	if (temp & EXT2_APPEND_FL)
    200 		wprintw (show_pad,"a");
    201 	else
    202 		wprintw (show_pad,"-");
    203 
    204 	if (temp & EXT2_NODUMP_FL)
    205 		wprintw (show_pad,"d");
    206 	else
    207 		wprintw (show_pad,"-");
    208 
    209 	refresh_show_pad ();
    210 
    211 	wmove (show_win,1,0);
    212 
    213 	wprintw (show_win,"Inode %ld of %ld. Entry %ld of %ld in group descriptor %ld.\n"
    214 		,inode_num,file_system_info.super_block.s_inodes_count,entry_num,last_entry,group_num);
    215 
    216 	wprintw (show_win,"Inode type: ");
    217 
    218 	if (inode_num < EXT2_GOOD_OLD_FIRST_INO) {
    219 		switch (inode_num) {
    220 			case EXT2_BAD_INO:
    221 				wprintw (show_win,"Bad blocks inode - ");
    222 				break;
    223 			case EXT2_ROOT_INO:
    224 				wprintw (show_win,"Root inode - ");
    225 				break;
    226 			case EXT4_USR_QUOTA_INO:
    227 				wprintw (show_win,"User quota inode - ");
    228 				break;
    229 			case EXT4_GRP_QUOTA_INO:
    230 				wprintw (show_win,"Group quota inode - ");
    231 				break;
    232 			case EXT2_BOOT_LOADER_INO:
    233 				wprintw (show_win,"Boot loader inode - ");
    234 				break;
    235 			case EXT2_UNDEL_DIR_INO:
    236 				wprintw (show_win,"Undelete directory inode - ");
    237 				break;
    238 			default:
    239 				wprintw (show_win,"Reserved inode - ");
    240 				break;
    241 		}
    242 	}
    243 	if (type_data.u.t_ext2_inode.i_mode==0)
    244 		wprintw (show_win,"Free.            ");
    245 
    246 	if (S_ISREG (type_data.u.t_ext2_inode.i_mode))
    247 		wprintw (show_win,"File.            ");
    248 
    249 	if (S_ISDIR (type_data.u.t_ext2_inode.i_mode))
    250 		wprintw (show_win,"Directory.       ");
    251 
    252 	if (S_ISLNK (type_data.u.t_ext2_inode.i_mode)) {
    253 		wprintw (show_win,"Symbolic link.   ");
    254 		wmove (show_pad,12,40);
    255 
    256 		if (inode_ptr->i_size <= 60)
    257 			wprintw (show_pad,"-> %s",(char *) &type_data.u.t_ext2_inode.i_block [0]);
    258 		else
    259 			wprintw (show_pad,"Slow symbolic link\n");
    260 		refresh_show_pad ();
    261 	}
    262 
    263 	if (S_ISCHR (type_data.u.t_ext2_inode.i_mode))
    264 		wprintw (show_win,"Character device.");
    265 
    266 	if (S_ISBLK (type_data.u.t_ext2_inode.i_mode))
    267 		wprintw (show_win,"Block device.    ");
    268 
    269 	wprintw (show_win,"\n");refresh_show_win ();
    270 
    271 	if (entry_num==last_entry) {
    272 		wprintw (command_win,"Reached last inode in current group descriptor\n");
    273 		refresh_command_win ();
    274 	}
    275 
    276 	if (entry_num==first_entry) {
    277 		wprintw (command_win,"Reached first inode in current group descriptor\n");
    278 		refresh_command_win ();
    279 	}
    280 
    281 }
    282 
    283 void type_ext2_inode___entry (char *command_line)
    284 
    285 {
    286 	char *ptr,buffer [80];
    287 
    288 	long group_num,group_offset,entry_num,block_num,wanted_entry;
    289 	struct ext2_group_desc desc;
    290 
    291 	ptr=parse_word (command_line,buffer);
    292 	if (*ptr==0) return;
    293 	ptr=parse_word (ptr,buffer);
    294 	wanted_entry=atol (buffer);
    295 
    296 	block_num=device_offset/file_system_info.block_size;
    297 
    298 	group_num=inode_offset_to_group_num (device_offset);
    299 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
    300 
    301 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
    302 
    303 	entry_num=(device_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
    304 
    305 	if (wanted_entry > entry_num) {
    306 		sprintf (buffer,"next %ld",wanted_entry-entry_num);
    307 		dispatch (buffer);
    308 	}
    309 
    310 	else if (wanted_entry < entry_num) {
    311 		sprintf (buffer,"prev %ld",entry_num-wanted_entry);
    312 		dispatch (buffer);
    313 	}
    314 }
    315 
    316 void type_ext2_inode___group (char *command_line)
    317 
    318 {
    319 	char buffer [80];
    320 
    321 	long group_num,group_offset;
    322 
    323 	group_num=inode_offset_to_group_num (device_offset);
    324 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
    325 
    326 	sprintf (buffer,"setoffset %ld",group_offset);dispatch (buffer);
    327 	sprintf (buffer,"settype ext2_group_desc");dispatch (buffer);
    328 }
    329 
    330 void type_ext2_inode___file (char *command_line)
    331 
    332 {
    333 	char buffer [80];
    334 
    335 	if (!S_ISREG (type_data.u.t_ext2_inode.i_mode)) {
    336 		wprintw (command_win,"Error - Inode type is not file\n");refresh_command_win ();
    337 		return;
    338 	}
    339 
    340 	if (!init_file_info ()) {
    341 		wprintw (command_win,"Error - Unable to show file\n");refresh_command_win ();
    342 		return;
    343 	}
    344 
    345 	sprintf (buffer,"settype file");dispatch (buffer);
    346 }
    347 
    348 void type_ext2_inode___dir (char *command_line)
    349 
    350 {
    351 	char buffer [80];
    352 
    353 	if (!S_ISDIR (type_data.u.t_ext2_inode.i_mode)) {
    354 		wprintw (command_win,"Error - Inode type is not directory\n");refresh_command_win ();
    355 		return;
    356 	}
    357 
    358 /* It is very important to init first_file_info first, as search_dir_entries relies on it */
    359 
    360 	if (!init_dir_info (&first_file_info)) {
    361 		wprintw (command_win,"Error - Unable to show directory\n");refresh_command_win ();
    362 		return;
    363 	}
    364 
    365 	file_info=first_file_info;
    366 
    367 	sprintf (buffer,"settype dir");dispatch (buffer);
    368 }
    369 
    370 long inode_offset_to_group_num (long inode_offset)
    371 
    372 {
    373 	int found=0;
    374 	struct ext2_group_desc desc;
    375 
    376 	long block_num,group_offset,group_num;
    377 
    378 	block_num=inode_offset/file_system_info.block_size;
    379 
    380 	group_offset=file_system_info.first_group_desc_offset;
    381 	group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc);
    382 
    383 	while (!found && group_num>=0 && group_num<file_system_info.groups_count) {
    384 		low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
    385 		if (block_num>=desc.bg_inode_table && block_num<desc.bg_inode_table+file_system_info.blocks_per_group)
    386 			found=1;
    387 		else
    388 			group_offset+=sizeof (struct ext2_group_desc);
    389 		group_num=(group_offset-file_system_info.first_group_desc_offset)/sizeof (struct ext2_group_desc);
    390 	}
    391 
    392 	if (!found)
    393 		return (-1);
    394 
    395 	return (group_num);
    396 }
    397 
    398 
    399 
    400 long int inode_offset_to_inode_num (long inode_offset)
    401 
    402 {
    403 	long group_num,group_offset,entry_num,block_num,first_entry,last_entry,inode_num;
    404 	struct ext2_group_desc desc;
    405 
    406 	block_num=inode_offset/file_system_info.block_size;
    407 
    408 	group_num=inode_offset_to_group_num (inode_offset);
    409 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
    410 
    411 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
    412 
    413 	entry_num=(inode_offset-desc.bg_inode_table*file_system_info.block_size)/sizeof (struct ext2_inode);
    414 	first_entry=0;last_entry=file_system_info.super_block.s_inodes_per_group-1;
    415 	inode_num=group_num*file_system_info.super_block.s_inodes_per_group+1;
    416 	inode_num+=entry_num;
    417 
    418 	return (inode_num);
    419 }
    420 
    421 long int inode_num_to_inode_offset (long inode_num)
    422 
    423 {
    424 	long group_num,group_offset,inode_offset,inode_entry;
    425 	struct ext2_group_desc desc;
    426 
    427 	inode_num--;
    428 
    429 	group_num=inode_num/file_system_info.super_block.s_inodes_per_group;
    430 	inode_entry=inode_num%file_system_info.super_block.s_inodes_per_group;
    431 	group_offset=file_system_info.first_group_desc_offset+group_num*sizeof (struct ext2_group_desc);
    432 	low_read ((char *) &desc,sizeof (struct ext2_group_desc),group_offset);
    433 
    434 	inode_offset=desc.bg_inode_table*file_system_info.block_size+inode_entry*sizeof (struct ext2_inode);
    435 
    436 	return (inode_offset);
    437 }
    438