📄 de.c
字号:
} case 'o' : /* Set output base */ Draw_Prompt( "Output base?" ); return( Get_Base( &s->output_base ) ); case 'p' : /* Previous address */ { int i; s->address = s->prev_addr[ 0 ]; s->mode = s->prev_mode[ 0 ]; for ( i = 0; i < MAX_PREV - 1; ++i ) { s->prev_addr[ i ] = s->prev_addr[ i + 1 ]; s->prev_mode[ i ] = s->prev_mode[ i + 1 ]; } return( REDRAW ); } case 'q' : /* Quit */ case EOF : case CTRL_D : return( EOF ); case 'r' : /* Right */ case ESC_RIGHT : { s->last_addr = s->address; switch ( s->mode ) { case WORD : s->address += 32; return( REDRAW ); case BLOCK : s->address += 1; if ( (s->last_addr & K_MASK) != (s->address & K_MASK) ) return( REDRAW ); return( REDRAW_POINTERS ); case MAP : s->address += 4; if ( (s->last_addr & ~ MAP_MASK) != (s->address & ~ MAP_MASK) ) return( REDRAW ); return( REDRAW_POINTERS ); default : Error( "Internal fault (mode)" ); } } case 's' : /* Store word */ { unsigned long word; if ( s->mode != WORD ) { Warning( "Must be in visual mode \"word\"" ); return( REDRAW ); } if ( s->device_mode == O_RDONLY ) { Warning( "Use -w option to open device for writing" ); return( REDRAW ); } if ( Get_Count( "Store word?", &word ) ) { if ( word != (word_t) word ) { Warning( "Word is more than 16 bits" ); return( REDRAW ); } Write_Word( s, (word_t) word ); return( REDRAW ); } else return( ERROR ); } case 'u' : /* Up */ case ESC_UP : { s->last_addr = s->address; switch ( s->mode ) { case WORD : s->address -= 2; if ( (s->last_addr & PAGE_MASK) == 0 ) return( REDRAW ); return( REDRAW_POINTERS ); case BLOCK : s->address -= 64; if ( (s->last_addr & K_MASK) != (s->address & K_MASK) ) return( REDRAW ); return( REDRAW_POINTERS ); case MAP : s->address -= 256; return( REDRAW ); default : Error( "Internal fault (mode)" ); } } case 'v' : /* Visual mode */ Draw_Prompt( "Visual mode?" ); switch ( Get_Char() ) { case 'w' : s->mode = WORD; break; case 'b' : s->mode = BLOCK; break; case 'm' : { /* Assume user knows if map mode is possible char *tty = ttyname( 0 ); if ( tty == NULL || strcmp( tty, "/dev/tty0" ) != 0 ) Warning( "Must be at console" ); else */ s->mode = MAP; break; } default : return( ERROR ); } return( REDRAW ); case 'w' : /* Write ASCII block */ if ( s->file_name[0] == '\0' ) { int rc = Get_Filename( s ); if ( rc != OK ) return( rc ); } /* We have a successfully opened file */ /* Eliminate non-ASCII characters */ { int i; char buf[ K ]; char *from = s->buffer; char *to = buf; for ( i = 0; i < K; ++i, ++from ) { *to = *from & 0x7f; if ( *to != '\0' && *to != '\177' ) ++to; } if ( fwrite( buf, 1, (int)(to - buf), s->file_f ) != to - buf ) Warning( "Problem writing out buffer" ); s->file_written = 1; return( REDRAW ); } case 'W' : /* Write block exactly */ if ( s->file_name[0] == '\0' ) { int rc = Get_Filename( s ); if ( rc != OK ) return( rc ); } /* We have a successfully opened file */ if ( fwrite( s->buffer, 1, K, s->file_f ) != K ) Warning( "Problem writing out buffer" ); s->file_written = 1; return( REDRAW ); case 'x' : /* eXtract lost entry */ { ino_t inode; char *filename; Draw_Prompt( "Lost file name?" ); filename = Get_Line(); if ( filename == NULL || filename[0] == '\0' ) return( ERROR ); inode = Find_Deleted_Entry( s, filename ); if ( inode ) { Push( s ); s->mode = WORD; s->address = ( (long) s->first_data - s->inode_blocks ) * K + (long) (inode - 1) * s->inode_size; } return( REDRAW ); } case 'X' : /* eXtract lost blocks */ { int rc; if ( s->mode != WORD ) { Warning( "Must be in visual mode \"word\"" ); return( REDRAW ); } /* Force a new output file name. */ if ( (rc = Get_Filename( s )) != OK ) return( rc ); Draw_Strings( s ); Erase_Prompt(); Draw_Prompt( "Recovering..." ); if ( Recover_Blocks( s ) == -1L ) unlink( s->file_name ); /* Force closure of output file. */ fclose( s->file_f ); s->file_name[ 0 ] = '\0'; return( REDRAW ); } case '/' : /* Search */ case ESC_PLUS : { off_t addr; char *string; Draw_Prompt( "Search string?" ); string = Get_Line(); if ( string == NULL ) return( ERROR ); if ( string[0] != '\0' ) { strcpy( s->search_string, string ); Draw_Strings( s ); } else if ( s->search_string[0] == '\0' ) { Warning( "No search string defined" ); return( REDRAW ); } Erase_Prompt(); Draw_Prompt( "Searching..." ); if ( (addr = Search( s, s->search_string )) == -1L ) { Warning( "Search string not found" ); Wait_For_Key(); return( REDRAW ); } Push( s ); s->mode = BLOCK; s->address = addr; return( REDRAW ); } default: return( ERROR ); } }/****************************************************************//* *//* Push( state ) *//* *//* Push current address and mode, used by the *//* commands B, F, g, G, i, I, n, x and /. This *//* information is popped by the 'p' command. *//* *//****************************************************************/void Push( s ) de_state *s; { int i; for ( i = MAX_PREV - 1; i > 0; --i ) { s->prev_addr[ i ] = s->prev_addr[ i - 1 ]; s->prev_mode[ i ] = s->prev_mode[ i - 1 ]; } s->prev_addr[ 0 ] = s->address; s->prev_mode[ 0 ] = s->mode; }/****************************************************************//* *//* Get_Filename( state ) *//* *//* Read and check a filename. *//* *//****************************************************************/int Get_Filename( s ) de_state *s; { char *filename; char *name; FILE *f; Draw_Prompt( "File name?" ); filename = Get_Line(); if ( filename == NULL || filename[0] == '\0' ) return( ERROR ); for ( name = filename; *name != '\0'; ++name ) if ( ! isgraph( *name ) ) { Warning( "File name contains non-graphic characters" ); return( REDRAW ); } if ( access( filename, F_OK ) == 0 ) { Warning( "Will not overwrite file %s", filename ); return( REDRAW ); } if ( (f = fopen( filename, "w" )) == NULL ) { Warning( "Can not open file %s", filename ); return( REDRAW ); } /* If there is already an open output file then */ /* close it. If it was never written to then */ /* remove its directory entry. */ if ( s->file_name[0] != '\0' ) { if ( ! s->file_written ) unlink( s->file_name ); fclose( s->file_f ); } strcpy( s->file_name, filename ); s->file_f = f; s->file_written = 0; return( OK ); }/****************************************************************//* *//* Get_Count() *//* *//* Read and check a number. Returns non-zero *//* if successful. *//* *//****************************************************************/int Get_Count( units, result ) char *units; unsigned long *result; { char *number; Draw_Prompt( units ); number = Get_Line(); if ( number == NULL || number[0] == '\0' ) return( 0 ); errno = 0; *result = strtoul( number, (char **) NULL, 0 ); return( errno == 0 ); }/****************************************************************//* *//* In_Use( bit, map ) *//* *//* Is the bit set in the map? *//* *//****************************************************************/int In_Use( bit, map ) bit_t bit; bitchunk_t *map; { return( map[ (int) (bit / (CHAR_BIT * sizeof (bitchunk_t))) ] & (1 << ((unsigned) bit % (CHAR_BIT * sizeof (bitchunk_t)))) ); }/****************************************************************//* *//* Find_Inode( state, filename ) *//* *//* Find the i-node for the given file name. *//* *//****************************************************************/ino_t Find_Inode( s, filename ) de_state *s; char *filename; { struct stat device_stat; struct stat file_stat; ino_t inode; if ( fstat( s->device_d, &device_stat ) == -1 ) Error( "Can not fstat(2) file system device" );#ifdef S_IFLNK if ( lstat( filename, &file_stat ) == -1 )#else if ( stat( filename, &file_stat ) == -1 )#endif { Warning( "Can not find file %s", filename ); return( 0 ); } if ( device_stat.st_rdev != file_stat.st_dev ) { Warning( "File is not on device %s", s->device_name ); return( 0 ); } inode = file_stat.st_ino; if ( inode < 1 || inode > s->inodes ) { Warning( "Illegal i-node number" ); return( 0 ); } return( inode ); }/****************************************************************//* *//* Exec_Shell() *//* *//* Fork off a sub-process to exec() the shell. *//* *//****************************************************************/void Exec_Shell() { int pid = fork(); if ( pid == -1 ) return; if ( pid == 0 ) { /* The child process */ extern char **environ; char *shell = getenv( "SHELL" ); if ( shell == NULL ) shell = "/bin/sh"; execle( shell, shell, (char *) 0, environ ); perror( shell ); exit( 127 ); } /* The parent process: ignore signals, wait for sub-process */ signal( SIGINT, SIG_IGN ); signal( SIGQUIT, SIG_IGN ); { int status; int w; while ( (w=wait(&status)) != pid && w != -1 ); } signal( SIGINT, Sigint ); signal( SIGQUIT, Sigint ); return; }/****************************************************************//* *//* Sigint() *//* *//* Terminate the program on an interrupt (^C) *//* or quit (^\) signal. *//* *//****************************************************************/void Sigint(n)int n; { Reset_Term(); /* Restore terminal characteristics */ putchar( '\n' ); exit( 1 ); }/****************************************************************//* *//* Error( text, ... ) *//* *//* Print an error message on stderr. *//* *//****************************************************************/#if __STDC__void Error( const char *text, ... )#elsevoid Error( text ) char *text;#endif { va_list argp; Reset_Term(); fprintf( stderr, "\nde: " ); va_start( argp, text ); vfprintf( stderr, text, argp ); va_end( argp ); if ( errno != 0 ) fprintf( stderr, ": %s", strerror( errno ) ); fprintf( stderr, "\n" ); exit( 1 ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -