~csurbhi/ubuntu/maverick/e2fsprogs/e2fsprogs.fix-505719

« back to all changes in this revision

Viewing changes to ext2ed/dir_com.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-09-19 09:43:14 UTC
  • mto: (8.1.1 lenny) (1.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040919094314-2tafd19i76fhu6ei
Tags: upstream-1.35
ImportĀ upstreamĀ versionĀ 1.35

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
/usr/src/ext2ed/dir_com.c
 
4
 
 
5
A part of the extended file system 2 disk editor.
 
6
 
 
7
--------------------
 
8
Handles directories.
 
9
--------------------
 
10
 
 
11
This file contains the codes which allows the user to handle directories.
 
12
 
 
13
Most of the functions use the global variable file_info (along with the special directory fields there) to save
 
14
information and pass it between them.
 
15
 
 
16
Since a directory is just a big file which is composed of directory entries, you will find that
 
17
the functions here are a superset of those in the file_com.c source.
 
18
 
 
19
We assume that the user reached here using the dir command of the inode type and not by using settype dir, so
 
20
that init_dir_info is indeed called to gather the required information.
 
21
 
 
22
type_data is not changed ! It still contains the inode of the file - We handle the directory in our own
 
23
variables, so that settype ext2_inode will "go back" to the inode of this directory.
 
24
 
 
25
First written on: April 28 1995
 
26
 
 
27
Copyright (C) 1995 Gadi Oxman
 
28
 
 
29
*/
 
30
 
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
 
 
35
#include "ext2ed.h"
 
36
 
 
37
char name_search [80];
 
38
long entry_num_search;
 
39
 
 
40
int init_dir_info (struct struct_file_info *info_ptr)
 
41
 
 
42
/*
 
43
 
 
44
This function is called by the inode of the directory when the user issues the dir command from the inode.
 
45
It is used to gather information about the inode and to reset some variables which we need in order to handle
 
46
directories.
 
47
 
 
48
*/
 
49
 
 
50
{
 
51
        struct ext2_inode *ptr;
 
52
        
 
53
        ptr=&type_data.u.t_ext2_inode;                                  /* type_data contains the inode */
 
54
        
 
55
        info_ptr->inode_ptr=ptr;
 
56
        info_ptr->inode_offset=device_offset;                           /* device offset contains the inode's offset */
 
57
                                                                        
 
58
                                                                        /* Reset the current position to the start */
 
59
 
 
60
        info_ptr->global_block_num=ptr->i_block [0];                    
 
61
        info_ptr->global_block_offset=ptr->i_block [0]*file_system_info.block_size;
 
62
        info_ptr->block_num=0;
 
63
        info_ptr->file_offset=0;
 
64
                                                                        /* Set the size of the directory */
 
65
                                                                        
 
66
        info_ptr->blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size;
 
67
        info_ptr->file_length=ptr->i_size;
 
68
 
 
69
        info_ptr->level=0;                                              /* We start using direct blocks */
 
70
        info_ptr->display=HEX;                                          /* This is not actually used */
 
71
 
 
72
        info_ptr->dir_entry_num=0;info_ptr->dir_entries_count=0;        /* We'll start at the first directory entry */
 
73
        info_ptr->dir_entry_offset=0;
 
74
 
 
75
        /* Find dir_entries_count */
 
76
        
 
77
        info_ptr->dir_entries_count=count_dir_entries ();               /* Set the total number of entries */
 
78
        
 
79
        return (1);
 
80
}
 
81
 
 
82
struct struct_file_info search_dir_entries (int (*action) (struct struct_file_info *info),int *status)
 
83
 
 
84
/*
 
85
        This is the main function in this source file. Various actions are implemented using this basic function.
 
86
 
 
87
        This routine runs on all directory entries in the current directory.
 
88
        For each entry, action is called. We'll act according to the return code of action:
 
89
        
 
90
                ABORT           -       Current dir entry is returned.
 
91
                CONTINUE        -       Continue searching.
 
92
                FOUND           -       Current dir entry is returned.
 
93
                
 
94
        If the last entry is reached, it is returned, along with an ABORT status.
 
95
        
 
96
        status is updated to the returned code of action.       
 
97
*/
 
98
 
 
99
{
 
100
        struct struct_file_info info;                                           /* Temporary variables used to */
 
101
        struct ext2_dir_entry_2 *dir_entry_ptr;                                 /* contain the current search entries */
 
102
        int return_code, next;
 
103
        
 
104
        info=first_file_info;                                                   /* Start from the first entry - Read it */
 
105
        low_read (info.buffer,file_system_info.block_size,info.global_block_offset);
 
106
        dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset);
 
107
        
 
108
        while (info.file_offset < info.file_length) {                           /* While we haven't reached the end */
 
109
                
 
110
                *status=return_code=action (&info);                             /* Call the client function to test */
 
111
                                                                                /* the current entry */ 
 
112
                if (return_code==ABORT || return_code==FOUND)
 
113
                        return (info);                                          /* Stop, if so asked */
 
114
 
 
115
                                                                                /* Pass to the next entry */
 
116
                                                                                
 
117
                dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset);
 
118
 
 
119
                info.dir_entry_num++;
 
120
                next = dir_entry_ptr->rec_len;
 
121
                if (!next)
 
122
                        next = file_system_info.block_size - info.dir_entry_offset;
 
123
                info.dir_entry_offset += next;
 
124
                info.file_offset += next;
 
125
 
 
126
                if (info.file_offset >= info.file_length) break;
 
127
 
 
128
                if (info.dir_entry_offset >= file_system_info.block_size) {     /* We crossed a block boundary */
 
129
                                                                                /* Find the next block, */
 
130
                        info.block_num++;
 
131
                        info.global_block_num=file_block_to_global_block (info.block_num,&info);
 
132
                        info.global_block_offset=info.global_block_num*file_system_info.block_size;
 
133
                        info.file_offset=info.block_num*file_system_info.block_size;
 
134
                        info.dir_entry_offset=0;                
 
135
                                                                                /* read it and update the pointer */
 
136
                                                                                
 
137
                        low_read (info.buffer,file_system_info.block_size,info.global_block_offset);
 
138
                        dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset);
 
139
                        
 
140
                }
 
