pci: don't do sanity check for missing pci bus, the check can misfire.
[minix.git] / commands / de / de_stdout.c
blobe3f86fd04250009874c77c0b743b98d461649d83
1 /****************************************************************/
2 /* */
3 /* de_stdout.c */
4 /* */
5 /* Displaying information from the "Disk editor". */
6 /* */
7 /****************************************************************/
8 /* origination 1989-Jan-15 Terrence W. Holm */
9 /****************************************************************/
12 #include <minix/config.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <grp.h>
18 #include <pwd.h>
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <termcap.h>
23 #include <time.h>
24 #include <unistd.h>
26 #include <minix/const.h>
27 #include <minix/type.h>
28 #include "../../servers/mfs/const.h"
29 #include "../../servers/mfs/type.h"
30 #include "../../servers/mfs/inode.h"
31 #include <minix/fslib.h>
33 #include "de.h"
35 #ifndef major
36 #define major(x) ( (x>>8) & 0377)
37 #define minor(x) (x & 0377)
38 #endif
40 /****************************************************************/
41 /* Code for handling termcap */
42 /****************************************************************/
45 #define TC_BUFFER 1024 /* Size of termcap(3) buffer */
46 #define TC_STRINGS 200 /* Enough room for cm,cl,so,se */
49 static char *Tmove; /* (cm) - Format for tgoto */
50 static char *Tclr_all; /* (cl) - Clear screen */
51 static char *Treverse; /* (so) - Start reverse mode */
52 static char *Tnormal; /* (se) - End reverse mode */
54 char Kup = 0; /* (ku) - Up arrow key */
55 char Kdown = 0; /* (kd) - Down arrow key */
56 char Kleft = 0; /* (kl) - Left arrow key */
57 char Kright = 0; /* (kr) - Right arrow key */
59 _PROTOTYPE(void Goto , (int column , int line ));
60 _PROTOTYPE(void Block_Type , (de_state *s ));
61 _PROTOTYPE(void Draw_Words , (de_state *s ));
62 _PROTOTYPE(void Draw_Info , (de_state *s ));
63 _PROTOTYPE(void Draw_Block , (char *block ));
64 _PROTOTYPE(void Draw_Map , (char *block , int max_bits ));
65 _PROTOTYPE(void Draw_Offset , (de_state *s ));
66 _PROTOTYPE(void Word_Pointers , (off_t old_addr , off_t new_addr ));
67 _PROTOTYPE(void Block_Pointers , (off_t old_addr , off_t new_addr ));
68 _PROTOTYPE(void Map_Pointers , (off_t old_addr , off_t new_addr ));
69 _PROTOTYPE(void Print_Number , (Word_t number , int output_base ));
70 _PROTOTYPE(void Draw_Zone_Numbers , (de_state *s , struct inode *inode ,
71 int zindex , int zrow ));
75 /****************************************************************/
76 /* */
77 /* Init_Termcap() */
78 /* */
79 /* Initializes the external variables for the */
80 /* current terminal. */
81 /* */
82 /****************************************************************/
85 int Init_Termcap()
88 char *term;
89 char buffer[ TC_BUFFER ];
90 static char strings[ TC_STRINGS ];
91 char *s = &strings[0];
92 char *Kcode;
95 term = getenv( "TERM" );
97 if ( term == NULL )
98 return( 0 );
100 if ( tgetent( buffer, term ) != 1 )
101 return( 0 );
104 if ( (Tmove = tgetstr( "cm", &s )) == NULL )
105 return( 0 );
107 if ( (Tclr_all = tgetstr( "cl", &s )) == NULL )
108 return( 0 );
110 if ( (Treverse = tgetstr( "so", &s )) == NULL )
112 Treverse = Tnormal = s;
113 *s = '\0';
114 ++s;
116 else if ( (Tnormal = tgetstr( "se", &s )) == NULL )
117 return( 0 );
120 /* See if there are single character arrow key codes */
122 if ( (Kcode = tgetstr( "ku", &s )) != NULL && strlen( Kcode ) == 1 )
123 Kup = Kcode[0];
125 if ( (Kcode = tgetstr( "kd", &s )) != NULL && strlen( Kcode ) == 1 )
126 Kdown = Kcode[0];
128 if ( (Kcode = tgetstr( "kl", &s )) != NULL && strlen( Kcode ) == 1 )
129 Kleft = Kcode[0];
131 if ( (Kcode = tgetstr( "kr", &s )) != NULL && strlen( Kcode ) == 1 )
132 Kright = Kcode[0];
135 return( 1 );
143 /****************************************************************/
144 /* */
145 /* Goto( column, line ) */
146 /* */
147 /* Use the termcap string to move the cursor. */
148 /* */
149 /****************************************************************/
152 void Goto( column, line )
153 int column;
154 int line;
157 fputs( tgoto( Tmove, column, line ), stdout );
165 /****************************************************************/
166 /* Output routines */
167 /****************************************************************/
172 /****************************************************************/
173 /* */
174 /* Draw_Help_Screen() */
175 /* */
176 /****************************************************************/
179 void Draw_Help_Screen( s )
180 de_state *s;
183 int down;
184 int right;
186 switch ( s->mode )
188 case WORD : down = 2; right = 32; break;
189 case BLOCK : down = 64; right = 1; break;
190 case MAP : down = 256; right = 4; break;
193 printf( "%s ", Tclr_all );
194 printf( "%sDE COMMANDS%s\r\n\n\n", Treverse, Tnormal );
197 printf( " PGUP b Back one block h Help\r\n" );
198 printf( " PGDN f Forward one block q Quit\r\n" );
199 printf( " HOME B Goto first block m Minix shell\r\n" );
200 printf( " END F Goto last block\r\n" );
201 printf( " v Visual mode (w b m)\r\n" );
202 printf( " g Goto specified block o Output base (h d o b)\r\n" );
203 printf( " G Goto block indirectly\r\n" );
204 printf( " i Goto i-node c Change file name\r\n" );
205 printf( " I Filename to i-node w Write ASCII block\r\n" );
206 printf( " W Write block exactly\r\n" );
207 printf( " / Search\r\n" );
208 printf( " n Next occurrence x Extract lost entry\r\n" );
209 printf( " p Previous address X Extract lost blocks\r\n" );
210 printf( " s Store word\r\n" );
211 printf( " UP u Move back %d bytes\r\n", down );
212 printf( " DOWN d Move forward %d bytes\r\n", down );
213 printf( " LEFT l Move back %d byte%s\r\n", right,
214 right == 1 ? "" : "s" );
215 printf( " RIGHT r Move forward %d byte%s\r\n\n\n", right,
216 right == 1 ? "" : "s" );
224 /****************************************************************/
225 /* */
226 /* Wait_For_Key() */
227 /* */
228 /* The user must press a key to continue. */
229 /* */
230 /****************************************************************/
233 void Wait_For_Key()
236 Draw_Prompt( "Press a key to continue..." );
238 Get_Char();
246 /****************************************************************/
247 /* */
248 /* Draw_Prompt( string ) */
249 /* */
250 /* Write a message in the "prompt" area. */
251 /* */
252 /****************************************************************/
255 void Draw_Prompt( string )
256 char *string;
259 Goto( PROMPT_COLUMN, PROMPT_LINE );
261 printf( "%s%s%s ", Treverse, string, Tnormal );
269 /****************************************************************/
270 /* */
271 /* Erase_Prompt() */
272 /* */
273 /* Erase the message in the "prompt" area. */
274 /* */
275 /****************************************************************/
278 void Erase_Prompt()
281 Goto( PROMPT_COLUMN, PROMPT_LINE );
283 printf( "%77c", ' ' );
285 Goto( PROMPT_COLUMN, PROMPT_LINE );
293 /****************************************************************/
294 /* */
295 /* Draw_Screen( state ) */
296 /* */
297 /* Redraw everything, except pointers. */
298 /* */
299 /****************************************************************/
302 void Draw_Screen( s )
303 de_state *s;
306 fputs( Tclr_all, stdout );
308 Draw_Strings( s );
309 Block_Type( s );
311 switch ( s->mode )
313 case WORD : Draw_Words( s );
314 Draw_Info( s );
315 break;
317 case BLOCK : Draw_Block( s->buffer );
318 break;
320 case MAP : {
321 int max_bits = 2 * K;
323 /* Don't display the bits after the end */
324 /* of the i-node or zone bit maps. */
326 if ( s->block == 2 + s->inode_maps - 1 )
327 max_bits = (int)
328 (s->inodes_in_map
329 - CHAR_BIT * K * (ino_t) (s->inode_maps - 1)
330 - CHAR_BIT * (ino_t) (s->offset & ~ MAP_MASK));
332 else if ( s->block == 2 + s->inode_maps + s->zone_maps - 1 )
333 max_bits = (int)
334 (s->zones_in_map
335 - CHAR_BIT * K * (zone_t) (s->zone_maps - 1)
336 - CHAR_BIT * (zone_t) (s->offset & ~ MAP_MASK));
338 if ( max_bits < 0 )
339 max_bits = 0;
341 Draw_Map( &s->buffer[ s->offset & ~ MAP_MASK ], max_bits );
342 break;
352 /****************************************************************/
353 /* */
354 /* Draw_Strings( state ) */
355 /* */
356 /* The first status line contains the device name, */
357 /* the current write file name (if one is open) */
358 /* and the current search string (if one has */
359 /* been defined). */
360 /* */
361 /* Long strings are truncated. */
362 /* */
363 /****************************************************************/
366 void Draw_Strings( s )
367 de_state *s;
370 int len;
371 int i;
373 Goto( STATUS_COLUMN, STATUS_LINE );
375 printf( "Device %s= %-14.14s ",
376 s->device_mode == O_RDONLY ? "" : "(w) ", s->device_name );
378 switch ( s->magic )
380 case SUPER_MAGIC : printf( "V1 file system ");
381 break;
382 case SUPER_REV : printf( "V1-bytes-swapped file system (?) ");
383 break;
384 case SUPER_V2 : printf( "V2 file system ");
385 break;
386 case SUPER_V2_REV : printf( "V2-bytes-swapped file system (?) ");
387 break;
388 case SUPER_V3 : printf( "V3 file system ");
389 break;
390 default : printf( "not a Minix file system ");
391 break;
394 len = strlen( s->file_name );
396 if ( len == 0 )
397 printf( "%29s", " " );
398 else if ( len <= 20 )
399 printf( "File = %-20s ", s->file_name );
400 else
401 printf( "File = ...%17.17s ", s->file_name + len - 17 );
404 len = strlen( s->search_string );
406 if ( len == 0 )
407 printf( "%20s", " " );
408 else
410 printf( "Search = " );
412 if ( len <= 11 )
414 for ( i = 0; i < len; ++i )
415 Print_Ascii( s->search_string[ i ] );
417 for ( ; i < 11; ++i )
418 putchar( ' ' );
420 else
422 for ( i = 0; i < 8; ++i )
423 Print_Ascii( s->search_string[ i ] );
425 printf( "..." );
435 /****************************************************************/
436 /* */
437 /* Block_Type( state ) */
438 /* */
439 /* Display the current block type. */
440 /* */
441 /****************************************************************/
444 void Block_Type( s )
445 de_state *s;
448 Goto( STATUS_COLUMN, STATUS_LINE + 1 );
450 printf( "Block = %5u of %-5u ", s->block, s->zones );
452 if ( !s->is_fs )
453 return;
455 if ( s->block == BOOT_BLOCK )
456 printf( "Boot block" );
458 else if ( s->block == 1 )
459 printf( "Super block" );
461 else if ( s->block < 2 + s->inode_maps )
462 printf( "I-node bit map" );
464 else if ( s->block < 2 + s->inode_maps + s->zone_maps )
465 printf( "Zone bit map" );
467 else if ( s->block < s->first_data )
468 printf( "I-nodes" );
470 else
471 printf( "Data block (%sin use)",
472 In_Use( (bit_t) (s->block - (s->first_data - 1)), s->zone_map )
473 ? "" : "not " );
481 /****************************************************************/
482 /* */
483 /* Draw_Words( state ) */
484 /* */
485 /* Draw a page in word format. */
486 /* */
487 /****************************************************************/
490 void Draw_Words( s )
491 de_state *s;
494 int line;
495 int addr = s->offset & ~ PAGE_MASK;
498 for ( line = 0; line < 16; ++line, addr += 2 )
500 Goto( BLOCK_COLUMN, BLOCK_LINE + line );
502 printf( "%5d ", addr );
504 Print_Number( *( (word_t *) &s->buffer[ addr ] ), s->output_base );
507 Goto( BLOCK_COLUMN + 64, BLOCK_LINE );
508 printf( "(base %d)", s->output_base );
516 /****************************************************************/
517 /* */
518 /* Draw_Info( state ) */
519 /* */
520 /* Add information to a page drawn in word format. */
521 /* The routine recognizes the super block, inodes, */
522 /* executables and "ar" archives. If the current */
523 /* page is not one of these, then ASCII characters */
524 /* are printed from the data words. */
525 /* */
526 /****************************************************************/
529 char *super_block_info[] = { "number of inodes",
530 "V1 number of zones",
531 "inode bit map blocks",
532 "zone bit map blocks",
533 "first data zone",
534 "blocks per zone shift & flags",
535 "maximum file size",
537 "magic number",
538 "fsck magic number",
539 "V2 number of zones" };
542 void Draw_Info( s )
543 de_state *s;
546 int i;
547 int page = s->offset >> PAGE_SHIFT;
548 dev_t dev;
551 if ( s->is_fs && s->block == 1 && page == 0 )
552 for ( i = 0; i < 11; ++i )
554 Goto( INFO_COLUMN, INFO_LINE + i );
555 printf( "%s", super_block_info[ i ] );
558 else if ( s->is_fs && s->block >= s->first_data - s->inode_blocks &&
559 s->block < s->first_data )
561 struct inode core_inode;
562 d1_inode *dip1;
563 d2_inode *dip2;
564 struct inode *inode = &core_inode;
565 int special = 0;
566 int m;
567 struct passwd *user;
568 struct group *grp;
570 dip1 = (d1_inode *) &s->buffer[ s->offset & ~ PAGE_MASK ];
571 dip2 = (d2_inode *) &s->buffer[ s->offset & ~ PAGE_MASK
572 & ~ (V2_INODE_SIZE-1) ];
573 conv_inode( inode, dip1, dip2, READING, s->magic );
575 user = getpwuid( inode->i_uid );
576 grp = getgrgid( inode->i_gid );
578 if ( s->magic != SUPER_MAGIC && page & 1 )
580 Draw_Zone_Numbers( s, inode, 2, 0 );
581 return;
584 Goto( INFO_COLUMN, INFO_LINE );
586 switch( inode->i_mode & S_IFMT )
588 case S_IFDIR : printf( "directory " );
589 break;
591 case S_IFCHR : printf( "character " );
592 special = 1;
593 break;
595 case S_IFBLK : printf( "block " );
596 special = 1;
597 break;
599 case S_IFREG : printf( "regular " );
600 break;
601 #ifdef S_IFIFO
602 case S_IFIFO : printf( "fifo " );
603 break;
604 #endif
605 #ifdef S_IFLNK
606 case S_IFLNK : printf( "symlink " );
607 break;
608 #endif
609 #ifdef S_IFSOCK
610 case S_IFSOCK: printf( "socket " );
611 break;
612 #endif
613 default : printf( "unknown " );
616 for ( m = 11; m >= 0; --m )
617 putchar( (inode->i_mode & (1<<m)) ? "xwrxwrxwrtgu"[m] : '-' );
619 if ( s->magic == SUPER_MAGIC )
621 /* V1 file system */
622 Goto( INFO_COLUMN, INFO_LINE + 1 );
623 printf( "user %s", user ? user->pw_name : "" );
625 Goto( INFO_COLUMN, INFO_LINE + 2 );
626 printf( "file size %lu", inode->i_size );
628 Goto( INFO_COLUMN, INFO_LINE + 4 );
629 printf( "m_time %s", ctime( &inode->i_mtime ) );
631 Goto( INFO_COLUMN, INFO_LINE + 6 );
632 printf( "links %d, group %s",
633 inode->i_nlinks, grp ? grp->gr_name : "" );
635 Draw_Zone_Numbers( s, inode, 0, 7 );
637 else
639 /* V2 file system, even page. */
640 Goto( INFO_COLUMN, INFO_LINE + 1 );
641 printf( "links %d ", inode->i_nlinks);
643 Goto( INFO_COLUMN, INFO_LINE + 2 );
644 printf( "user %s", user ? user->pw_name : "" );
646 Goto( INFO_COLUMN, INFO_LINE + 3 );
647 printf( "group %s", grp ? grp->gr_name : "" );
649 Goto( INFO_COLUMN, INFO_LINE + 4 );
650 printf( "file size %lu", inode->i_size );
652 Goto( INFO_COLUMN, INFO_LINE + 6 );
653 printf( "a_time %s", ctime( &inode->i_atime ) );
655 Goto( INFO_COLUMN, INFO_LINE + 8 );
656 printf( "m_time %s", ctime( &inode->i_mtime ) );
658 Goto( INFO_COLUMN, INFO_LINE + 10 );
659 printf( "c_time %s", ctime( &inode->i_ctime ) );
661 Draw_Zone_Numbers( s, inode, 0, 12 );
664 if ( special )
666 Goto( INFO_COLUMN, INFO_LINE + 7 );
667 dev = (dev_t) inode->i_zone[0];
668 printf( "major %d, minor %d", major(dev), minor(dev) );
672 else /* Print ASCII characters for each byte in page */
674 char *p = &s->buffer[ s->offset & ~ PAGE_MASK ];
676 for ( i = 0; i < 16; ++i )
678 Goto( INFO_COLUMN, INFO_LINE + i );
679 Print_Ascii( *p++ );
680 Print_Ascii( *p++ );
683 if ( s->block >= s->first_data && page == 0 )
685 unsigned magic = ((s->buffer[1] & 0xff) << 8) | (s->buffer[0] & 0xff);
686 unsigned second = ((s->buffer[3] & 0xff) << 8) | (s->buffer[2] & 0xff);
688 /* Is this block the start of an executable file? */
690 if ( magic == (unsigned) A_OUT )
692 Goto( INFO_COLUMN, INFO_LINE );
693 printf( "executable" );
695 Goto( INFO_COLUMN, INFO_LINE + 1 );
697 if ( second == (unsigned) SPLIT )
698 printf( "separate I & D" );
699 else
700 printf( "combined I & D" );
711 /****************************************************************/
712 /* */
713 /* Draw_Block( block ) */
714 /* */
715 /* Redraw a 1k block in character format. */
716 /* */
717 /****************************************************************/
720 void Draw_Block( block )
721 char *block;
724 int line;
725 int column;
726 int reverse = 0;
727 int msb_flag = 0;
730 for ( line = 0; line < 16; ++line )
732 Goto( BLOCK_COLUMN, BLOCK_LINE + line );
734 for ( column = 0; column < 64; ++column )
736 char c = *block++;
738 if ( c & 0x80 )
740 msb_flag = 1;
741 c &= 0x7f;
744 if ( c >= ' ' && c < DEL )
746 if ( reverse )
747 { fputs( Tnormal, stdout ); reverse = 0; }
749 putchar( c );
751 else
753 if ( ! reverse )
754 { fputs( Treverse, stdout ); reverse = 1; }
756 putchar( c == DEL ? '?' : '@' + c );
758 } /* end for ( column ) */
759 } /* end for ( line ) */
761 if ( reverse )
762 { fputs( Tnormal, stdout ); reverse = 0; }
764 if ( msb_flag )
766 Goto( BLOCK_COLUMN + 68, BLOCK_LINE + 6 );
767 fputs( "(MSB)", stdout );
776 /****************************************************************/
777 /* */
778 /* Draw_Map( block, max_bits ) */
779 /* */
780 /* Redraw a block in a bit map format. */
781 /* Display min( max_bits, 2048 ) bits. */
782 /* */
783 /* The 256 bytes in "block" are displayed from */
784 /* top to bottom and left to right. Bit 0 of */
785 /* a byte is towards the top of the screen. */
786 /* */
787 /* Special graphic codes are used to generate */
788 /* two "bits" per character position. So a 16 */
789 /* line by 64 column display is 32 "bits" by */
790 /* 64 "bits". Or 4 bytes by 64 bytes. */
791 /* */
792 /****************************************************************/
795 void Draw_Map( block, max_bits )
796 char *block;
797 int max_bits;
800 int line;
801 int column;
802 int bit_count = 0;
804 for ( line = 0; line < 16; ++line )
806 char *p = &block[ (line & 0xC) >> 2 ];
807 int shift = (line & 0x3) << 1;
809 Goto( BLOCK_COLUMN, BLOCK_LINE + line );
811 for ( column = 0; column < 64; ++column, p += 4 )
813 char c = (*p >> shift) & 0x3;
814 int current_bit = ((p - block) << 3) + shift;
816 /* Don't display bits past "max_bits" */
818 if ( current_bit >= max_bits )
819 break;
821 /* If "max_bits" occurs in between the two bits */
822 /* I am trying to display as one character, then */
823 /* zero off the high-order bit. */
825 if ( current_bit + 1 == max_bits )
826 c &= 1;
828 switch ( c )
830 case 0 : putchar( BOX_CLR );
831 break;
833 case 1 : putchar( BOX_TOP );
834 ++bit_count;
835 break;
837 case 2 : putchar( BOX_BOT );
838 ++bit_count;
839 break;
841 case 3 : putchar( BOX_ALL );
842 bit_count += 2;
843 break;
845 } /* end for ( column ) */
846 } /* end for ( line ) */
849 Goto( BLOCK_COLUMN + 68, BLOCK_LINE + 6 );
850 printf( "(%d)", bit_count );
858 /****************************************************************/
859 /* */
860 /* Draw_Pointers( state ) */
861 /* */
862 /* Redraw the pointers and the offset field. */
863 /* The rest of the screen stays intact. */
864 /* */
865 /****************************************************************/
868 void Draw_Pointers( s )
869 de_state *s;
872 Draw_Offset( s );
874 switch ( s->mode )
876 case WORD : Word_Pointers( s->last_addr, s->address );
877 break;
879 case BLOCK : Block_Pointers( s->last_addr, s->address );
880 break;
882 case MAP : Map_Pointers( s->last_addr, s->address );
883 break;
886 Goto( PROMPT_COLUMN, PROMPT_LINE );
894 /****************************************************************/
895 /* */
896 /* Draw_Offset( state ) */
897 /* */
898 /* Display the offset in the current buffer */
899 /* and the relative position if within a map */
900 /* or i-node block. */
901 /* */
902 /****************************************************************/
905 void Draw_Offset( s )
906 de_state *s;
909 Goto( STATUS_COLUMN, STATUS_LINE + 2 );
911 printf( "Offset = %5d ", s->offset );
914 if ( s->block < 2 )
915 return;
917 if ( s->block < 2 + s->inode_maps )
919 long bit = (s->address - 2 * K) * 8;
921 if ( bit < s->inodes_in_map )
922 printf( "I-node %ld of %d ", bit, s->inodes );
923 else
924 printf( "(padding) " );
927 else if ( s->block < 2 + s->inode_maps + s->zone_maps )
929 long bit = (s->address - (2 + s->inode_maps) * K) * 8;
931 if ( bit < s->zones_in_map )
932 printf( "Block %ld of %u ", bit + s->first_data - 1, s->zones );
933 else
934 printf( "(padding) " );
937 else if ( s->block < s->first_data )
939 bit_t node = (s->address - (2 + s->inode_maps + s->zone_maps) * K) /
940 s->inode_size + 1;
942 if ( node <= s->inodes )
943 printf( "I-node %lu of %lu (%sin use) ",
944 (unsigned long) node, (unsigned long) s->inodes,
945 In_Use( node, s->inode_map ) ? "" : "not " );
946 else
947 printf( "(padding) " );
956 /****************************************************************/
957 /* */
958 /* Word_Pointers( old_addr, new_addr ) */
959 /* */
960 /* Block_Pointers( old_addr, new_addr ) */
961 /* */
962 /* Map_Pointers( old_addr, new_addr ) */
963 /* */
964 /* Redraw the index pointers for a each type */
965 /* of display. The pointer at "old_addr" is */
966 /* erased and a new pointer is positioned */
967 /* for "new_addr". This makes the screen */
968 /* update faster and more pleasant for the user. */
969 /* */
970 /****************************************************************/
973 void Word_Pointers( old_addr, new_addr )
974 off_t old_addr;
975 off_t new_addr;
978 int from = ( (int) old_addr & PAGE_MASK ) >> 1;
979 int to = ( (int) new_addr & PAGE_MASK ) >> 1;
981 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + from );
982 putchar( ' ' );
984 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + to );
985 putchar( '>' );
991 void Block_Pointers( old_addr, new_addr )
992 off_t old_addr;
993 off_t new_addr;
996 int from = (int) old_addr & ~K_MASK;
997 int to = (int) new_addr & ~K_MASK;
999 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + from / 64 );
1000 putchar( ' ' );
1002 Goto( BLOCK_COLUMN - 2, BLOCK_LINE + to / 64 );
1003 putchar( '>' );
1005 Goto( BLOCK_COLUMN + from % 64, BLOCK_LINE + 17 );
1006 putchar( ' ' );
1008 Goto( BLOCK_COLUMN + to % 64, BLOCK_LINE + 17 );
1009 putchar( '^' );
1015 void Map_Pointers( old_addr, new_addr )
1016 off_t old_addr;
1017 off_t new_addr;
1020 int from = ( (int) old_addr & MAP_MASK ) >> 2;
1021 int to = ( (int) new_addr & MAP_MASK ) >> 2;
1023 Goto( BLOCK_COLUMN + from, BLOCK_LINE + 17 );
1024 putchar( ' ' );
1026 Goto( BLOCK_COLUMN + to, BLOCK_LINE + 17 );
1027 putchar( '^' );
1035 /****************************************************************/
1036 /* */
1037 /* Print_Number( number, output_base ) */
1038 /* */
1039 /* Output "number" in the output base. */
1040 /* */
1041 /****************************************************************/
1044 void Print_Number( number, output_base )
1045 word_t number;
1046 int output_base;
1049 switch ( output_base )
1051 case 16 : printf( "%5x", number );
1052 break;
1054 case 10 : printf( "%7u", number );
1055 break;
1057 case 8 : printf( "%7o", number );
1058 break;
1060 case 2 : {
1061 unsigned int mask;
1062 char pad = ' ';
1064 for ( mask = 0x8000; mask > 1; mask >>= 1 )
1065 putchar( (mask & number) ? (pad = '0', '1') : pad );
1067 putchar( (0x01 & number) ? '1' : '0' );
1069 break;
1072 default : Error( "Internal fault (output_base)" );
1081 /****************************************************************/
1082 /* */
1083 /* Print_Ascii( char ) */
1084 /* */
1085 /* Display a character in reverse mode if it */
1086 /* is not a normal printable ASCII character. */
1087 /* */
1088 /****************************************************************/
1091 void Print_Ascii( c )
1092 char c;
1095 c &= 0x7f;
1097 if ( c < ' ' )
1098 printf( "%s%c%s", Treverse, '@' + c, Tnormal );
1099 else if ( c == DEL )
1100 printf( "%s?%s", Treverse, Tnormal );
1101 else
1102 putchar( c );
1110 /****************************************************************/
1111 /* */
1112 /* Warning( text, arg1, arg2 ) */
1113 /* */
1114 /* Display a message for 2 seconds. */
1115 /* */
1116 /****************************************************************/
1119 #if __STDC__
1120 void Warning( const char *text, ... )
1121 #else
1122 void Warning( text )
1123 char *text;
1124 #endif
1127 va_list argp;
1129 printf( "%c%s", BELL, Tclr_all );
1131 Goto( WARNING_COLUMN, WARNING_LINE );
1133 printf( "%s Warning: ", Treverse );
1134 va_start( argp, text );
1135 vprintf( text, argp );
1136 va_end( argp );
1137 printf( " %s", Tnormal );
1139 fflush(stdout); /* why does everyone forget this? */
1141 sleep( 2 );
1145 void Draw_Zone_Numbers( s, inode, zindex, zrow )
1146 de_state *s;
1147 struct inode *inode;
1148 int zindex;
1149 int zrow;
1152 static char *plurals[] = { "", "double ", "triple " };
1153 zone_t zone;
1155 for ( ; zrow < 16;
1156 ++zindex, zrow += s->zone_num_size / sizeof (word_t) )
1158 Goto( INFO_COLUMN, INFO_LINE + zrow );
1159 if ( zindex < s->ndzones )
1160 printf( "zone %d", zindex );
1161 else
1162 printf( "%sindirect", plurals[ zindex - s->ndzones ] );
1163 if ( s->magic != SUPER_MAGIC )
1165 zone = inode->i_zone[ zindex ];
1166 if ( zone != (word_t) zone )
1168 Goto( INFO_COLUMN + 16, INFO_LINE + zrow );
1169 printf("%ld", (long) zone );