[9] | 1 | /****************************************************************/
|
---|
| 2 | /* */
|
---|
| 3 | /* de.h */
|
---|
| 4 | /* */
|
---|
| 5 | /* Definitions for the "Disk editor". */
|
---|
| 6 | /* */
|
---|
| 7 | /****************************************************************/
|
---|
| 8 | /* origination 1989-Jan-15 Terrence W. Holm */
|
---|
| 9 | /****************************************************************/
|
---|
| 10 |
|
---|
| 11 |
|
---|
| 12 | /****************************************************************/
|
---|
| 13 | /* */
|
---|
| 14 | /* de(1) */
|
---|
| 15 | /* */
|
---|
| 16 | /* This is the MINIX disk editor. It allows the user to */
|
---|
| 17 | /* observe and modify a file system. It can also be used */
|
---|
| 18 | /* to recover unlink(2)'ed files */
|
---|
| 19 | /* */
|
---|
| 20 | /* See the de(1) man page. */
|
---|
| 21 | /* */
|
---|
| 22 | /****************************************************************/
|
---|
| 23 |
|
---|
| 24 |
|
---|
| 25 | /****************************************************************/
|
---|
| 26 | /* */
|
---|
| 27 | /* de Copyright Terrence W. Holm 1989 */
|
---|
| 28 | /* */
|
---|
| 29 | /* This program was written for users of the Minix operating */
|
---|
| 30 | /* system, and in the spirit of other public domain software */
|
---|
| 31 | /* written for said system, this source code is made available */
|
---|
| 32 | /* at no cost to everyone. I assume no responsibility for */
|
---|
| 33 | /* damage to file systems caused by this program. */
|
---|
| 34 | /* */
|
---|
| 35 | /* This program (one .h, five .c's and a "man" page) may be */
|
---|
| 36 | /* copied and/or modified subject to (1) no charge must be */
|
---|
| 37 | /* made for distribution, other than for the medium, (2) all */
|
---|
| 38 | /* modified sources must be clearly marked as such, (3) all */
|
---|
| 39 | /* sources must carry this copyright. */
|
---|
| 40 | /* */
|
---|
| 41 | /****************************************************************/
|
---|
| 42 |
|
---|
| 43 |
|
---|
| 44 | /****************************************************************/
|
---|
| 45 | /* */
|
---|
| 46 | /* files */
|
---|
| 47 | /* */
|
---|
| 48 | /* de.h Definitions */
|
---|
| 49 | /* de.c The main loop */
|
---|
| 50 | /* de_stdin.c Character input routines */
|
---|
| 51 | /* de_stdout.c Output routines */
|
---|
| 52 | /* de_diskio.c File system read/write */
|
---|
| 53 | /* de_recover.c File restoration routines */
|
---|
| 54 | /* */
|
---|
| 55 | /* de.1 "Man" page */
|
---|
| 56 | /* Makefile For "make" */
|
---|
| 57 | /* README Installation help */
|
---|
| 58 | /* */
|
---|
| 59 | /* */
|
---|
| 60 | /* fs/path.c was modified to support the 'x' command. */
|
---|
| 61 | /* fs/link.c and fs/open.c were changed for 'X'. */
|
---|
| 62 | /* */
|
---|
| 63 | /****************************************************************/
|
---|
| 64 | #undef printf
|
---|
| 65 | #include <stdio.h>
|
---|
| 66 | #include <dirent.h>
|
---|
| 67 |
|
---|
| 68 | /* General constants */
|
---|
| 69 |
|
---|
| 70 | #define MAX_STRING 60 /* For all input lines */
|
---|
| 71 | #define MAX_PREV 8 /* For 'p' command */
|
---|
| 72 | #define SEARCH_BUFFER (4*K) /* For '/' and 'n' */
|
---|
| 73 |
|
---|
| 74 |
|
---|
| 75 | /* Files */
|
---|
| 76 |
|
---|
| 77 | #define TMP "/tmp" /* For "-r" output */
|
---|
| 78 | #define DEV "/dev" /* Where devices are */
|
---|
| 79 |
|
---|
| 80 |
|
---|
| 81 | /* a.out header constants (see a.out.h, if you have it) */
|
---|
| 82 |
|
---|
| 83 | #if (CHIP == INTEL)
|
---|
| 84 | #define A_OUT 0x0301
|
---|
| 85 | #define SPLIT 0x0420
|
---|
| 86 | #endif
|
---|
| 87 |
|
---|
| 88 | #if (CHIP == M68000)
|
---|
| 89 | #define A_OUT 0x0301
|
---|
| 90 | #define SPLIT 0x0B20
|
---|
| 91 | #endif
|
---|
| 92 |
|
---|
| 93 | #if (CHIP == SPARC)
|
---|
| 94 | #define A_OUT 0x0301
|
---|
| 95 | #define SPLIT 0x0B20
|
---|
| 96 | #endif
|
---|
| 97 |
|
---|
| 98 | /* Each buffer is 1k. In WORD mode 16 words (32 bytes) can be */
|
---|
| 99 | /* displayed at once. In BLOCK mode 1K bytes can be displayed. */
|
---|
| 100 | /* In MAP mode 2048 bits (256 bytes) are displayed. */
|
---|
| 101 |
|
---|
| 102 | #define K 1024 /* STD_BLK */
|
---|
| 103 | #define K_MASK (~(K-1)) /* Round to K boundary */
|
---|
| 104 | #define K_SHIFT 10 /* Ie. 1<<10 = K */
|
---|
| 105 | #define PAGE_MASK 0x1f /* Word mode: 32 bytes */
|
---|
| 106 | #define PAGE_SHIFT 5 /* Ie. 1<<5 = 32 */
|
---|
| 107 | #define MAP_BITS_PER_BLOCK (8 * K) /* 1k block, 8192 bits */
|
---|
| 108 | #define MAP_MASK 0xff /* 256 bytes/screen */
|
---|
| 109 |
|
---|
| 110 |
|
---|
| 111 |
|
---|
| 112 | /* Terminal i/o codes */
|
---|
| 113 |
|
---|
| 114 | #define CTRL_D '\004' /* ASCII ^D */
|
---|
| 115 | #define BELL '\007' /* ASCII bell code */
|
---|
| 116 | #define BS '\010' /* ASCII back space */
|
---|
| 117 | #define CTRL_U '\025' /* ASCII ^U */
|
---|
| 118 | #define ESCAPE '\033' /* ASCII escape code */
|
---|
| 119 | #define DEL '\177' /* ASCII delete code */
|
---|
| 120 |
|
---|
| 121 |
|
---|
| 122 | /* Input escape codes generated by the Minix console. */
|
---|
| 123 | /* Format: ESC [ X. */
|
---|
| 124 |
|
---|
| 125 | #define ESC_HOME ('H' + 0x80)
|
---|
| 126 | #define ESC_UP ('A' + 0x80)
|
---|
| 127 | #define ESC_PGUP ('V' + 0x80)
|
---|
| 128 | #define ESC_LEFT ('D' + 0x80)
|
---|
| 129 | #define ESC_5 ('G' + 0x80)
|
---|
| 130 | #define ESC_RIGHT ('C' + 0x80)
|
---|
| 131 | #define ESC_END ('Y' + 0x80)
|
---|
| 132 | #define ESC_DOWN ('B' + 0x80)
|
---|
| 133 | #define ESC_PGDN ('U' + 0x80)
|
---|
| 134 | #define ESC_PLUS ('T' + 0x80)
|
---|
| 135 | #define ESC_MINUS ('S' + 0x80)
|
---|
| 136 |
|
---|
| 137 |
|
---|
| 138 | /* Graphic box codes - only applicable for console display */
|
---|
| 139 | /* in visual mode "map". */
|
---|
| 140 |
|
---|
| 141 | #if (CHIP == INTEL)
|
---|
| 142 | #define BOX_CLR ' ' /* Empty box */
|
---|
| 143 | #define BOX_ALL '\333' /* Filled box */
|
---|
| 144 | #define BOX_TOP '\337' /* Filled upper half */
|
---|
| 145 | #define BOX_BOT '\334' /* Filled lower half */
|
---|
| 146 | #endif
|
---|
| 147 |
|
---|
| 148 | #if (CHIP == M68000)
|
---|
| 149 | /* Please change these. */
|
---|
| 150 | #define BOX_CLR ' ' /* Empty box */
|
---|
| 151 | #define BOX_ALL '=' /* Filled box */
|
---|
| 152 | #define BOX_TOP '-' /* Filled upper half */
|
---|
| 153 | #define BOX_BOT '_' /* Filled lower half */
|
---|
| 154 | #endif
|
---|
| 155 |
|
---|
| 156 | #if (CHIP == SPARC)
|
---|
| 157 | /* Please change these. */
|
---|
| 158 | #define BOX_CLR ' ' /* Empty box */
|
---|
| 159 | #define BOX_ALL '=' /* Filled box */
|
---|
| 160 | #define BOX_TOP '-' /* Filled upper half */
|
---|
| 161 | #define BOX_BOT '_' /* Filled lower half */
|
---|
| 162 | #endif
|
---|
| 163 |
|
---|
| 164 | /* Move positions for the output display. */
|
---|
| 165 |
|
---|
| 166 | #define STATUS_COLUMN 2
|
---|
| 167 | #define STATUS_LINE 0
|
---|
| 168 | #define BLOCK_COLUMN 4
|
---|
| 169 | #define BLOCK_LINE 4
|
---|
| 170 | #define INFO_COLUMN 30
|
---|
| 171 | #define INFO_LINE BLOCK_LINE
|
---|
| 172 | #define PROMPT_COLUMN 0
|
---|
| 173 | #define PROMPT_LINE 23
|
---|
| 174 | #define WARNING_COLUMN 5
|
---|
| 175 | #define WARNING_LINE 10
|
---|
| 176 |
|
---|
| 177 |
|
---|
| 178 |
|
---|
| 179 | /* Values returned by Process() and Get_Filename() */
|
---|
| 180 |
|
---|
| 181 | #define OK 0 /* No update required */
|
---|
| 182 | #define REDRAW 1 /* Redraw whole screen */
|
---|
| 183 | #define REDRAW_POINTERS 2 /* Redraw just ptrs */
|
---|
| 184 | #define ERROR 3 /* Beep */
|
---|
| 185 |
|
---|
| 186 |
|
---|
| 187 | /* Visual modes */
|
---|
| 188 |
|
---|
| 189 | #define WORD 1
|
---|
| 190 | #define BLOCK 2
|
---|
| 191 | #define MAP 3
|
---|
| 192 |
|
---|
| 193 | typedef unsigned short word_t; /* For most user i/o */
|
---|
| 194 | #if _WORD_SIZE == 2
|
---|
| 195 | typedef unsigned int Word_t; /* What it should always be */
|
---|
| 196 | #else
|
---|
| 197 | typedef int Word_t; /* Unsigned promotion under ANSI C */
|
---|
| 198 | #endif
|
---|
| 199 |
|
---|
| 200 | #ifndef I_MAP_SLOTS
|
---|
| 201 | /* Max number of inode and zone map blocks we can handle. */
|
---|
| 202 | #define I_MAP_SLOTS 8
|
---|
| 203 | #define Z_MAP_SLOTS (sizeof(char *) == 2 ? 16 : 128)
|
---|
| 204 | #endif
|
---|
| 205 |
|
---|
| 206 | typedef struct de_state /* State of disk ed. */
|
---|
| 207 | {
|
---|
| 208 | /* Information from super block */
|
---|
| 209 | /* The types here are mostly promoted types for simplicity */
|
---|
| 210 | /* and efficiency. */
|
---|
| 211 |
|
---|
| 212 | unsigned inodes; /* Number of i-nodes */
|
---|
| 213 | zone_t zones; /* Total # of blocks */
|
---|
| 214 | unsigned inode_maps; /* I-node map blocks */
|
---|
| 215 | unsigned zone_maps; /* Zone map blocks */
|
---|
| 216 | unsigned inode_blocks; /* I-node blocks */
|
---|
| 217 | unsigned first_data; /* Total non-data blks */
|
---|
| 218 | int magic; /* Magic number */
|
---|
| 219 |
|
---|
| 220 | /* Numbers derived from the magic number */
|
---|
| 221 |
|
---|
| 222 | unsigned char is_fs; /* Nonzero for good fs */
|
---|
| 223 | unsigned char v1; /* Nonzero for V1 fs */
|
---|
| 224 | unsigned inode_size; /* Size of disk inode */
|
---|
| 225 | unsigned nr_indirects; /* # indirect blocks */
|
---|
| 226 | unsigned zone_num_size; /* Size of disk z num */
|
---|
| 227 | int block_size; /* FS block size */
|
---|
| 228 |
|
---|
| 229 | /* Other derived numbers */
|
---|
| 230 |
|
---|
| 231 | bit_t inodes_in_map; /* Bits in i-node map */
|
---|
| 232 | bit_t zones_in_map; /* Bits in zone map */
|
---|
| 233 | int ndzones; /* # direct zones in an inode */
|
---|
| 234 |
|
---|
| 235 | /* Information from map blocks */
|
---|
| 236 |
|
---|
| 237 | bitchunk_t inode_map[ I_MAP_SLOTS * K / sizeof (bitchunk_t) ];
|
---|
| 238 | bitchunk_t zone_map[ Z_MAP_SLOTS * K / sizeof (bitchunk_t) ];
|
---|
| 239 |
|
---|
| 240 | /* Information for current block */
|
---|
| 241 |
|
---|
| 242 | off_t address; /* Current address */
|
---|
| 243 | off_t last_addr; /* For erasing ptrs */
|
---|
| 244 | zone_t block; /* Current block (1K) */
|
---|
| 245 | unsigned offset; /* Offset within block */
|
---|
| 246 |
|
---|
| 247 | char buffer[ _MAX_BLOCK_SIZE ];
|
---|
| 248 |
|
---|
| 249 | /* Display state */
|
---|
| 250 |
|
---|
| 251 | int mode; /* WORD, BLOCK or MAP */
|
---|
| 252 | int output_base; /* 2, 8, 10, or 16 */
|
---|
| 253 |
|
---|
| 254 | /* Search information */
|
---|
| 255 |
|
---|
| 256 | char search_string[ MAX_STRING + 1 ]; /* For '/' and 'n' */
|
---|
| 257 | off_t prev_addr[ MAX_PREV ]; /* For 'p' command */
|
---|
| 258 | int prev_mode[ MAX_PREV ];
|
---|
| 259 |
|
---|
| 260 | /* File information */
|
---|
| 261 |
|
---|
| 262 | char *device_name; /* From command line */
|
---|
| 263 | int device_d;
|
---|
| 264 | int device_mode; /* O_RDONLY or O_RDWR */
|
---|
| 265 | zone_t device_size; /* Number of blocks */
|
---|
| 266 |
|
---|
| 267 | char file_name[ MAX_STRING + 1 ]; /* For 'w' and 'W' */
|
---|
| 268 | FILE *file_f;
|
---|
| 269 | int file_written; /* Flag if written to */
|
---|
| 270 |
|
---|
| 271 | } de_state;
|
---|
| 272 |
|
---|
| 273 |
|
---|
| 274 |
|
---|
| 275 | /* Forward references for external routines */
|
---|
| 276 |
|
---|
| 277 | /* de.c */
|
---|
| 278 |
|
---|
| 279 | _PROTOTYPE(void main , (int argc , char *argv []));
|
---|
| 280 | _PROTOTYPE(int Process , (de_state *s , int c ));
|
---|
| 281 |
|
---|
| 282 | #if __STDC__
|
---|
| 283 | void Error( const char *text, ... );
|
---|
| 284 | #else
|
---|
| 285 | void Error();
|
---|
| 286 | #endif
|
---|
| 287 |
|
---|
| 288 | _PROTOTYPE(int In_Use , (bit_t bit , bitchunk_t *map ));
|
---|
| 289 | _PROTOTYPE(ino_t Find_Inode , (de_state *s , char *filename ));
|
---|
| 290 |
|
---|
| 291 |
|
---|
| 292 | /* de_stdin.c */
|
---|
| 293 |
|
---|
| 294 | _PROTOTYPE(void Save_Term , (void));
|
---|
| 295 | _PROTOTYPE(void Set_Term , (void));
|
---|
| 296 | _PROTOTYPE(void Reset_Term , (void));
|
---|
| 297 | _PROTOTYPE(int Get_Char , (void));
|
---|
| 298 | _PROTOTYPE(char *Get_Line , (void));
|
---|
| 299 | _PROTOTYPE(int Arrow_Esc , (int c ));
|
---|
| 300 |
|
---|
| 301 | /* de_stdout.c */
|
---|
| 302 |
|
---|
| 303 | _PROTOTYPE(int Init_Termcap , (void));
|
---|
| 304 | _PROTOTYPE(void Draw_Help_Screen , (de_state *s ));
|
---|
| 305 | _PROTOTYPE(void Wait_For_Key , (void));
|
---|
| 306 | _PROTOTYPE(void Draw_Prompt , (char *string ));
|
---|
| 307 | _PROTOTYPE(void Erase_Prompt , (void));
|
---|
| 308 |
|
---|
| 309 | _PROTOTYPE(void Draw_Screen , (de_state *s ));
|
---|
| 310 | _PROTOTYPE(void Draw_Strings , (de_state *s ));
|
---|
| 311 | _PROTOTYPE(void Draw_Pointers , (de_state *s ));
|
---|
| 312 | _PROTOTYPE(void Print_Ascii , (int c ));
|
---|
| 313 |
|
---|
| 314 | _PROTOTYPE(void Goto , (int column , int line ));
|
---|
| 315 | _PROTOTYPE(void Block_Type , (de_state *s ));
|
---|
| 316 | _PROTOTYPE(void Draw_Words , (de_state *s ));
|
---|
| 317 | _PROTOTYPE(void Draw_Info , (de_state *s ));
|
---|
| 318 | _PROTOTYPE(void Draw_Block , (char *block ));
|
---|
| 319 | _PROTOTYPE(void Draw_Map , (char *block , int max_bits ));
|
---|
| 320 | _PROTOTYPE(void Draw_Offset , (de_state *s ));
|
---|
| 321 | _PROTOTYPE(void Word_Pointers , (off_t old_addr , off_t new_addr ));
|
---|
| 322 | _PROTOTYPE(void Block_Pointers , (off_t old_addr , off_t new_addr ));
|
---|
| 323 | _PROTOTYPE(void Map_Pointers , (off_t old_addr , off_t new_addr ));
|
---|
| 324 | _PROTOTYPE(void Print_Number , (Word_t number , int output_base ));
|
---|
| 325 | _PROTOTYPE(void Draw_Zone_Numbers , (de_state *s , struct inode *inode ,
|
---|
| 326 | int zindex , int zrow ));
|
---|
| 327 |
|
---|
| 328 | #if __STDC__
|
---|
| 329 | void Warning( const char *text, ... );
|
---|
| 330 | #else
|
---|
| 331 | void Warning();
|
---|
| 332 | #endif
|
---|
| 333 |
|
---|
| 334 |
|
---|
| 335 | /* de_diskio.c */
|
---|
| 336 |
|
---|
| 337 | _PROTOTYPE(void Read_Disk , (de_state *s , off_t block_addr , char *buffer ));
|
---|
| 338 | _PROTOTYPE(void Read_Block , (de_state *s , char *buffer ));
|
---|
| 339 | _PROTOTYPE(void Read_Super_Block , (de_state *s ));
|
---|
| 340 | _PROTOTYPE(void Read_Bit_Maps , (de_state *s ));
|
---|
| 341 | _PROTOTYPE(off_t Search , (de_state *s , char *string ));
|
---|
| 342 | _PROTOTYPE(void Write_Word , (de_state *s , Word_t word ));
|
---|
| 343 |
|
---|
| 344 |
|
---|
| 345 | /* de_recover.c */
|
---|
| 346 |
|
---|
| 347 | _PROTOTYPE(int Path_Dir_File , (char *path_name , char **dir_name ,
|
---|
| 348 | char **file_name ));
|
---|
| 349 | _PROTOTYPE(char *File_Device , (char *file_name ));
|
---|
| 350 | _PROTOTYPE(ino_t Find_Deleted_Entry , (de_state *s , char *path_name ));
|
---|
| 351 | _PROTOTYPE(off_t Recover_Blocks , (de_state *s ));
|
---|
| 352 |
|
---|
| 353 |
|
---|
| 354 | #undef printf /* Because fs/const.h */
|
---|
| 355 | /* defines it. */
|
---|
| 356 |
|
---|
| 357 |
|
---|
| 358 | /* Static functions are all pre-declared FORWARD but none are */
|
---|
| 359 | /* declared static yet - this can wait until all functions are */
|
---|
| 360 | /* declared with prototypes. */
|
---|
| 361 |
|
---|
| 362 | #undef FORWARD
|
---|
| 363 | #define FORWARD /* static */
|
---|