141
                
 
142
        }
 
143
        
 
144
        *status=ABORT;return (info);                                            /* There was no match */
 
145
}
 
146
 
 
147
long count_dir_entries (void)
 
148
 
 
149
/*
 
150
 
 
151
This function counts the number of entries in the directory. We just call search_dir_entries till the end.
 
152
The client function is action_count, which just tell search_dir_entries to continue.
 
153
 
 
154
*/
 
155
 
 
156
{
 
157
        int status;
 
158
        
 
159
        return (search_dir_entries (&action_count,&status).dir_entry_num);
 
160
}
 
161
 
 
162
int action_count (struct struct_file_info *info)
 
163
 
 
164
/*
 
165
 
 
166
Used by count_dir_entries above - This function is called by search_dir_entries, and it tells it to continue
 
167
searching, until we get to the last entry.
 
168
 
 
169
*/
 
170
 
 
171
{
 
172
        return (CONTINUE);                                                      /* Just continue searching */
 
173
}
 
174
 
 
175
void type_dir___cd (char *command_line)
 
176
 
 
177
/*
 
178
        Changes to a directory, relative to the current directory.
 
179
 
 
180
        This is a complicated operation, so I would repeat here the explanation from the design and
 
181
        implementation document.
 
182
 
 
183
1.      The path is checked that it is not an absolute path (from /). If it is, we let the general cd to do the job by
 
184
        calling directly type_ext2___cd.
 
185
 
 
186
2.      The path is divided into the nearest path and the rest of the path. For example, cd 1/2/3/4 is divided into
 
187
        1 and into 2/3/4.
 
188
 
 
189
3.      It is the first part of the path that we need to search for in the current directory. We search for it using
 
190
        search_dir_entries, which accepts the action_name function as the client function. 
 
191
 
 
192
4.      search_dir_entries will scan the entire entries and will call our action_name function for each entry.
 
193
        In action_name, the required name will be checked against the name of the current entry, and FOUND will be
 
194
        returned when a match occurs.
 
195
 
 
196
5.      If the required entry is found, we dispatch a remember command to insert the current inode (remember that
 
197
        type_data is still intact and contains the inode of the current directory) into the object memory.
 
198
        This is required to easily support symbolic links - If we find later that the inode pointed by the entry is
 
199
        actually a symbolic link, we'll need to return to this point, and the above inode doesn't have (and can't have,
 
200
        because of hard links) the information necessary to "move back".
 
201
 
 
202
6.      We then dispatch a followinode command to reach the inode pointed by the required entry. This command will
 
203
        automatically change the type to ext2_inode - We are now at an inode, and all the inode commands are available.
 
204
 
 
205
7.      We check the inode's type to see if it is a directory. If it is, we dispatch a dir command to "enter the directory",
 
206
        and recursively call ourself (The type is dir again) by dispatching a cd command, with the rest of the path
 
207
        as an argument.
 
208
        
 
209
8.      If the inode's type is a symbolic link (only fast symbolic link were meanwhile implemented. I guess this is
 
210
        typically the case.), we note the path it is pointing at, the saved inode is recalled, we dispatch dir to
 
211
        get back to the original directory, and we call ourself again with the link path/rest of the path argument.
 
212
 
 
213
9.      In any other case, we just stop at the resulting inode.
 
214
 
 
215
*/
 
