00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <minix/config.h>
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 #include <fcntl.h>
00016 #include <limits.h>
00017 #include <grp.h>
00018 #include <pwd.h>
00019 #include <stdarg.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <termcap.h>
00023 #include <time.h>
00024 #include <unistd.h>
00025
00026 #include <minix/const.h>
00027 #include <minix/type.h>
00028 #include "../../servers/mfs/const.h"
00029 #include "../../servers/mfs/type.h"
00030 #include "../../servers/mfs/inode.h"
00031 #include <minix/fslib.h>
00032
00033 #include "de.h"
00034
00035 #ifndef major
00036 #define major(x) ( (x>>8) & 0377)
00037 #define minor(x) (x & 0377)
00038 #endif
00039
00040
00041
00042
00043
00044
00045 #define TC_BUFFER 1024
00046 #define TC_STRINGS 200
00047
00048
00049 static char *Tmove;
00050 static char *Tclr_all;
00051 static char *Treverse;
00052 static char *Tnormal;
00053
00054 char Kup = 0;
00055 char Kdown = 0;
00056 char Kleft = 0;
00057 char Kright = 0;
00058
00059 _PROTOTYPE(void Goto , (int column , int line ));
00060 _PROTOTYPE(void Block_Type , (de_state *s ));
00061 _PROTOTYPE(void Draw_Words , (de_state *s ));
00062 _PROTOTYPE(void Draw_Info , (de_state *s ));
00063 _PROTOTYPE(void Draw_Block , (char *block ));
00064 _PROTOTYPE(void Draw_Map , (char *block , int max_bits ));
00065 _PROTOTYPE(void Draw_Offset , (de_state *s ));
00066 _PROTOTYPE(void Word_Pointers , (off_t old_addr , off_t new_addr ));
00067 _PROTOTYPE(void Block_Pointers , (off_t old_addr , off_t new_addr ));
00068 _PROTOTYPE(void Map_Pointers , (off_t old_addr , off_t new_addr ));
00069 _PROTOTYPE(void Print_Number , (Word_t number , int output_base ));
00070 _PROTOTYPE(void Draw_Zone_Numbers , (de_state *s , struct inode *inode ,
00071 int zindex , int zrow ));
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 int Init_Termcap()
00086
00087 {
00088 char *term;
00089 char buffer[ TC_BUFFER ];
00090 static char strings[ TC_STRINGS ];
00091 char *s = &strings[0];
00092 char *Kcode;
00093
00094
00095 term = getenv( "TERM" );
00096
00097 if ( term == NULL )
00098 return( 0 );
00099
00100 if ( tgetent( buffer, term ) != 1 )
00101 return( 0 );
00102
00103
00104 if ( (Tmove = tgetstr( "cm", &s )) == NULL )
00105 return( 0 );
00106
00107 if ( (Tclr_all = tgetstr( "cl", &s )) == NULL )
00108 return( 0 );
00109
00110 if ( (Treverse = tgetstr( "so", &s )) == NULL )
00111 {
00112 Treverse = Tnormal = s;
00113 *s = '\0';
00114 ++s;
00115 }
00116 else if ( (Tnormal = tgetstr( "se", &s )) == NULL )
00117 return( 0 );
00118
00119
00120
00121
00122 if ( (Kcode = tgetstr( "ku", &s )) != NULL && strlen( Kcode ) == 1 )
00123 Kup = Kcode[0];
00124
00125 if ( (Kcode = tgetstr( "kd", &s )) != NULL && strlen( Kcode ) == 1 )
00126 Kdown = Kcode[0];
00127
00128 if ( (Kcode = tgetstr( "kl", &s )) != NULL && strlen( Kcode ) == 1 )
00129 Kleft = Kcode[0];
00130
00131 if ( (Kcode = tgetstr( "kr", &s )) != NULL && strlen( Kcode ) == 1 )
00132 Kright = Kcode[0];
00133
00134
00135 return( 1 );
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 void Goto( column, line )
00153 int column;
00154 int line;
00155
00156 {
00157 fputs( tgoto( Tmove, column, line ), stdout );
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 void Draw_Help_Screen( s )
00180 de_state *s;
00181
00182 {
00183 int down;
00184 int right;
00185
00186 switch ( s->mode )
00187 {
00188 case WORD : down = 2; right = 32; break;
00189 case BLOCK : down = 64; right = 1; break;
00190 case MAP : down = 256; right = 4; break;
00191 }
00192
00193 printf( "%s ", Tclr_all );
00194 printf( "%sDE COMMANDS%s\r\n\n\n", Treverse, Tnormal );
00195
00196
00197 printf( " PGUP b Back one block h Help\r\n" );
00198 printf( " PGDN f Forward one block q Quit\r\n" );
00199 printf( " HOME B Goto first block m Minix shell\r\n" );
00200 printf( " END F Goto last block\r\n" );
00201 printf( " v Visual mode (w b m)\r\n" );
00202 printf( " g Goto specified block o Output base (h d o b)\r\n" );
00203 printf( " G Goto block indirectly\r\n" );
00204 printf( " i Goto i-node c Change file name\r\n" );
00205 printf( " I Filename to i-node w Write ASCII block\r\n" );
00206 printf( " W Write block exactly\r\n" );
00207 printf( " / Search\r\n" );
00208 printf( " n Next occurrence x Extract lost entry\r\n" );
00209 printf( " p Previous address X Extract lost blocks\r\n" );
00210 printf( " s Store word\r\n" );
00211 printf( " UP u Move back %d bytes\r\n", down );
00212 printf( " DOWN d Move forward %d bytes\r\n", down );
00213 printf( " LEFT l Move back %d byte%s\r\n", right,
00214 right == 1 ? "" : "s" );
00215 printf( " RIGHT r Move forward %d byte%s\r\n\n\n", right,
00216 right == 1 ? "" : "s" );
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 void Wait_For_Key()
00234
00235 {
00236 Draw_Prompt( "Press a key to continue..." );
00237
00238 Get_Char();
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 void Draw_Prompt( string )
00256 char *string;
00257
00258 {
00259 Goto( PROMPT_COLUMN, PROMPT_LINE );
00260
00261 printf( "%s%s%s ", Treverse, string, Tnormal );
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 void Erase_Prompt()
00279
00280 {
00281 Goto( PROMPT_COLUMN, PROMPT_LINE );
00282
00283 printf( "%77c", ' ' );
00284
00285 Goto( PROMPT_COLUMN, PROMPT_LINE );
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 void Draw_Screen( s )
00303 de_state *s;
00304
00305 {
00306 fputs( Tclr_all, stdout );
00307
00308 Draw_Strings( s );
00309 Block_Type( s );
00310
00311 switch ( s->mode )
00312 {
00313 case WORD : Draw_Words( s );
00314 Draw_Info( s );
00315 break;
00316
00317 case BLOCK : Draw_Block( s->buffer );
00318 break;
00319
00320 case MAP : {
00321 int max_bits = 2 * K;
00322
00323
00324
00325
00326 if ( s->block == 2 + s->inode_maps - 1 )
00327 max_bits = (int)
00328 (s->inodes_in_map
00329 - CHAR_BIT * K * (ino_t) (s->inode_maps - 1)
00330 - CHAR_BIT * (ino_t) (s->offset & ~ MAP_MASK));
00331
00332 else if ( s->block == 2 + s->inode_maps + s->zone_maps - 1 )
00333 max_bits = (int)
00334 (s->zones_in_map
00335 - CHAR_BIT * K * (zone_t) (s->zone_maps - 1)
00336 - CHAR_BIT * (zone_t) (s->offset & ~ MAP_MASK));
00337
00338 if ( max_bits < 0 )
00339 max_bits = 0;
00340
00341 Draw_Map( &s->buffer[ s->offset & ~ MAP_MASK ], max_bits );
00342 break;
00343 }
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 void Draw_Strings( s )
00367 de_state *s;
00368
00369 {
00370 int len;
00371 int i;
00372
00373 Goto( STATUS_COLUMN, STATUS_LINE );
00374
00375 printf( "Device %s= %-14.14s ",
00376 s->device_mode == O_RDONLY ? "" : "(w) ", s->device_name );
00377
00378 switch ( s->magic )
00379 {
00380 case SUPER_MAGIC : printf( "V1 file system ");
00381 break;
00382 case SUPER_REV : printf( "V1-bytes-swapped file system (?) ");
00383 break;
00384 case SUPER_V2 : printf( "V2 file system ");
00385 break;
00386 case SUPER_V2_REV : printf( "V2-bytes-swapped file system (?) ");
00387 break;
00388 case SUPER_V3 : printf( "V3 file system ");
00389 break;
00390 default : printf( "not a Minix file system ");
00391 break;
00392 }
00393
00394 len = strlen( s->file_name );
00395
00396 if ( len == 0 )
00397 printf( "%29s", " " );
00398 else if ( len <= 20 )
00399 printf( "File = %-20s ", s->file_name );
00400 else
00401 printf( "File = ...%17.17s ", s->file_name + len - 17 );
00402
00403
00404 len = strlen( s->search_string );
00405
00406 if ( len == 0 )
00407 printf( "%20s", " " );
00408 else
00409 {
00410 printf( "Search = " );
00411
00412 if ( len <= 11 )
00413 {
00414 for ( i = 0; i < len; ++i )
00415 Print_Ascii( s->search_string[ i ] );
00416
00417 for ( ; i < 11; ++i )
00418 putchar( ' ' );
00419 }
00420 else
00421 {
00422 for ( i = 0; i < 8; ++i )
00423 Print_Ascii( s->search_string[ i ] );
00424
00425 printf( "..." );
00426 }
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 void Block_Type( s )
00445 de_state *s;
00446
00447 {
00448 Goto( STATUS_COLUMN, STATUS_LINE + 1 );
00449
00450 printf( "Block = %5u of %-5u ", s->block, s->zones );
00451
00452 if ( !s->is_fs )
00453 return;
00454
00455 if ( s->block == BOOT_BLOCK )
00456 printf( "Boot block" );
00457
00458 else if ( s->block == 1 )
00459 printf( "Super block" );
00460
00461 else if ( s->block < 2 + s->inode_maps )
00462 printf( "I-node bit map" );
00463
00464 else if ( s->block < 2 + s->inode_maps + s->zone_maps )
00465 printf( "Zone bit map" );
00466
00467 else if ( s->block < s->first_data )
00468 printf( "I-nodes" );
00469
00470 else
00471 printf( "Data block (%sin use)",
00472 In_Use( (bit_t) (s->block - (s->first_data - 1)), s->zone_map )
00473 ? "" : "not " );
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 void Draw_Words( s )
00491 de_state *s;
00492
00493 {
00494 int line;
00495 int addr = s->offset & ~ PAGE_MASK;
00496
00497
00498 for ( line = 0; line < 16; ++line, addr += 2 )
00499 {
00500 Goto( BLOCK_COLUMN, BLOCK_LINE + line );
00501
00502 printf( "%5d ", addr );
00503
00504 Print_Number( *( (word_t *) &s->buffer[ addr ] ), s->output_base );
00505 }
00506
00507 Goto( BLOCK_COLUMN + 64, BLOCK_LINE );
00508 printf( "(base %d)", s->output_base );
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529 char *super_block_info[] = { "number of inodes",
00530 "V1 number of zones",
00531 "inode bit map blocks",
00532 "zone bit map blocks",
00533 "first data zone",
00534 "blocks per zone shift & flags",
00535 "maximum file size",
00536 "",
00537 "magic number",
00538 "fsck magic number",
00539 "V2 number of zones" };
00540
00541
00542 void Draw_Info( s )
00543 de_state *s;
00544
00545 {
00546 int i;
00547 int page = s->offset >> PAGE_SHIFT;
00548 dev_t dev;
00549
00550
00551 if ( s->is_fs && s->block == 1 && page == 0 )
00552 for ( i = 0; i < 11; ++i )
00553 {
00554 Goto( INFO_COLUMN, INFO_LINE + i );
00555 printf( "%s", super_block_info[ i ] );
00556 }
00557
00558 else if ( s->is_fs && s->block >= s->first_data - s->inode_blocks &&
00559 s->block < s->first_data )
00560 {
00561 struct inode core_inode;
00562 d1_inode *dip1;
00563 d2_inode *dip2;
00564 struct inode *inode = &core_inode;
00565 int special = 0;
00566 int m;
00567 struct passwd *user;
00568 struct group *grp;
00569
00570 dip1 = (d1_inode *) &s->buffer[ s->offset & ~ PAGE_MASK ];
00571 dip2 = (d2_inode *) &s->buffer[ s->offset & ~ PAGE_MASK
00572 & ~ (V2_INODE_SIZE-1) ];
00573 conv_inode( inode, dip1, dip2, READING, s->magic );
00574
00575 user = getpwuid( inode->i_uid );
00576 grp = getgrgid( inode->i_gid );
00577
00578 if ( s->magic != SUPER_MAGIC && page & 1 )
00579 {
00580 Draw_Zone_Numbers( s, inode, 2, 0 );
00581 return;
00582 }
00583
00584 Goto( INFO_COLUMN, INFO_LINE );
00585
00586 switch( inode->i_mode & S_IFMT )
00587 {
00588 case S_IFDIR : printf( "directory " );
00589 break;
00590
00591 case S_IFCHR : printf( "character " );
00592 special = 1;
00593 break;
00594
00595 case S_IFBLK : printf( "block " );
00596 special = 1;
00597 break;
00598
00599 case S_IFREG : printf( "regular " );
00600 break;
00601 #ifdef S_IFIFO
00602 case S_IFIFO : printf( "fifo " );
00603 break;
00604 #endif
00605 #ifdef S_IFLNK
00606 case S_IFLNK : printf( "symlink " );
00607 break;
00608 #endif
00609 #ifdef S_IFSOCK
00610 case S_IFSOCK: printf( "socket " );
00611 break;
00612 #endif
00613 default : printf( "unknown " );
00614 }
00615
00616 for ( m = 11; m >= 0; --m )
00617 putchar( (inode->i_mode & (1<<m)) ? "xwrxwrxwrtgu"[m] : '-' );
00618
00619 if ( s->magic == SUPER_MAGIC )
00620 {
00621
00622 Goto( INFO_COLUMN, INFO_LINE + 1 );
00623 printf( "user %s", user ? user->pw_name : "" );
00624
00625 Goto( INFO_COLUMN, INFO_LINE + 2 );
00626 printf( "file size %lu", inode->i_size );
00627
00628 Goto( INFO_COLUMN, INFO_LINE + 4 );
00629 printf( "m_time %s", ctime( &inode->i_mtime ) );
00630
00631 Goto( INFO_COLUMN, INFO_LINE + 6 );
00632 printf( "links %d, group %s",
00633 inode->i_nlinks, grp ? grp->gr_name : "" );
00634
00635 Draw_Zone_Numbers( s, inode, 0, 7 );
00636 }
00637 else
00638 {
00639
00640 Goto( INFO_COLUMN, INFO_LINE + 1 );
00641 printf( "links %d ", inode->i_nlinks);
00642
00643 Goto( INFO_COLUMN, INFO_LINE + 2 );
00644 printf( "user %s", user ? user->pw_name : "" );
00645
00646 Goto( INFO_COLUMN, INFO_LINE + 3 );
00647 printf( "group %s", grp ? grp->gr_name : "" );
00648
00649 Goto( INFO_COLUMN, INFO_LINE + 4 );
00650 printf( "file size %lu", inode->i_size );
00651
00652 Goto( INFO_COLUMN, INFO_LINE + 6 );
00653 printf( "a_time %s", ctime( &inode->i_atime ) );
00654
00655 Goto( INFO_COLUMN, INFO_LINE + 8 );
00656 printf( "m_time %s", ctime( &inode->i_mtime ) );
00657
00658 Goto( INFO_COLUMN, INFO_LINE + 10 );
00659 printf( "c_time %s", ctime( &inode->i_ctime ) );
00660
00661 Draw_Zone_Numbers( s, inode, 0, 12 );
00662 }
00663
00664 if ( special )
00665 {
00666 Goto( INFO_COLUMN, INFO_LINE + 7 );
00667 dev = (dev_t) inode->i_zone[0];
00668 printf( "major %d, minor %d", major(dev), minor(dev) );
00669 }
00670 }
00671
00672 else
00673 {
00674 char *p = &s->buffer[ s->offset & ~ PAGE_MASK ];
00675
00676 for ( i = 0; i < 16; ++i )
00677 {
00678 Goto( INFO_COLUMN, INFO_LINE + i );
00679 Print_Ascii( *p++ );
00680 Print_Ascii( *p++ );
00681 }
00682
00683 if ( s->block >= s->first_data && page == 0 )
00684 {
00685 unsigned magic = ((s->buffer[1] & 0xff) << 8) | (s->buffer[0] & 0xff);
00686 unsigned second = ((s->buffer[3] & 0xff) << 8) | (s->buffer[2] & 0xff);
00687
00688
00689
00690 if ( magic == (unsigned) A_OUT )
00691 {
00692 Goto( INFO_COLUMN, INFO_LINE );
00693 printf( "executable" );
00694
00695 Goto( INFO_COLUMN, INFO_LINE + 1 );
00696
00697 if ( second == (unsigned) SPLIT )
00698 printf( "separate I & D" );
00699 else
00700 printf( "combined I & D" );
00701 }
00702 }
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 void Draw_Block( block )
00721 char *block;
00722
00723 {
00724 int line;
00725 int column;
00726 int reverse = 0;
00727 int msb_flag = 0;
00728
00729
00730 for ( line = 0; line < 16; ++line )
00731 {
00732 Goto( BLOCK_COLUMN, BLOCK_LINE + line );
00733
00734 for ( column = 0; column < 64; ++column )
00735 {
00736 char c = *block++;
00737
00738 if ( c & 0x80 )
00739 {
00740 msb_flag = 1;
00741 c &= 0x7f;
00742 }
00743
00744 if ( c >= ' ' && c < DEL )
00745 {
00746 if ( reverse )
00747 { fputs( Tnormal, stdout ); reverse = 0; }
00748
00749 putchar( c );
00750 }
00751 else
00752 {
00753 if ( ! reverse )
00754 { fputs( Treverse, stdout ); reverse = 1; }
00755
00756 putchar( c == DEL ? '?' : '@' + c );
00757 }
00758 }
00759 }
00760
00761 if ( reverse )
00762 { fputs( Tnormal, stdout ); reverse = 0; }
00763
00764 if ( msb_flag )
00765 {
00766 Goto( BLOCK_COLUMN + 68, BLOCK_LINE + 6 );
00767 fputs( "(MSB)", stdout );
00768 }
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 void Draw_Map( block, max_bits )
00796 char *block;
00797 int max_bits;
00798
00799 {
00800 int line;
00801 int column;
00802 int bit_count = 0;
00803
00804 for ( line = 0; line < 16; ++line )
00805 {
00806 char *p = &block[ (line & 0xC) >> 2 ];
00807 int shift = (line & 0x3) << 1;
00808
00809 Goto( BLOCK_COLUMN, BLOCK_LINE + line );
00810
00811 for ( column = 0; column < 64; ++column, p += 4 )
00812 {
00813 char c = (*p >> shift) & 0x3;
00814 int current_bit = ((p - block) << 3) + shift;
00815
00816
00817
00818 if ( current_bit >= max_bits )
00819 break;
00820
00821
00822
00823
00824
00825 if ( current_bit + 1 == max_bits )
00826 c &= 1;
00827
00828 switch ( c )
00829 {
00830 case 0 : putchar( BOX_CLR );
00831 break;
00832
00833 case 1 : putchar( BOX_TOP );
00834 ++bit_count;
00835 break;
00836
00837 case 2 : putchar( BOX_BOT );
00838 ++bit_count;
00839 break;
00840
00841 case 3 : putchar( BOX_ALL );
00842 bit_count += 2;
00843 break;
00844 }
00845 }
00846 }
00847
00848
00849 Goto( BLOCK_COLUMN + 68, BLOCK_LINE + 6 );
00850 printf( "(%d)", bit_count );
00851 }
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 void Draw_Pointers( s )
00869 de_state *s;
00870
00871 {
00872 Draw_Offset( s );
00873
00874 switch ( s->mode )
00875 {
00876 case WORD : Word_Pointers( s->last_addr, s->address );
00877 break;
00878
00879 case BLOCK : Block_Pointers( s->last_addr, s->address );
00880 break;
00881
00882 case MAP : Map_Pointers( s->last_addr, s->address );
00883 break;
00884 }
00885
00886 Goto( PROMPT_COLUMN, PROMPT_LINE );
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905 void Draw_Offset( s )
00906 de_state *s;
00907
00908 {
00909 Goto( STATUS_COLUMN, STATUS_LINE + 2 );
00910
00911 printf( "Offset = %5d ", s->offset );
00912
00913
00914 if ( s->block < 2 )
00915 return;
00916
00917 if ( s->block < 2 + s->inode_maps )
00918 {
00919 long bit = (s->address - 2 * K) * 8;
00920
00921 if ( bit < s->inodes_in_map )
00922 printf( "I-node %ld of %d ", bit, s->inodes );
00923 else
00924 printf( "(padding) " );
00925 }
00926
00927 else if ( s->block < 2 + s->inode_maps + s->zone_maps )
00928 {
00929 long bit = (s->address - (2 + s->inode_maps) * K) * 8;
00930
00931 if ( bit < s->zones_in_map )
00932 printf( "Block %ld of %u ", bit + s->first_data - 1, s->zones );
00933 else
00934 printf( "(padding) " );
00935 }
00936
00937 else if ( s->block < s->first_data )
00938 {
00939 bit_t node = (s->address - (2 + s->inode_maps + s->zone_maps) * K) /
00940 s->inode_size + 1;
00941
00942 if ( node <= s->inodes )
00943 printf( "I-node %lu of %lu (%sin use) ",
00944 (unsigned long) node, (unsigned long) s->inodes,
00945 In_Use( node, s->inode_map ) ? "" : "not " );
00946 else
00947 printf( "(padding) " );
00948 }
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973 void Word_Pointers( old_addr, new_addr )
00974 off_t old_addr;
00975 off_t new_addr;
00976
00977 {
00978 int from = ( (int) old_addr & PAGE_MASK ) >> 1;
00979 int to = ( (int) new_addr & PAGE_MASK ) >> 1;
00980
00981 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + from );
00982 putchar( ' ' );
00983
00984 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + to );
00985 putchar( '>' );
00986 }
00987
00988
00989
00990
00991 void Block_Pointers( old_addr, new_addr )
00992 off_t old_addr;
00993 off_t new_addr;
00994
00995 {
00996 int from = (int) old_addr & ~K_MASK;
00997 int to = (int) new_addr & ~K_MASK;
00998
00999 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + from / 64 );
01000 putchar( ' ' );
01001
01002 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + to / 64 );
01003 putchar( '>' );
01004
01005 Goto( BLOCK_COLUMN + from % 64, BLOCK_LINE + 17 );
01006 putchar( ' ' );
01007
01008 Goto( BLOCK_COLUMN + to % 64, BLOCK_LINE + 17 );
01009 putchar( '^' );
01010 }
01011
01012
01013
01014
01015 void Map_Pointers( old_addr, new_addr )
01016 off_t old_addr;
01017 off_t new_addr;
01018
01019 {
01020 int from = ( (int) old_addr & MAP_MASK ) >> 2;
01021 int to = ( (int) new_addr & MAP_MASK ) >> 2;
01022
01023 Goto( BLOCK_COLUMN + from, BLOCK_LINE + 17 );
01024 putchar( ' ' );
01025
01026 Goto( BLOCK_COLUMN + to, BLOCK_LINE + 17 );
01027 putchar( '^' );
01028 }
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 void Print_Number( number, output_base )
01045 word_t number;
01046 int output_base;
01047
01048 {
01049 switch ( output_base )
01050 {
01051 case 16 : printf( "%5x", number );
01052 break;
01053
01054 case 10 : printf( "%7u", number );
01055 break;
01056
01057 case 8 : printf( "%7o", number );
01058 break;
01059
01060 case 2 : {
01061 unsigned int mask;
01062 char pad = ' ';
01063
01064 for ( mask = 0x8000; mask > 1; mask >>= 1 )
01065 putchar( (mask & number) ? (pad = '0', '1') : pad );
01066
01067 putchar( (0x01 & number) ? '1' : '0' );
01068
01069 break;
01070 }
01071
01072 default : Error( "Internal fault (output_base)" );
01073 }
01074 }
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 void Print_Ascii( c )
01092 char c;
01093
01094 {
01095 c &= 0x7f;
01096
01097 if ( c < ' ' )
01098 printf( "%s%c%s", Treverse, '@' + c, Tnormal );
01099 else if ( c == DEL )
01100 printf( "%s?%s", Treverse, Tnormal );
01101 else
01102 putchar( c );
01103 }
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119 #if __STDC__
01120 void Warning( const char *text, ... )
01121 #else
01122 void Warning( text )
01123 char *text;
01124 #endif
01125
01126 {
01127 va_list argp;
01128
01129 printf( "%c%s", BELL, Tclr_all );
01130
01131 Goto( WARNING_COLUMN, WARNING_LINE );
01132
01133 printf( "%s Warning: ", Treverse );
01134 va_start( argp, text );
01135 vprintf( text, argp );
01136 va_end( argp );
01137 printf( " %s", Tnormal );
01138
01139 fflush(stdout);
01140
01141 sleep( 2 );
01142 }
01143
01144
01145 void Draw_Zone_Numbers( s, inode, zindex, zrow )
01146 de_state *s;
01147 struct inode *inode;
01148 int zindex;
01149 int zrow;
01150
01151 {
01152 static char *plurals[] = { "", "double ", "triple " };
01153 zone_t zone;
01154
01155 for ( ; zrow < 16;
01156 ++zindex, zrow += s->zone_num_size / sizeof (word_t) )
01157 {
01158 Goto( INFO_COLUMN, INFO_LINE + zrow );
01159 if ( zindex < s->ndzones )
01160 printf( "zone %d", zindex );
01161 else
01162 printf( "%sindirect", plurals[ zindex - s->ndzones ] );
01163 if ( s->magic != SUPER_MAGIC )
01164 {
01165 zone = inode->i_zone[ zindex ];
01166 if ( zone != (word_t) zone )
01167 {
01168 Goto( INFO_COLUMN + 16, INFO_LINE + zrow );
01169 printf("%ld", (long) zone );
01170 }
01171 }
01172 }
01173 }