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 */
|
---|