216
 
 
217
{
 
218
        int status;
 
219
        char *ptr,full_dir_name [500],dir_name [500],temp [500],temp2 [500];
 
220
        struct struct_file_info info;
 
221
        struct ext2_dir_entry_2 *dir_entry_ptr;
 
222
 
 
223
        dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset);
 
224
                
 
225
        ptr=parse_word (command_line,dir_name);
 
226
        
 
227
        if (*ptr==0) {                                          /* cd alone will enter the highlighted directory */
 
228
                strncpy (full_dir_name,dir_entry_ptr->name,dir_entry_ptr->name_len);
 
229
                full_dir_name [dir_entry_ptr->name_len]=0;
 
230
        }
 
231
        else
 
232
                ptr=parse_word (ptr,full_dir_name);
 
233
 
 
234
        ptr=strchr (full_dir_name,'/');
 
235
        
 
236
        if (ptr==full_dir_name) {                               /* Pathname is from root - Let the general cd do the job */
 
237
                sprintf (temp,"cd %s",full_dir_name);type_ext2___cd (temp);return;
 
238
        }
 
239
        
 
240
        if (ptr==NULL) {
 
241
                strcpy (dir_name,full_dir_name);
 
242
                full_dir_name [0]=0;
 
243
        }
 
244
 
 
245
        else {
 
246
                strncpy (dir_name,full_dir_name,ptr-full_dir_name);
 
247
                dir_name [ptr-full_dir_name]=0;
 
248
                strcpy (full_dir_name,++ptr);
 
249
        }
 
250
                                                                /* dir_name contains the current entry, while */
 
251
                                                                /* full_dir_name contains the rest */
 
252
 
 
253
        strcpy (name_search,dir_name);                          /* name_search is used to hold the required entry name */
 
254
        
 
255
        if (dir_entry_ptr->name_len != strlen (dir_name) ||
 
256
            strncmp (dir_name,dir_entry_ptr->name,dir_entry_ptr->name_len)!=0)
 
257
                info=search_dir_entries (&action_name,&status); /* Search for the entry. Answer in info. */
 
258
        else {
 
259
                status=FOUND;info=file_info;
 
260
        }
 
