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