]>
Commit | Line | Data |
---|---|---|
583a1ce5 TT |
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 | ||
598ff014 | 22 | type_data is not changed! It still contains the inode of the file - We handle the directory in our own |
583a1ce5 TT |
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 */ | |
0f31c737 | 101 | struct ext2_dir_entry_2 *dir_entry_ptr; /* contain the current search entries */ |
93599d0c | 102 | int return_code, next; |
583a1ce5 TT |
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); | |
0f31c737 | 106 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); |
583a1ce5 TT |
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 | ||
0f31c737 | 117 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); |
583a1ce5 TT |
118 | |
119 | info.dir_entry_num++; | |
93599d0c TT |
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; | |
583a1ce5 TT |
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); | |
0f31c737 | 138 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset); |
583a1ce5 TT |
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; | |
0f31c737 | 221 | struct ext2_dir_entry_2 *dir_entry_ptr; |
583a1ce5 | 222 | |
0f31c737 | 223 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset); |
583a1ce5 TT |
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 | { | |
0f31c737 | 322 | struct ext2_dir_entry_2 *dir_entry_ptr; |
583a1ce5 | 323 | |
0f31c737 | 324 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (info->buffer+info->dir_entry_offset); |
583a1ce5 TT |
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 | ||
0f31c737 | 400 | struct ext2_dir_entry_2 *dir_entry_ptr; |
583a1ce5 TT |
401 | |
402 | low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset); | |
0f31c737 | 403 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset); |
583a1ce5 TT |
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]; | |
0f31c737 | 454 | struct ext2_dir_entry_2 *dir_entry_ptr; |
583a1ce5 | 455 | |
0f31c737 | 456 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (info->buffer+info->dir_entry_offset); |
583a1ce5 TT |
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]; | |
0f31c737 | 596 | struct ext2_dir_entry_2 *dir_entry_ptr; |
583a1ce5 | 597 | |
0f31c737 | 598 | dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset); |
583a1ce5 TT |
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 | } |