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