261
 
 
262
        if (status==FOUND) {                                    /* If found */
 
263
                file_info=info;                                 /* Switch to it, by setting the global file_info */
 
264
                dispatch ("remember internal_variable");        /* Move the inode into the objects memory */
 
265
                
 
266
                dispatch ("followinode");                       /* Go to the inode pointed by this directory entry */
 
267
                
 
268
                if (S_ISLNK (type_data.u.t_ext2_inode.i_mode)) {/* Symbolic link ? */
 
269
 
 
270
                        if (type_data.u.t_ext2_inode.i_size > 60) {     /* I'm lazy, I guess :-) */
 
271
                                wprintw (command_win,"Error - Sorry, Only fast symbolic link following is currently supported\n");
 
272
                                refresh_command_win ();
 
273
                                return;                         
 
274
                        }
 
275
                                                                /* Get the pointed name and append the previous path */
 
276
 
 
277
                        strcpy (temp2,(unsigned char *) &type_data.u.t_ext2_inode.i_block);
 
278
                        strcat (temp2,"/");
 
279
                        strcat (temp2,full_dir_name);
 
280
 
 
281
                        dispatch ("recall internal_variable");  /* Return to the original inode */
 
282
                        dispatch ("dir");                       /* and to the directory */
 
283
                        
 
284
                        sprintf (temp,"cd %s",temp2);           /* And continue from there by dispatching a cd command */
 
285
                        dispatch (temp);                        /* (which can call ourself or the general cd) */
 
286
                        
 
287
                        return;
 
288
                }
 
289
 
 
290
                if (S_ISDIR (type_data.u.t_ext2_inode.i_mode)) { /* Is it an inode of a directory ? */
 
291
 
 
292
                        dispatch ("dir");                       /* Yes - Pass to the pointed directory */
 
293
 
 
294
                        if (full_dir_name [0] != 0) {           /* And call ourself with the rest of the pathname */
 
295
                                sprintf (temp,"cd %s",full_dir_name);
 
296
                                dispatch (temp);
 
297
                        }
 
298
                        
 
299
                        return;
 
300
                }
 
301
                
 
302
                else {                                          /* If we can't continue from here, we'll just stop */
 
303
                        wprintw (command_win,"Can\'t continue - Stopping at last inode\n");refresh_command_win ();
 
304
                        return;
 
305
                }
 
306
        }
 
307
        
 
308
        wprintw (command_win,"Error - Directory entry %s not found.\n",dir_name);       /* Hmm, an invalid path somewhere */
 
309
        refresh_command_win ();
 
310
}
 
311
 
 
312
int action_name (struct struct_file_info *info)
 
313
 
 
314
/*
 
315
 
 
316
Compares the current search entry name (somewhere inside info) with the required name (in name_search).
 
317
Returns FOUND if found, or CONTINUE if not found.
 
318
 
 
319
*/
 
320
 
 
321
{
 
322
        struct ext2_dir_entry_2 *dir_entry_ptr;
 
323
 
 
324
        dir_entry_ptr=(struct ext2_dir_entry_2 *) (info->buffer+info->dir_entry_offset);
 
325
 
 
326
        if (dir_entry_ptr->name_len != strlen (name_search))
 
327
                return (CONTINUE);
 
328
                
 
329
        if (strncmp (dir_entry_ptr->name,name_search,dir_entry_ptr->name_len)==0)
 
330
                return (FOUND);
 
331
 
 
332
        return (CONTINUE);
 
333
}
 
334
 
 
335
void type_dir___entry (char *command_line)
 
336
 
 
337
/*
 
338
 
 
339
Selects a directory entry according to its number.
 
340
search_dir_entries is used along with action_entry_num, in the same fashion as the previous usage of search_dir_entries.
 
341
 
 
342
*/
 
343
 
 
344
{
 
345
        int status;
 
346
        struct struct_file_info info;
 
347
        char *ptr,buffer [80];
 
348
        
 
349
        ptr=parse_word (command_line,buffer);
 
350
        if (*ptr==0) {
 
351
                wprintw (command_win,"Error - Argument_not_specified\n");wrefresh (command_win);
 
352
                return;
 
353
        }
 
354
        ptr=parse_word (ptr,buffer);
 
355
        entry_num_search=atol (buffer);
 
356
        
 
357
        if (entry_num_search < 0 || entry_num_search >= file_info.dir_entries_count) {
 
358
                wprintw (command_win,"Error - Entry number out of range\n");wrefresh (command_win);
 
359
                return;
 
360
        }
 
361
 
 
362
        info=search_dir_entries (&action_entry_num,&status);
 
363
        if (status==FOUND) {
 
364
                file_info=info;
 
365
                dispatch ("show");
 
366
                return;
 
367
        }
 
368
#ifdef DEBUG
 
369
        internal_error ("dir_com","type_dir___entry","According to our gathered data, we should have found this entry");
 
370
#endif
 
371
}
 
