de_stdout.c

Go to the documentation of this file.
00001 /****************************************************************/
00002 /*                                                              */
00003 /*      de_stdout.c                                             */
00004 /*                                                              */
00005 /*              Displaying information from the "Disk editor".  */
00006 /*                                                              */
00007 /****************************************************************/
00008 /*  origination         1989-Jan-15        Terrence W. Holm     */
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/fs/const.h"
00029 #include "../../servers/fs/type.h"
00030 #include "../../servers/fs/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 /*              Code for handling termcap                       */
00042 /****************************************************************/
00043 
00044 
00045 #define  TC_BUFFER  1024        /* Size of termcap(3) buffer    */
00046 #define  TC_STRINGS  200        /* Enough room for cm,cl,so,se  */
00047 
00048 
00049 static  char  *Tmove;           /* (cm) - Format for tgoto      */
00050 static  char  *Tclr_all;        /* (cl) - Clear screen          */
00051 static  char  *Treverse;        /* (so) - Start reverse mode    */
00052 static  char  *Tnormal;         /* (se) - End reverse mode      */
00053 
00054 char   Kup    = 0;              /* (ku) - Up arrow key          */
00055 char   Kdown  = 0;              /* (kd) - Down arrow key        */
00056 char   Kleft  = 0;              /* (kl) - Left arrow key        */
00057 char   Kright = 0;              /* (kr) - Right arrow key       */
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 /*      Init_Termcap()                                          */
00078 /*                                                              */
00079 /*              Initializes the external variables for the      */
00080 /*              current terminal.                               */
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   /*  See if there are single character arrow key codes  */
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 /*      Goto( column, line )                                    */
00146 /*                                                              */
00147 /*              Use the termcap string to move the cursor.      */
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 /*                     Output routines                          */
00167 /****************************************************************/
00168 
00169 
00170 
00171 
00172 /****************************************************************/
00173 /*                                                              */
00174 /*      Draw_Help_Screen()                                      */
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 /*      Wait_For_Key()                                          */
00227 /*                                                              */
00228 /*              The user must press a key to continue.          */
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 /*      Draw_Prompt( string )                                   */
00249 /*                                                              */
00250 /*              Write a message in the "prompt" area.           */
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 /*      Erase_Prompt()                                          */
00272 /*                                                              */
00273 /*              Erase the message in the "prompt" area.         */
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 /*      Draw_Screen( state )                                    */
00296 /*                                                              */
00297 /*              Redraw everything, except pointers.             */
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                   /*  Don't display the bits after the end  */
00324                   /*  of the i-node or zone bit maps.       */
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 /*      Draw_Strings( state )                                   */
00355 /*                                                              */
00356 /*              The first status line contains the device name, */
00357 /*              the current write file name (if one is open)    */
00358 /*              and the current search string (if one has       */
00359 /*              been defined).                                  */
00360 /*                                                              */
00361 /*              Long strings are truncated.                     */
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 /*      Block_Type( state )                                     */
00438 /*                                                              */
00439 /*              Display the current block type.                 */
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 /*      Draw_Words( state )                                     */
00484 /*                                                              */
00485 /*              Draw a page in word format.                     */
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 /*      Draw_Info( state )                                      */
00519 /*                                                              */
00520 /*              Add information to a page drawn in word format. */
00521 /*              The routine recognizes the super block, inodes, */
00522 /*              executables and "ar" archives. If the current   */
00523 /*              page is not one of these, then ASCII characters */
00524 /*              are printed from the data words.                */
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           /* V1 file system */
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           /* V2 file system, even page. */
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  /*  Print ASCII characters for each byte in page  */
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         /*  Is this block the start of an executable file?  */
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 /*      Draw_Block( block )                                     */
00714 /*                                                              */
00715 /*              Redraw a 1k block in character format.          */
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       }  /*  end for ( column )  */
00759     }  /*  end for ( line )  */
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 /*      Draw_Map( block, max_bits )                             */
00779 /*                                                              */
00780 /*              Redraw a block in a bit map format.             */
00781 /*              Display min( max_bits, 2048 ) bits.             */
00782 /*                                                              */
00783 /*              The 256 bytes in "block" are displayed from     */
00784 /*              top to bottom and left to right. Bit 0 of       */
00785 /*              a byte is towards the top of the screen.        */
00786 /*                                                              */
00787 /*              Special graphic codes are used to generate      */
00788 /*              two "bits" per character position. So a 16      */
00789 /*              line by 64 column display is 32 "bits" by       */
00790 /*              64 "bits". Or 4 bytes by 64 bytes.              */
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       /*  Don't display bits past "max_bits"  */
00817 
00818       if ( current_bit >= max_bits )
00819         break;
00820 
00821       /*  If "max_bits" occurs in between the two bits  */
00822       /*  I am trying to display as one character, then */
00823       /*  zero off the high-order bit.                  */
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       }  /*  end for ( column )  */
00846     }  /*  end for ( line )  */
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 /*      Draw_Pointers( state )                                  */
00861 /*                                                              */
00862 /*              Redraw the pointers and the offset field.       */
00863 /*              The rest of the screen stays intact.            */
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 /*      Draw_Offset( state )                                    */
00897 /*                                                              */
00898 /*              Display the offset in the current buffer        */
00899 /*              and the relative position if within a map       */
00900 /*              or i-node block.                                */
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 /*      Word_Pointers( old_addr, new_addr )                     */
00959 /*                                                              */
00960 /*      Block_Pointers( old_addr, new_addr )                    */
00961 /*                                                              */
00962 /*      Map_Pointers( old_addr, new_addr )                      */
00963 /*                                                              */
00964 /*              Redraw the index pointers for a each type       */
00965 /*              of display. The pointer at "old_addr" is        */
00966 /*              erased and a new pointer is positioned          */
00967 /*              for "new_addr". This makes the screen           */
00968 /*              update faster and more pleasant for the user.   */
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 /*      Print_Number( number, output_base )                     */
01038 /*                                                              */
01039 /*              Output "number" in the output base.             */
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 /*      Print_Ascii( char )                                     */
01084 /*                                                              */
01085 /*              Display a character in reverse mode if it       */
01086 /*              is not a normal printable ASCII character.      */
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 /*      Warning( text, arg1, arg2 )                             */
01113 /*                                                              */
01114 /*              Display a message for 2 seconds.                */
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);               /* why does everyone forget this? */
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   }

Generated on Fri Apr 14 22:56:47 2006 for minix by  doxygen 1.4.6