Whamcloud - gitweb
e2fsck: mark that we don't care about the return value of e2fsck_lookup()
[tools/e2fsprogs.git] / ext2ed / file_com.c
1 /*
2
3 /usr/src/ext2ed/file_com.c
4
5 A part of the extended file system 2 disk editor.
6
7 ----------------------------
8 Commands which handle a file
9 ----------------------------
10
11 First written on: April 18 1995
12
13 Copyright (C) 1995 Gadi Oxman
14
15 */
16
17 #include "config.h"
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #include "ext2ed.h"
23
24 int init_file_info (void)
25
26 {
27         struct ext2_inode *ptr;
28
29         ptr=&type_data.u.t_ext2_inode;
30
31         file_info.inode_ptr=ptr;
32         file_info.inode_offset=device_offset;
33
34         file_info.global_block_num=ptr->i_block [0];
35         file_info.global_block_offset=ptr->i_block [0]*file_system_info.block_size;
36         file_info.block_num=0;
37         file_info.blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size;
38         file_info.file_offset=0;
39         file_info.file_length=ptr->i_size;
40         file_info.level=0;
41         file_info.offset_in_block=0;
42
43         file_info.display=HEX;
44
45         low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
46
47         return (1);
48 }
49
50
51 void type_file___inode (char *command_line)
52
53 {
54         dispatch ("settype ext2_inode");
55 }
56
57 void type_file___show (char *command_line)
58
59 {
60         if (file_info.display==HEX)
61                 file_show_hex ();
62         if (file_info.display==TEXT)
63                 file_show_text ();
64 }
65
66 void type_file___nextblock (char *command_line)
67
68 {
69         long block_offset=1;
70         char *ptr,buffer [80];
71
72         ptr=parse_word (command_line,buffer);
73
74         if (*ptr!=0) {
75                 ptr=parse_word (ptr,buffer);
76                 block_offset*=atol (buffer);
77         }
78
79         if (file_info.block_num+block_offset >= file_info.blocks_count) {
80                 wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
81                 return;
82         }
83
84         file_info.block_num+=block_offset;
85         file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
86         file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
87         file_info.file_offset=file_info.block_num*file_system_info.block_size;
88
89         low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
90
91         strcpy (buffer,"show");dispatch (buffer);
92 }
93
94 void type_file___next (char *command_line)
95
96 {
97         int offset=1;
98         char *ptr,buffer [80];
99
100         ptr=parse_word (command_line,buffer);
101
102         if (*ptr!=0) {
103                 ptr=parse_word (ptr,buffer);
104                 offset*=atol (buffer);
105         }
106
107         if (file_info.offset_in_block+offset < file_system_info.block_size) {
108                 file_info.offset_in_block+=offset;
109                 sprintf (buffer,"show");dispatch (buffer);
110         }
111
112         else {
113                 wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
114         }
115 }
116
117 void type_file___offset (char *command_line)
118
119 {
120         unsigned long offset;
121         char *ptr,buffer [80];
122
123         ptr=parse_word (command_line,buffer);
124
125         if (*ptr!=0) {
126                 ptr=parse_word (ptr,buffer);
127                 offset=atol (buffer);
128         }
129         else {
130                 wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();
131                 return;
132         }
133
134         if (offset < file_system_info.block_size) {
135                 file_info.offset_in_block=offset;
136                 sprintf (buffer,"show");dispatch (buffer);
137         }
138
139         else {
140                 wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
141         }
142 }
143
144 void type_file___prev (char *command_line)
145
146 {
147         int offset=1;
148         char *ptr,buffer [80];
149
150         ptr=parse_word (command_line,buffer);
151
152         if (*ptr!=0) {
153                 ptr=parse_word (ptr,buffer);
154                 offset*=atol (buffer);
155         }
156
157         if (file_info.offset_in_block-offset >= 0) {
158                 file_info.offset_in_block-=offset;
159                 sprintf (buffer,"show");dispatch (buffer);
160         }
161
162         else {
163                 wprintw (command_win,"Error - Offset out of block\n");refresh_command_win ();
164         }
165 }
166
167 void type_file___prevblock (char *command_line)
168
169 {
170         long block_offset=1;
171         char *ptr,buffer [80];
172
173         ptr=parse_word (command_line,buffer);
174
175         if (*ptr!=0) {
176                 ptr=parse_word (ptr,buffer);
177                 block_offset*=atol (buffer);
178         }
179
180         if (file_info.block_num-block_offset < 0) {
181                 wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
182                 return;
183         }
184
185         file_info.block_num-=block_offset;
186         file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
187         file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
188         file_info.file_offset=file_info.block_num*file_system_info.block_size;
189
190         low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
191
192         strcpy (buffer,"show");dispatch (buffer);
193 }
194
195 void type_file___block (char *command_line)
196
197 {
198         long block_offset=1;
199         char *ptr,buffer [80];
200
201         ptr=parse_word (command_line,buffer);
202
203         if (*ptr==0) {
204                 wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
205                 return;
206         }
207
208         ptr=parse_word (ptr,buffer);
209         block_offset=atol (buffer);
210
211         if (block_offset < 0 || block_offset >= file_info.blocks_count) {
212                 wprintw (command_win,"Error - Block offset out of range\n");wrefresh (command_win);
213                 return;
214         }
215
216         file_info.block_num=block_offset;
217         file_info.global_block_num=file_block_to_global_block (file_info.block_num,&file_info);
218         file_info.global_block_offset=file_info.global_block_num*file_system_info.block_size;
219         file_info.file_offset=file_info.block_num*file_system_info.block_size;
220
221         low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
222
223         strcpy (buffer,"show");dispatch (buffer);
224 }
225
226 void type_file___display (char *command_line)
227
228 {
229         char *ptr,buffer [80];
230
231         ptr=parse_word (command_line,buffer);
232         if (*ptr==0)
233                 strcpy (buffer,"hex");
234         else
235                 ptr=parse_word (ptr,buffer);
236
237         if (strcasecmp (buffer,"hex")==0) {
238                 wprintw (command_win,"Display set to hex\n");wrefresh (command_win);
239                 file_info.display=HEX;
240                 sprintf (buffer,"show");dispatch (buffer);
241         }
242
243         else if (strcasecmp (buffer,"text")==0) {
244                 wprintw (command_win,"Display set to text\n");wrefresh (command_win);
245                 file_info.display=TEXT;
246                 sprintf (buffer,"show");dispatch (buffer);
247         }
248
249         else {
250                 wprintw (command_win,"Error - Invalid arguments\n");wrefresh (command_win);
251         }
252 }
253
254 void file_show_hex (void)
255
256 {
257         long offset=0,l,i;
258         unsigned char *ch_ptr;
259
260         /* device_offset and type_data points to the inode */
261
262         show_pad_info.line=0;
263
264         wmove (show_pad,0,0);
265         ch_ptr=file_info.buffer;
266         for (l=0;l<file_system_info.block_size/16;l++) {
267                 if (file_info.file_offset+offset>file_info.file_length-1) break;
268                 wprintw (show_pad,"%08ld :  ",offset);
269                 for (i=0;i<16;i++) {
270
271                         if (file_info.file_offset+offset+i>file_info.file_length-1) {
272                                 wprintw (show_pad," ");
273                         }
274
275                         else {
276                                 if (file_info.offset_in_block==offset+i)
277                                         wattrset (show_pad,A_REVERSE);
278
279                                 if (ch_ptr [i]>=' ' && ch_ptr [i]<='z')
280                                         wprintw (show_pad,"%c",ch_ptr [i]);
281                                 else
282                                         wprintw (show_pad,".");
283
284                                 if (file_info.offset_in_block==offset+i)
285                                         wattrset (show_pad,A_NORMAL);
286                         }
287                 }
288
289                 wprintw (show_pad,"   ");
290                 for (i=0;i<16;i++) {
291                         if (file_info.file_offset+offset+i>file_info.file_length-1) break;
292                         if (file_info.offset_in_block==offset+i)
293                                 wattrset (show_pad,A_REVERSE);
294
295                         wprintw (show_pad,"%02x",ch_ptr [i]);
296
297                         if (file_info.offset_in_block==offset+i) {
298                                 wattrset (show_pad,A_NORMAL);
299                                 show_pad_info.line=l-l % show_pad_info.display_lines;
300                         }
301
302                         wprintw (show_pad," ");
303
304                 }
305
306                 wprintw (show_pad,"\n");
307                 offset+=i;
308                 ch_ptr+=i;
309         }
310
311         show_pad_info.max_line=l-1;
312
313         refresh_show_pad ();
314
315         show_status ();
316 }
317
318 void file_show_text (void)
319
320 {
321         long offset=0,last_offset,l=0,cols=0;
322         unsigned char *ch_ptr;
323
324         /* device_offset and type_data points to the inode */
325
326         show_pad_info.line=0;
327         wmove (show_pad,0,0);
328         ch_ptr=file_info.buffer;
329
330         last_offset=file_system_info.block_size-1;
331
332         if (file_info.file_offset+last_offset > file_info.file_length-1)
333                 last_offset=file_info.file_length-1-file_info.file_offset;
334
335         while ( (offset <= last_offset) && l<SHOW_PAD_LINES) {
336
337                 if (cols==SHOW_PAD_COLS-1) {
338                         wprintw (show_pad,"\n");
339                         l++;cols=0;
340                 }
341
342
343                 if (file_info.offset_in_block==offset)
344                         wattrset (show_pad,A_REVERSE);
345
346                 if (*ch_ptr >= ' ' && *ch_ptr <= 'z')
347                         wprintw (show_pad,"%c",*ch_ptr);
348
349
350                 else {
351                         if (*ch_ptr == 0xa) {
352                                 wprintw (show_pad,"\n");
353                                 l++;cols=0;
354                         }
355
356                         else if (*ch_ptr == 0x9)
357                                 wprintw (show_pad,"    ");
358
359                         else
360                                 wprintw (show_pad,".");
361                 }
362
363                 if (file_info.offset_in_block==offset) {
364                         wattrset (show_pad,A_NORMAL);
365                         show_pad_info.line=l-l % show_pad_info.display_lines;
366                 }
367
368
369                 offset++;cols++;ch_ptr++;
370         }
371
372         wprintw (show_pad,"\n");
373         show_pad_info.max_line=l;
374
375         refresh_show_pad ();
376
377         show_status ();
378 }
379
380 void show_status (void)
381
382 {
383         long inode_num;
384
385         werase (show_win);wmove (show_win,0,0);
386         wprintw (show_win,"File contents. Block %ld. ",file_info.global_block_num);
387         wprintw (show_win,"File block %ld of %ld. ",file_info.block_num,file_info.blocks_count-1);
388         wprintw (show_win,"File Offset %ld of %ld.",file_info.file_offset,file_info.file_length-1);
389
390         wmove (show_win,1,0);
391         inode_num=inode_offset_to_inode_num (file_info.inode_offset);
392         wprintw (show_win,"File inode %ld. Indirection level %ld.",inode_num,file_info.level);
393
394         refresh_show_win ();
395 }
396
397 void type_file___remember (char *command_line)
398
399 {
400         int found=0;
401         long entry_num;
402         char *ptr,buffer [80];
403         struct struct_descriptor *descriptor_ptr;
404
405         ptr=parse_word (command_line,buffer);
406
407         if (*ptr==0) {
408                 wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win);
409                 return;
410         }
411
412         ptr=parse_word (ptr,buffer);
413
414         entry_num=remember_lifo.entries_count++;
415         if (entry_num>REMEMBER_COUNT-1) {
416                 entry_num=0;
417                 remember_lifo.entries_count--;
418         }
419
420         descriptor_ptr=first_type;
421         while (descriptor_ptr!=NULL && !found) {
422                 if (strcmp (descriptor_ptr->name,"ext2_inode")==0)
423                         found=1;
424                 else
425                         descriptor_ptr=descriptor_ptr->next;
426         }
427
428
429         remember_lifo.offset [entry_num]=device_offset;
430         remember_lifo.type [entry_num]=descriptor_ptr;
431         strcpy (remember_lifo.name [entry_num],buffer);
432
433         wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer);
434         wrefresh (command_win);
435 }
436
437 void type_file___set (char *command_line)
438
439 {
440         unsigned char tmp;
441         char *ptr,buffer [80],*ch_ptr;
442         int mode=HEX;
443
444         ptr=parse_word (command_line,buffer);
445         if (*ptr==0) {
446                 wprintw (command_win,"Error - Argument not specified\n");refresh_command_win ();return;
447         }
448
449         ptr=parse_word (ptr,buffer);
450
451         if (strcasecmp (buffer,"text")==0) {
452                 mode=TEXT;
453                 strcpy (buffer,ptr);
454         }
455
456         else if (strcasecmp (buffer,"hex")==0) {
457                 mode=HEX;
458                 ptr=parse_word (ptr,buffer);
459         }
460
461         if (*buffer==0) {
462                 wprintw (command_win,"Error - Data not specified\n");refresh_command_win ();return;
463         }
464
465         if (mode==HEX) {
466                 do {
467                         tmp=(unsigned char) strtol (buffer,NULL,16);
468                         file_info.buffer [file_info.offset_in_block]=tmp;
469                         file_info.offset_in_block++;
470                         ptr=parse_word (ptr,buffer);
471                         if (file_info.offset_in_block==file_system_info.block_size) {
472                                 if (*ptr) {
473                                         wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
474                                         refresh_command_win ();
475                                 }
476                                 file_info.offset_in_block--;
477                         }
478                 } while (*buffer) ;
479         }
480
481         else {
482                 ch_ptr=buffer;
483                 while (*ch_ptr) {
484                         tmp=(unsigned char) *ch_ptr++;
485                         file_info.buffer [file_info.offset_in_block]=tmp;
486                         file_info.offset_in_block++;
487                         if (file_info.offset_in_block==file_system_info.block_size) {
488                                 if (*ch_ptr) {
489                                         wprintw (command_win,"Error - Ending offset outside block, only partial string changed\n");
490                                         refresh_command_win ();
491                                 }
492                                 file_info.offset_in_block--;
493                         }
494                 }
495         }
496
497         strcpy (buffer,"show");dispatch (buffer);
498 }
499
500 void type_file___writedata (char *command_line)
501
502 {
503         low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
504         return;
505 }
506
507 long file_block_to_global_block (long file_block,struct struct_file_info *file_info_ptr)
508
509 {
510         long last_direct,last_indirect,last_dindirect;
511
512         last_direct=EXT2_NDIR_BLOCKS-1;
513         last_indirect=last_direct+file_system_info.block_size/4;
514         last_dindirect=last_indirect+(file_system_info.block_size/4)*(file_system_info.block_size/4);
515
516         if (file_block <= last_direct) {
517                 file_info_ptr->level=0;
518                 return (file_info_ptr->inode_ptr->i_block [file_block]);
519         }
520
521         if (file_block <= last_indirect) {
522                 file_info_ptr->level=1;
523                 file_block=file_block-last_direct-1;
524                 return (return_indirect (file_info_ptr->inode_ptr->i_block [EXT2_IND_BLOCK],file_block));
525         }
526
527         if (file_block <= last_dindirect) {
528                 file_info_ptr->level=2;
529                 file_block=file_block-last_indirect-1;
530                 return (return_dindirect (file_info_ptr->inode_ptr->i_block [EXT2_DIND_BLOCK],file_block));
531         }
532
533         file_info_ptr->level=3;
534         file_block=file_block-last_dindirect-1;
535         return (return_tindirect (file_info_ptr->inode_ptr->i_block [EXT2_TIND_BLOCK],file_block));
536 }
537
538 long return_indirect (long table_block,long block_num)
539
540 {
541         long block_table [EXT2_MAX_BLOCK_SIZE/4];
542
543         low_read ((char *) block_table,file_system_info.block_size,table_block*file_system_info.block_size);
544         return (block_table [block_num]);
545 }
546
547 long return_dindirect (long table_block,long block_num)
548
549 {
550         long f_indirect;
551
552         f_indirect=block_num/(file_system_info.block_size/4);
553         f_indirect=return_indirect (table_block,f_indirect);
554         return (return_indirect (f_indirect,block_num%(file_system_info.block_size/4)));
555 }
556
557 long return_tindirect (long table_block,long block_num)
558
559 {
560         long s_indirect;
561
562         s_indirect=block_num/((file_system_info.block_size/4)*(file_system_info.block_size/4));
563         s_indirect=return_indirect (table_block,s_indirect);
564         return (return_dindirect (s_indirect,block_num%((file_system_info.block_size/4)*(file_system_info.block_size/4))));
565 }