372
 
 
373
int action_entry_num (struct struct_file_info *info)
 
374
 
 
375
/*
 
376
 
 
377
Used by the above function. Just compares the current number (in info) with the required one.
 
378
 
 
379
*/
 
380
 
 
381
{
 
382
        if (info->dir_entry_num == entry_num_search)
 
383
                return (FOUND);
 
384
 
 
385
        return (CONTINUE);
 
386
}
 
387
 
 
388
void type_dir___followinode (char *command_line)
 
389
 
 
390
/*
 
391
 
 
392
Here we pass to the inode pointed by the current entry.
 
393
It involves computing the device offset of the inode and using directly the setoffset and settype commands.
 
394
 
 
395
*/
 
396
{
 
397
        long inode_offset;
 
398
        char buffer [80];
 
399
 
 
400
        struct ext2_dir_entry_2 *dir_entry_ptr;
 
401
 
 
402
        low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
 
403
        dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset);
 
404
 
 
405
        inode_offset=inode_num_to_inode_offset (dir_entry_ptr->inode);                  /* Compute the inode's offset */
 
406
        sprintf (buffer,"setoffset %ld",inode_offset);dispatch (buffer);                /* Move to it */
 
407
        sprintf (buffer,"settype ext2_inode");dispatch (buffer);                        /* and set the type to an inode */
 
408
}
 
409
 
 
410
void type_dir___inode (char *command_line)
 
411
 
 
412
/*
 
413
 
 
414
Returns to the parent inode of the current directory.
 
415
This is trivial, as we type_data is still intact and contains the parent inode !
 
416
 
 
417
*/
 
418
 
 
419
{
 
420
        dispatch ("settype ext2_inode");
 
421
}
 
422
 
 
423
 
 
424
void type_dir___show (char *command_line)
 
425
 
 
426
/*
 
427
 
 
428
We use search_dir_entries to run on all the entries. Each time, action_show will be called to show one entry.
 
429
 
 
430
*/
 
431
 
 
432
{
 
433
        int status;
 
434
        
 
435
        wmove (show_pad,0,0);
 
436
        show_pad_info.max_line=-1;
 
437
 
 
438
        search_dir_entries (&action_show,&status);
 
439
        show_pad_info.line=file_info.dir_entry_num-show_pad_info.display_lines/2;
 
440
        refresh_show_pad ();
 
441
        show_dir_status ();
 
442
}
 
443
 
 
444
int action_show (struct struct_file_info *info)
 
445
 
 
446
/*
 
447
 
 
448
Show the current search entry (info) in one line. If the entry happens to be the current edited entry, it is highlighted.
 
449
 
 
450
*/
 
451
 
 
452
{
 
453
        unsigned char temp [80];
 
454
        struct ext2_dir_entry_2 *dir_entry_ptr;
 
455
        
 
456
        dir_entry_ptr=(struct ext2_dir_entry_2 *) (info->buffer+info->dir_entry_offset);
 
457
 
 
458
        if (info->dir_entry_num == file_info.dir_entry_num)                             /* Highlight the current entry */
 
459
                wattrset (show_pad,A_REVERSE);
 
460
 
 
461
        strncpy (temp,dir_entry_ptr->name,dir_entry_ptr->name_len);                     /* The name is not terminated */
 
462
        temp [dir_entry_ptr->name_len]=0;
 
463
        if (dir_entry_ptr->name_len > (COLS - 55) && COLS > 55)
 
464
                temp [COLS-55]=0;
 
465
        wprintw (show_pad,"inode = %-8lu rec_len = %-4lu name_len = %-3lu name = %s\n", /* Display the various fields */
 
466
                 dir_entry_ptr->inode,dir_entry_ptr->rec_len,dir_entry_ptr->name_len,temp);
 
467
 
 
468
        show_pad_info.max_line++;
 
469
 
 
470
        if (info->dir_entry_num == file_info.dir_entry_num)
 
471
                wattrset (show_pad,A_NORMAL);
 
472
 
 
473
        return (CONTINUE);                                                              /* And pass to the next */
 
474
}
 
