1 /* 2 3 /usr/src/ext2ed/file_com.c 4 5 A part of the extended file system 2 disk editor. 6 7 ---------------------------- 8 Commands which handle a file 9 ---------------------------- 10 11 First written on: April 18 1995 12 13 Copyright (C) 1995 Gadi Oxman 14 15 */ 16 17 #include "config.h" 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #include "ext2ed.h" 23 24 int init_file_info (void) 25 26 { 27 struct ext2_inode *ptr; 28 29 ptr=&type_data.u.t_ext2_inode; 30 31 file_info.inode_ptr=ptr; 32 file_info.inode_offset=device_offset; 33 34 file_info.global_block_num=ptr->i_block [0]; 35 file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size; 36 file_info.block_num=0; 37 file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size; 38 file_info.file_offset=0; 39 file_info.file_length=ptr->i_size; 40 file_info.level=0; 41 file_info.offset_in_block=0; 42 43 file_info.display=HEX; 44 45 low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); 46 47 return (1); 48 } 49 50 51 void type_file___inode (char *command_line) 52 53 { 54 dispatch ("settype ext2_inode"); 55 } 56 57 void type_file___show (char *command_line) 58 59 { 60 if (file_info.display==HEX) 61 file_show_hex (); 62 if (file_info.display==TEXT) 63 file_show_text (); 64 } 65 66 void type_file___nextblock (char *command_line) 67 68 { 69 long block_offset=1; 70 char *ptr,buffer [80]; 71 72 ptr=parse_word (command_line,buffer); 73 74 if (*ptr!=0) { 75 ptr=parse_word (ptr,buffer); 76 block_offset*=atol (buffer); 77 } 78 79 if (file_info.block_num+block_offset >= file_info.blocks_count) { 80 wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); 81 return; 82 } 83 84 file_info.block_num+=block_offset; 85 file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); 86 file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; 87 file_info.file_offset=file_info.block_num*file_system_info.block_size; 88 89 low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); 90 91 strcpy (buffer,"show");dispatch (buffer); 92 } 93 94 void type_file___next (char *command_line) 95 96 { 97 int offset=1; 98 char *ptr,buffer [80]; 99 100 ptr=parse_word (command_line,buffer); 101 102 if (*ptr!=0) { 103 ptr=parse_word (ptr,buffer); 104 offset*=atol (buffer); 105 } 106 107 if (file_info.offset_in_block+offset < file_system_info.block_size) { 108 file_info.offset_in_block+=offset; 109 sprintf (buffer,"show");dispatch (buffer); 110 } 111 112 else { 113 wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); 114 } 115 } 116 117 void type_file___offset (char *command_line) 118 119 { 120 unsigned long offset; 121 char *ptr,buffer [80]; 122 123 ptr=parse_word (command_line,buffer); 124 125 if (*ptr!=0) { 126 ptr=parse_word (ptr,buffer); 127 offset=atol (buffer); 128 } 129 else { 130 wprintw (command_win,"Error - Argument not specified\n");refresh_command_win (); 131 return; 132 } 133 134 if (offset < file_system_info.block_size) { 135 file_info.offset_in_block=offset; 136 sprintf (buffer,"show");dispatch (buffer); 137 } 138 139 else { 140 wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); 141 } 142 } 143 144 void type_file___prev (char *command_line) 145 146 { 147 int offset=1; 148 char *ptr,buffer [80]; 149 150 ptr=parse_word (command_line,buffer); 151 152 if (*ptr!=0) { 153 ptr=parse_word (ptr,buffer); 154 offset*=atol (buffer); 155 } 156 157 if (file_info.offset_in_block-offset >= 0) { 158 file_info.offset_in_block-=offset; 159 sprintf (buffer,"show");dispatch (buffer); 160 } 161 162 else { 163 wprintw (command_win,"Error - Offset out of block\n");refresh_command_win (); 164 } 165 } 166 167 void type_file___prevblock (char *command_line) 168 169 { 170 long block_offset=1; 171 char *ptr,buffer [80]; 172 173 ptr=parse_word (command_line,buffer); 174 175 if (*ptr!=0) { 176 ptr=parse_word (ptr,buffer); 177 block_offset*=atol (buffer); 178 } 179 180 if (file_info.block_num-block_offset < 0) { 181 wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); 182 return; 183 } 184 185 file_info.block_num-=block_offset; 186 file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); 187 file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; 188 file_info.file_offset=file_info.block_num*file_system_info.block_size; 189 190 low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); 191 192 strcpy (buffer,"show");dispatch (buffer); 193 } 194 195 void type_file___block (char *command_line) 196 197 { 198 long block_offset=1; 199 char *ptr,buffer [80]; 200 201 ptr=parse_word (command_line,buffer); 202 203 if (*ptr==0) { 204 wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win); 205 return; 206 } 207 208 ptr=parse_word (ptr,buffer); 209 block_offset=atol (buffer); 210 211 if (block_offset < 0 || block_offset >= file_info.blocks_count) { 212 wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win); 213 return; 214 } 215 216 file_info.block_num=block_offset; 217 file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info); 218 file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size; 219 file_info.file_offset=file_info.block_num*file_system_info.block_size; 220 221 low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); 222 223 strcpy (buffer,"show");dispatch (buffer); 224 } 225 226 void type_file___display (char *command_line) 227 228 { 229 char *ptr,buffer [80]; 230 231 ptr=parse_word (command_line,buffer); 232 if (*ptr==0) 233 strcpy (buffer,"hex"); 234 else 235 ptr=parse_word (ptr,buffer); 236 237 if (strcasecmp (buffer,"hex")==0) { 238 wprintw (command_win,"Display set to hex\n");wrefresh (command_win); 239 file_info.display=HEX; 240 sprintf (buffer,"show");dispatch (buffer); 241 } 242 243 else if (strcasecmp (buffer,"text")==0) { 244 wprintw (command_win,"Display set to text\n");wrefresh (command_win); 245 file_info.display=TEXT; 246 sprintf (buffer,"show");dispatch (buffer); 247 } 248 249 else { 250 wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win); 251 } 252 } 253 254 void file_show_hex (void) 255 256 { 257 long offset=0,l,i; 258 unsigned char *ch_ptr; 259 260 /* device_offset and type_data points to the inode */ 261 262 show_pad_info.line=0; 263 264 wmove (show_pad,0,0); 265 ch_ptr=file_info.buffer; 266 for (l=0;l<file_system_info.block_size/16;l++) { 267 if (file_info.file_offset+offset>file_info.file_length-1) break; 268 wprintw (show_pad,"%08ld : ",offset); 269 for (i=0;i<16;i++) { 270 271 if (file_info.file_offset+offset+i>file_info.file_length-1) { 272 wprintw (show_pad," "); 273 } 274 275 else { 276 if (file_info.offset_in_block==offset+i) 277 wattrset (show_pad,A_REVERSE); 278 279 if (ch_ptr [i]>=' ' && ch_ptr [i]<='z') 280 wprintw (show_pad,"%c",ch_ptr [i]); 281 else 282 wprintw (show_pad,"."); 283 284 if (file_info.offset_in_block==offset+i) 285 wattrset (show_pad,A_NORMAL); 286 } 287 } 288 289 wprintw (show_pad," "); 290 for (i=0;i<16;i++) { 291 if (file_info.file_offset+offset+i>file_info.file_length-1) break; 292 if (file_info.offset_in_block==offset+i) 293 wattrset (show_pad,A_REVERSE); 294 295 wprintw (show_pad,"%02x",ch_ptr [i]); 296 297 if (file_info.offset_in_block==offset+i) { 298 wattrset (show_pad,A_NORMAL); 299 show_pad_info.line=l-l % show_pad_info.display_lines; 300 } 301 302 wprintw (show_pad," "); 303 304 } 305 306 wprintw (show_pad,"\n"); 307 offset+=i; 308 ch_ptr+=i; 309 } 310 311 show_pad_info.max_line=l-1; 312 313 refresh_show_pad (); 314 315 show_status (); 316 } 317 318 void file_show_text (void) 319 320 { 321 long offset=0,last_offset,l=0,cols=0; 322 unsigned char *ch_ptr; 323 324 /* device_offset and type_data points to the inode */ 325 326 show_pad_info.line=0; 327 wmove (show_pad,0,0); 328 ch_ptr=file_info.buffer; 329 330 last_offset=file_system_info.block_size-1; 331 332 if (file_info.file_offset+last_offset > file_info.file_length-1) 333 last_offset=file_info.file_length-1-file_info.file_offset; 334 335 while ( (offset <= last_offset) && l<SHOW_PAD_LINES) { 336 337 if (cols==SHOW_PAD_COLS-1) { 338 wprintw (show_pad,"\n"); 339 l++;cols=0; 340 } 341 342 343 if (file_info.offset_in_block==offset) 344 wattrset (show_pad,A_REVERSE); 345 346 if (*ch_ptr >= ' ' && *ch_ptr <= 'z') 347 wprintw (show_pad,"%c",*ch_ptr); 348 349 350 else { 351 if (*ch_ptr == 0xa) { 352 wprintw (show_pad,"\n"); 353 l++;cols=0; 354 } 355 356 else if (*ch_ptr == 0x9) 357 wprintw (show_pad," "); 358 359 else 360 wprintw (show_pad,"."); 361 } 362 363 if (file_info.offset_in_block==offset) { 364 wattrset (show_pad,A_NORMAL); 365 show_pad_info.line=l-l % show_pad_info.display_lines; 366 } 367 368 369 offset++;cols++;ch_ptr++; 370 } 371 372 wprintw (show_pad,"\n"); 373 show_pad_info.max_line=l; 374 375 refresh_show_pad (); 376 377 show_status (); 378 } 379 380 void show_status (void) 381 382 { 383 long inode_num; 384 385 werase (show_win);wmove (show_win,0,0); 386 wprintw (show_win,"File contents. Block %ld. ",file_info.global_block_num); 387 wprintw (show_win,"File block %ld of %ld. ",file_info.block_num,file_info.blocks_count-1); 388 wprintw (show_win,"File Offset %ld of %ld.",file_info.file_offset,file_info.file_length-1); 389 390 wmove (show_win,1,0); 391 inode_num=inode_offset_to_inode_num (file_info.inode_offset); 392 wprintw (show_win,"File inode %ld. Indirection level %ld.",inode_num,file_info.level); 393 394 refresh_show_win (); 395 } 396 397 void type_file___remember (char *command_line) 398 399 { 400 int found=0; 401 long entry_num; 402 char *ptr,buffer [80]; 403 struct struct_descriptor *descriptor_ptr; 404 405 ptr=parse_word (command_line,buffer); 406 407 if (*ptr==0) { 408 wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win); 409 return; 410 } 411 412 ptr=parse_word (ptr,buffer); 413 414 entry_num=remember_lifo.entries_count++; 415 if (entry_num>REMEMBER_COUNT-1) { 416 entry_num=0; 417 remember_lifo.entries_count--; 418 } 419 420 descriptor_ptr=first_type; 421 while (descriptor_ptr!=NULL && !found) { 422 if (strcmp (descriptor_ptr->name,"ext2_inode")==0) 423 found=1; 424 else 425 descriptor_ptr=descriptor_ptr->next; 426 } 427 428 429 remember_lifo.offset [entry_num]=device_offset; 430 remember_lifo.type [entry_num]=descriptor_ptr; 431 strcpy (remember_lifo.name [entry_num],buffer); 432 433 wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer); 434 wrefresh (command_win); 435 } 436 437 void type_file___set (char *command_line) 438 439 { 440 unsigned char tmp; 441 char *ptr,buffer [80],*ch_ptr; 442 int mode=HEX; 443 444 ptr=parse_word (command_line,buffer); 445 if (*ptr==0) { 446 wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return; 447 } 448 449 ptr=parse_word (ptr,buffer); 450 451 if (strcasecmp (buffer,"text")==0) { 452 mode=TEXT; 453 strcpy (buffer,ptr); 454 } 455 456 else if (strcasecmp (buffer,"hex")==0) { 457 mode=HEX; 458 ptr=parse_word (ptr,buffer); 459 } 460 461 if (*buffer==0) { 462 wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return; 463 } 464 465 if (mode==HEX) { 466 do { 467 tmp=(unsigned char) strtol (buffer,NULL,16); 468 file_info.buffer [file_info.offset_in_block]=tmp; 469 file_info.offset_in_block++; 470 ptr=parse_word (ptr,buffer); 471 if (file_info.offset_in_block==file_system_info.block_size) { 472 if (*ptr) { 473 wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n"); 474 refresh_command_win (); 475 } 476 file_info.offset_in_block--; 477 } 478 } while (*buffer) ; 479 } 480 481 else { 482 ch_ptr=buffer; 483 while (*ch_ptr) { 484 tmp=(unsigned char) *ch_ptr++; 485 file_info.buffer [file_info.offset_in_block]=tmp; 486 file_info.offset_in_block++; 487 if (file_info.offset_in_block==file_system_info.block_size) { 488 if (*ch_ptr) { 489 wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n"); 490 refresh_command_win (); 491 } 492 file_info.offset_in_block--; 493 } 494 } 495 } 496 497 strcpy (buffer,"show");dispatch (buffer); 498 } 499 500 void type_file___writedata (char *command_line) 501 502 { 503 low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); 504 return; 505 } 506 507 long file_block_to_global_block (long file_block,struct struct_file_info *file_info_ptr) 508 509 { 510 long last_direct,last_indirect,last_dindirect; 511 512 last_direct=EXT2_NDIR_BLOCKS-1; 513 last_indirect=last_direct+file_system_info.block_size/4; 514 last_dindirect=last_indirect+(file_system_info.block_size/4)*(file_system_info.block_size/4); 515 516 if (file_block <= last_direct) { 517 file_info_ptr->level=0; 518 return (file_info_ptr->inode_ptr->i_block [file_block]); 519 } 520 521 if (file_block <= last_indirect) { 522 file_info_ptr->level=1; 523 file_block=file_block-last_direct-1; 524 return (return_indirect (file_info_ptr->inode_ptr->i_block [EXT2_IND_BLOCK],file_block)); 525 } 526 527 if (file_block <= last_dindirect) { 528 file_info_ptr->level=2; 529 file_block=file_block-last_indirect-1; 530 return (return_dindirect (file_info_ptr->inode_ptr->i_block [EXT2_DIND_BLOCK],file_block)); 531 } 532 533 file_info_ptr->level=3; 534 file_block=file_block-last_dindirect-1; 535 return (return_tindirect (file_info_ptr->inode_ptr->i_block [EXT2_TIND_BLOCK],file_block)); 536 } 537 538 long return_indirect (long table_block,long block_num) 539 540 { 541 long block_table [EXT2_MAX_BLOCK_SIZE/4]; 542 543 low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size); 544 return (block_table [block_num]); 545 } 546 547 long return_dindirect (long table_block,long block_num) 548 549 { 550 long f_indirect; 551 552 f_indirect=block_num/(file_system_info.block_size/4); 553 f_indirect=return_indirect (table_block,f_indirect); 554 return (return_indirect (f_indirect,block_num%(file_system_info.block_size/4))); 555 } 556 557 long return_tindirect (long table_block,long block_num) 558 559 { 560 long s_indirect; 561 562 s_indirect=block_num/((file_system_info.block_size/4)*(file_system_info.block_size/4)); 563 s_indirect=return_indirect (table_block,s_indirect); 564 return (return_dindirect (s_indirect,block_num%((file_system_info.block_size/4)*(file_system_info.block_size/4)))); 565 } 566