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