475
 
 
476
void type_dir___next (char *command_line)
 
477
 
 
478
/*
 
479
 
 
480
This function moves to the next directory entry. It just uses the current information and the entry command.
 
481
 
 
482
*/
 
483
 
 
484
{
 
485
        int offset=1;
 
486
        char *ptr,buffer [80];
 
487
 
 
488
        ptr=parse_word (command_line,buffer);
 
489
        
 
490
        if (*ptr!=0) {
 
491
                ptr=parse_word (ptr,buffer);
 
492
                offset*=atol (buffer);
 
493
        }
 
494
 
 
495
        sprintf (buffer,"entry %ld",file_info.dir_entry_num+offset);dispatch (buffer);
 
496
 
 
497
}
 
498
 
 
499
void type_dir___prev (char *command_line)
 
500
 
 
501
{
 
502
        int offset=1;
 
503
        char *ptr,buffer [80];
 
504
 
 
505
        ptr=parse_word (command_line,buffer);
 
506
        
 
507
        if (*ptr!=0) {
 
508
                ptr=parse_word (ptr,buffer);
 
509
                offset*=atol (buffer);
 
510
        }
 
511
 
 
512
        sprintf (buffer,"entry %ld",file_info.dir_entry_num-offset);dispatch (buffer);
 
513
}
 
514
 
 
515
void show_dir_status (void)
 
516
 
 
517
/*
 
518
 
 
519
Various statistics about the directory.
 
520
 
 
521
*/
 
522
 
 
523
{
 
524
        long inode_num;
 
525
        
 
526
        wmove (show_win,0,0);
 
527
        wprintw (show_win,"Directory listing. Block %ld. ",file_info.global_block_num);
 
528
        wprintw (show_win,"Directory entry %ld of %ld.\n",file_info.dir_entry_num,file_info.dir_entries_count-1);
 
529
        wprintw (show_win,"Directory Offset %ld of %ld. ",file_info.file_offset,file_info.file_length-1);
 
530
        
 
531
        inode_num=inode_offset_to_inode_num (file_info.inode_offset);
 
532
        wprintw (show_win,"File inode %ld. Indirection level %ld.\n",inode_num,file_info.level);
 
533
 
 
534
        refresh_show_win ();
 
535
}
 
536
 
 
537
void type_dir___remember (char *command_line)
 
538
 
 
539
/*
 
540
 
 
541
This is overrided here because we don't remember a directory - It is too complicated. Instead, we remember the
 
542
inode of the current directory.
 
543
 
 
544
*/
 
545
 
 
546
{
 
547
        int found=0;
 
548
        long entry_num;
 
549
        char *ptr,buffer [80];
 
550
        struct struct_descriptor *descriptor_ptr;
 
551
        
 
552
        ptr=parse_word (command_line,buffer);
 
553
        
 
554
        if (*ptr==0) {
 
555
                wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win);
 
556
                return;         
 
557
        }
 
558
        
 
559
        ptr=parse_word (ptr,buffer);
 
560
 
 
561
        entry_num=remember_lifo.entries_count++;
 
562
        if (entry_num>REMEMBER_COUNT-1) {
 
563
                entry_num=0;
 
564
                remember_lifo.entries_count--;
 
565
        }
 
566
        
 
567
        descriptor_ptr=first_type;
 
568
        while (descriptor_ptr!=NULL && !found) {
 
569
                if (strcmp (descriptor_ptr->name,"ext2_inode")==0)
 
570
                        found=1;
 
571
                else
 
572
                        descriptor_ptr=descriptor_ptr->next;
 
573
        }
 
574
 
 
575
 
 
576
        remember_lifo.offset [entry_num]=device_offset;
 
577
        remember_lifo.type [entry_num]=descriptor_ptr;
 
578
        strcpy (remember_lifo.name [entry_num],buffer);
 
579
        
 
580
        wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer);
 
581
        wrefresh (command_win);
 
582
}
 
583
 
 
584
void type_dir___set (char *command_line)
 
585
 
 
586
/*
 
587
 
 
588
Since the dir object doesn't have variables, we provide the impression that it has here. ext2_dir_entry was not used
 
589
because it is of variable length.
 
590
 
 
591
*/
 
592
 
 
593
{
 
594
        int found=0;
 
595
        unsigned char *ptr,buffer [80],variable [80],value [80],temp [80];
 
596
        struct ext2_dir_entry_2 *dir_entry_ptr;
 
597
        
 
598
        dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset);
 
599
        
 
600
        ptr=parse_word (command_line,buffer);
 
601
        if (*ptr==0) {
 
602
                wprintw (command_win,"Error - Missing arguments\n");refresh_command_win ();
 
603
                return;
 
604
        }
 
605
        parse_word (ptr,buffer);
 
606
        ptr=strchr (buffer,'=');
 
607
        if (ptr==NULL) {
 
608
                wprintw (command_win,"Error - Bad syntax\n");refresh_command_win ();return;
 
609
        }
 
610
        strncpy (variable,buffer,ptr-buffer);variable [ptr-buffer]=0;
 
611
        strcpy (value,++ptr);
 
612
 
 
613
        if (strcasecmp ("inode",variable)==0) {
 
614
                found=1;
 
615
                dir_entry_ptr->inode=atol (value);
 
616
                wprintw (command_win,"Variable %s set to %lu\n",variable,dir_entry_ptr->inode);refresh_command_win ();
 
617
 
 
618
        }
 
619
 
 
620
        if (strcasecmp ("rec_len",variable)==0) {
 
621
                found=1;
 
622
                dir_entry_ptr->rec_len=(unsigned int) atol (value);
 
623
                wprintw (command_win,"Variable %s set to %lu\n",variable,dir_entry_ptr->rec_len);refresh_command_win ();
 
624
 
 
625
        }
 
626
 
 
627
        if (strcasecmp ("name_len",variable)==0) {
 
628
                found=1;
 
629
                dir_entry_ptr->name_len=(unsigned int) atol (value);
 
630
                wprintw (command_win,"Variable %s set to %lu\n",variable,dir_entry_ptr->name_len);refresh_command_win ();
 
631
 
 
632
        }
 
633
 
 
634
        if (strcasecmp ("name",variable)==0) {
 
635
                found=1;
 
636
                if (strlen (value) > dir_entry_ptr->name_len) {
 
637
                        wprintw (command_win,"Error - Length of name greater then name_len\n");
 
638
                        refresh_command_win ();return;
 
639
                }
 
640
                strncpy (dir_entry_ptr->name,value,strlen (value));
 
641
                wprintw (command_win,"Variable %s set to %s\n",variable,value);refresh_command_win ();
 
642
 
 
643
        }
 
644
        
 
645
        if (found) {
 
646
                wattrset (show_pad,A_REVERSE);
 
647
                strncpy (temp,dir_entry_ptr->name,dir_entry_ptr->name_len);
 
648
                temp [dir_entry_ptr->name_len]=0;
 
649
                wmove (show_pad,file_info.dir_entry_num,0);
 
650
                wprintw (show_pad,"inode = %-8lu rec_len = %-4lu name_len = %-3lu name = %s\n",
 
651
                         dir_entry_ptr->inode,dir_entry_ptr->rec_len,dir_entry_ptr->name_len,temp);
 
652
                wattrset (show_pad,A_NORMAL);
 
653
                show_pad_info.line=file_info.dir_entry_num-show_pad_info.display_lines/2;
 
654
                refresh_show_pad ();
 
655
                show_dir_status ();
 
656
        }
 
657
        
 
658
        else {
 
659
                wprintw (command_win,"Error - Variable %s not found\n",variable);
 
660
                refresh_command_win ();
 
661
        }
 
662
 
 
663
}
 
664
 
 
665
void type_dir___writedata (char *command_line)
 
666
 
 
667
/*
 
668
 
 
669
We need to override this since the data is not in type_data. Instead, we have to write the buffer which corresponds
 
670
to the current block.
 
671
 
 
672
*/
 
673
 
 
674
{
 
675
        low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
 
676
        return;
 
677
}