679 lines
20 KiB
C
679 lines
20 KiB
C
/*
|
|
|
|
/usr/src/ext2ed/dir_com.c
|
|
|
|
A part of the extended file system 2 disk editor.
|
|
|
|
--------------------
|
|
Handles directories.
|
|
--------------------
|
|
|
|
This file contains the codes which allows the user to handle directories.
|
|
|
|
Most of the functions use the global variable file_info (along with the special directory fields there) to save
|
|
information and pass it between them.
|
|
|
|
Since a directory is just a big file which is composed of directory entries, you will find that
|
|
the functions here are a superset of those in the file_com.c source.
|
|
|
|
We assume that the user reached here using the dir command of the inode type and not by using settype dir, so
|
|
that init_dir_info is indeed called to gather the required information.
|
|
|
|
type_data is not changed! It still contains the inode of the file - We handle the directory in our own
|
|
variables, so that settype ext2_inode will "go back" to the inode of this directory.
|
|
|
|
First written on: April 28 1995
|
|
|
|
Copyright (C) 1995 Gadi Oxman
|
|
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "ext2ed.h"
|
|
|
|
char name_search [80];
|
|
long entry_num_search;
|
|
|
|
int init_dir_info (struct struct_file_info *info_ptr)
|
|
|
|
/*
|
|
|
|
This function is called by the inode of the directory when the user issues the dir command from the inode.
|
|
It is used to gather information about the inode and to reset some variables which we need in order to handle
|
|
directories.
|
|
|
|
*/
|
|
|
|
{
|
|
struct ext2_inode *ptr;
|
|
|
|
ptr=&type_data.u.t_ext2_inode; /* type_data contains the inode */
|
|
|
|
info_ptr->inode_ptr=ptr;
|
|
info_ptr->inode_offset=device_offset; /* device offset contains the inode's offset */
|
|
|
|
/* Reset the current position to the start */
|
|
|
|
info_ptr->global_block_num=ptr->i_block [0];
|
|
info_ptr->global_block_offset=ptr->i_block [0]*file_system_info.block_size;
|
|
info_ptr->block_num=0;
|
|
info_ptr->file_offset=0;
|
|
/* Set the size of the directory */
|
|
|
|
info_ptr->blocks_count=(ptr->i_size+file_system_info.block_size-1)/file_system_info.block_size;
|
|
info_ptr->file_length=ptr->i_size;
|
|
|
|
info_ptr->level=0; /* We start using direct blocks */
|
|
info_ptr->display=HEX; /* This is not actually used */
|
|
|
|
info_ptr->dir_entry_num=0;info_ptr->dir_entries_count=0; /* We'll start at the first directory entry */
|
|
info_ptr->dir_entry_offset=0;
|
|
|
|
/* Find dir_entries_count */
|
|
|
|
info_ptr->dir_entries_count=count_dir_entries (); /* Set the total number of entries */
|
|
|
|
return (1);
|
|
}
|
|
|
|
struct struct_file_info search_dir_entries (int (*action) (struct struct_file_info *info),int *status)
|
|
|
|
/*
|
|
This is the main function in this source file. Various actions are implemented using this basic function.
|
|
|
|
This routine runs on all directory entries in the current directory.
|
|
For each entry, action is called. We'll act according to the return code of action:
|
|
|
|
ABORT - Current dir entry is returned.
|
|
CONTINUE - Continue searching.
|
|
FOUND - Current dir entry is returned.
|
|
|
|
If the last entry is reached, it is returned, along with an ABORT status.
|
|
|
|
status is updated to the returned code of action.
|
|
*/
|
|
|
|
{
|
|
struct struct_file_info info; /* Temporary variables used to */
|
|
struct ext2_dir_entry_2 *dir_entry_ptr; /* contain the current search entries */
|
|
int return_code, next;
|
|
|
|
info=first_file_info; /* Start from the first entry - Read it */
|
|
low_read (info.buffer,file_system_info.block_size,info.global_block_offset);
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset);
|
|
|
|
while (info.file_offset < info.file_length) { /* While we haven't reached the end */
|
|
|
|
*status=return_code=action (&info); /* Call the client function to test */
|
|
/* the current entry */
|
|
if (return_code==ABORT || return_code==FOUND)
|
|
return (info); /* Stop, if so asked */
|
|
|
|
/* Pass to the next entry */
|
|
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset);
|
|
|
|
info.dir_entry_num++;
|
|
next = dir_entry_ptr->rec_len;
|
|
if (!next)
|
|
next = file_system_info.block_size - info.dir_entry_offset;
|
|
info.dir_entry_offset += next;
|
|
info.file_offset += next;
|
|
|
|
if (info.file_offset >= info.file_length) break;
|
|
|
|
if (info.dir_entry_offset >= file_system_info.block_size) { /* We crossed a block boundary */
|
|
/* Find the next block, */
|
|
info.block_num++;
|
|
info.global_block_num=file_block_to_global_block (info.block_num,&info);
|
|
info.global_block_offset=info.global_block_num*file_system_info.block_size;
|
|
info.file_offset=info.block_num*file_system_info.block_size;
|
|
info.dir_entry_offset=0;
|
|
/* read it and update the pointer */
|
|
|
|
low_read (info.buffer,file_system_info.block_size,info.global_block_offset);
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (info.buffer+info.dir_entry_offset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*status=ABORT;return (info); /* There was no match */
|
|
}
|
|
|
|
long count_dir_entries (void)
|
|
|
|
/*
|
|
|
|
This function counts the number of entries in the directory. We just call search_dir_entries till the end.
|
|
The client function is action_count, which just tell search_dir_entries to continue.
|
|
|
|
*/
|
|
|
|
{
|
|
int status;
|
|
|
|
return (search_dir_entries (&action_count,&status).dir_entry_num);
|
|
}
|
|
|
|
int action_count (struct struct_file_info *info)
|
|
|
|
/*
|
|
|
|
Used by count_dir_entries above - This function is called by search_dir_entries, and it tells it to continue
|
|
searching, until we get to the last entry.
|
|
|
|
*/
|
|
|
|
{
|
|
return (CONTINUE); /* Just continue searching */
|
|
}
|
|
|
|
void type_dir___cd (char *command_line)
|
|
|
|
/*
|
|
Changes to a directory, relative to the current directory.
|
|
|
|
This is a complicated operation, so I would repeat here the explanation from the design and
|
|
implementation document.
|
|
|
|
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
|
|
calling directly type_ext2___cd.
|
|
|
|
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
|
|
1 and into 2/3/4.
|
|
|
|
3. It is the first part of the path that we need to search for in the current directory. We search for it using
|
|
search_dir_entries, which accepts the action_name function as the client function.
|
|
|
|
4. search_dir_entries will scan the entire entries and will call our action_name function for each entry.
|
|
In action_name, the required name will be checked against the name of the current entry, and FOUND will be
|
|
returned when a match occurs.
|
|
|
|
5. If the required entry is found, we dispatch a remember command to insert the current inode (remember that
|
|
type_data is still intact and contains the inode of the current directory) into the object memory.
|
|
This is required to easily support symbolic links - If we find later that the inode pointed by the entry is
|
|
actually a symbolic link, we'll need to return to this point, and the above inode doesn't have (and can't have,
|
|
because of hard links) the information necessary to "move back".
|
|
|
|
6. We then dispatch a followinode command to reach the inode pointed by the required entry. This command will
|
|
automatically change the type to ext2_inode - We are now at an inode, and all the inode commands are available.
|
|
|
|
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",
|
|
and recursively call ourself (The type is dir again) by dispatching a cd command, with the rest of the path
|
|
as an argument.
|
|
|
|
8. If the inode's type is a symbolic link (only fast symbolic link were meanwhile implemented. I guess this is
|
|
typically the case.), we note the path it is pointing at, the saved inode is recalled, we dispatch dir to
|
|
get back to the original directory, and we call ourself again with the link path/rest of the path argument.
|
|
|
|
9. In any other case, we just stop at the resulting inode.
|
|
|
|
*/
|
|
|
|
{
|
|
int status;
|
|
char *ptr,full_dir_name [500],dir_name [500],temp [500],temp2 [500];
|
|
struct struct_file_info info;
|
|
struct ext2_dir_entry_2 *dir_entry_ptr;
|
|
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset);
|
|
|
|
ptr=parse_word (command_line,dir_name);
|
|
|
|
if (*ptr==0) { /* cd alone will enter the highlighted directory */
|
|
strncpy (full_dir_name,dir_entry_ptr->name,dir_entry_ptr->name_len);
|
|
full_dir_name [dir_entry_ptr->name_len]=0;
|
|
}
|
|
else
|
|
ptr=parse_word (ptr,full_dir_name);
|
|
|
|
ptr=strchr (full_dir_name,'/');
|
|
|
|
if (ptr==full_dir_name) { /* Pathname is from root - Let the general cd do the job */
|
|
sprintf (temp,"cd %s",full_dir_name);type_ext2___cd (temp);return;
|
|
}
|
|
|
|
if (ptr==NULL) {
|
|
strcpy (dir_name,full_dir_name);
|
|
full_dir_name [0]=0;
|
|
}
|
|
|
|
else {
|
|
strncpy (dir_name,full_dir_name,ptr-full_dir_name);
|
|
dir_name [ptr-full_dir_name]=0;
|
|
strcpy (full_dir_name,++ptr);
|
|
}
|
|
/* dir_name contains the current entry, while */
|
|
/* full_dir_name contains the rest */
|
|
|
|
strcpy (name_search,dir_name); /* name_search is used to hold the required entry name */
|
|
|
|
if (dir_entry_ptr->name_len != strlen (dir_name) ||
|
|
strncmp (dir_name,dir_entry_ptr->name,dir_entry_ptr->name_len)!=0)
|
|
info=search_dir_entries (&action_name,&status); /* Search for the entry. Answer in info. */
|
|
else {
|
|
status=FOUND;info=file_info;
|
|
}
|
|
|
|
if (status==FOUND) { /* If found */
|
|
file_info=info; /* Switch to it, by setting the global file_info */
|
|
dispatch ("remember internal_variable"); /* Move the inode into the objects memory */
|
|
|
|
dispatch ("followinode"); /* Go to the inode pointed by this directory entry */
|
|
|
|
if (S_ISLNK (type_data.u.t_ext2_inode.i_mode)) {/* Symbolic link ? */
|
|
|
|
if (type_data.u.t_ext2_inode.i_size > 60) { /* I'm lazy, I guess :-) */
|
|
wprintw (command_win,"Error - Sorry, Only fast symbolic link following is currently supported\n");
|
|
refresh_command_win ();
|
|
return;
|
|
}
|
|
/* Get the pointed name and append the previous path */
|
|
|
|
strcpy (temp2,(unsigned char *) &type_data.u.t_ext2_inode.i_block);
|
|
strcat (temp2,"/");
|
|
strcat (temp2,full_dir_name);
|
|
|
|
dispatch ("recall internal_variable"); /* Return to the original inode */
|
|
dispatch ("dir"); /* and to the directory */
|
|
|
|
sprintf (temp,"cd %s",temp2); /* And continue from there by dispatching a cd command */
|
|
dispatch (temp); /* (which can call ourself or the general cd) */
|
|
|
|
return;
|
|
}
|
|
|
|
if (S_ISDIR (type_data.u.t_ext2_inode.i_mode)) { /* Is it an inode of a directory ? */
|
|
|
|
dispatch ("dir"); /* Yes - Pass to the pointed directory */
|
|
|
|
if (full_dir_name [0] != 0) { /* And call ourself with the rest of the pathname */
|
|
sprintf (temp,"cd %s",full_dir_name);
|
|
dispatch (temp);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
else { /* If we can't continue from here, we'll just stop */
|
|
wprintw (command_win,"Can\'t continue - Stopping at last inode\n");refresh_command_win ();
|
|
return;
|
|
}
|
|
}
|
|
|
|
wprintw (command_win,"Error - Directory entry %s not found.\n",dir_name); /* Hmm, an invalid path somewhere */
|
|
refresh_command_win ();
|
|
}
|
|
|
|
int action_name (struct struct_file_info *info)
|
|
|
|
/*
|
|
|
|
Compares the current search entry name (somewhere inside info) with the required name (in name_search).
|
|
Returns FOUND if found, or CONTINUE if not found.
|
|
|
|
*/
|
|
|
|
{
|
|
struct ext2_dir_entry_2 *dir_entry_ptr;
|
|
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (info->buffer+info->dir_entry_offset);
|
|
|
|
if (dir_entry_ptr->name_len != strlen (name_search))
|
|
return (CONTINUE);
|
|
|
|
if (strncmp (dir_entry_ptr->name,name_search,dir_entry_ptr->name_len)==0)
|
|
return (FOUND);
|
|
|
|
return (CONTINUE);
|
|
}
|
|
|
|
void type_dir___entry (char *command_line)
|
|
|
|
/*
|
|
|
|
Selects a directory entry according to its number.
|
|
search_dir_entries is used along with action_entry_num, in the same fashion as the previous usage of search_dir_entries.
|
|
|
|
*/
|
|
|
|
{
|
|
int status;
|
|
struct struct_file_info info;
|
|
char *ptr,buffer [80];
|
|
|
|
ptr=parse_word (command_line,buffer);
|
|
if (*ptr==0) {
|
|
wprintw (command_win,"Error - Argument_not_specified\n");wrefresh (command_win);
|
|
return;
|
|
}
|
|
ptr=parse_word (ptr,buffer);
|
|
entry_num_search=atol (buffer);
|
|
|
|
if (entry_num_search < 0 || entry_num_search >= file_info.dir_entries_count) {
|
|
wprintw (command_win,"Error - Entry number out of range\n");wrefresh (command_win);
|
|
return;
|
|
}
|
|
|
|
info=search_dir_entries (&action_entry_num,&status);
|
|
if (status==FOUND) {
|
|
file_info=info;
|
|
dispatch ("show");
|
|
return;
|
|
}
|
|
#ifdef DEBUG
|
|
internal_error ("dir_com","type_dir___entry","According to our gathered data, we should have found this entry");
|
|
#endif
|
|
}
|
|
|
|
int action_entry_num (struct struct_file_info *info)
|
|
|
|
/*
|
|
|
|
Used by the above function. Just compares the current number (in info) with the required one.
|
|
|
|
*/
|
|
|
|
{
|
|
if (info->dir_entry_num == entry_num_search)
|
|
return (FOUND);
|
|
|
|
return (CONTINUE);
|
|
}
|
|
|
|
void type_dir___followinode (char *command_line)
|
|
|
|
/*
|
|
|
|
Here we pass to the inode pointed by the current entry.
|
|
It involves computing the device offset of the inode and using directly the setoffset and settype commands.
|
|
|
|
*/
|
|
{
|
|
long inode_offset;
|
|
char buffer [80];
|
|
|
|
struct ext2_dir_entry_2 *dir_entry_ptr;
|
|
|
|
low_read (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset);
|
|
|
|
inode_offset=inode_num_to_inode_offset (dir_entry_ptr->inode); /* Compute the inode's offset */
|
|
sprintf (buffer,"setoffset %ld",inode_offset);dispatch (buffer); /* Move to it */
|
|
sprintf (buffer,"settype ext2_inode");dispatch (buffer); /* and set the type to an inode */
|
|
}
|
|
|
|
void type_dir___inode (char *command_line)
|
|
|
|
/*
|
|
|
|
Returns to the parent inode of the current directory.
|
|
This is trivial, as we type_data is still intact and contains the parent inode !
|
|
|
|
*/
|
|
|
|
{
|
|
dispatch ("settype ext2_inode");
|
|
}
|
|
|
|
|
|
void type_dir___show (char *command_line)
|
|
|
|
/*
|
|
|
|
We use search_dir_entries to run on all the entries. Each time, action_show will be called to show one entry.
|
|
|
|
*/
|
|
|
|
{
|
|
int status;
|
|
|
|
wmove (show_pad,0,0);
|
|
show_pad_info.max_line=-1;
|
|
|
|
search_dir_entries (&action_show,&status);
|
|
show_pad_info.line=file_info.dir_entry_num-show_pad_info.display_lines/2;
|
|
refresh_show_pad ();
|
|
show_dir_status ();
|
|
}
|
|
|
|
int action_show (struct struct_file_info *info)
|
|
|
|
/*
|
|
|
|
Show the current search entry (info) in one line. If the entry happens to be the current edited entry, it is highlighted.
|
|
|
|
*/
|
|
|
|
{
|
|
unsigned char temp [80];
|
|
struct ext2_dir_entry_2 *dir_entry_ptr;
|
|
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (info->buffer+info->dir_entry_offset);
|
|
|
|
if (info->dir_entry_num == file_info.dir_entry_num) /* Highlight the current entry */
|
|
wattrset (show_pad,A_REVERSE);
|
|
|
|
strncpy (temp,dir_entry_ptr->name,dir_entry_ptr->name_len); /* The name is not terminated */
|
|
temp [dir_entry_ptr->name_len]=0;
|
|
if (dir_entry_ptr->name_len > (COLS - 55) && COLS > 55)
|
|
temp [COLS-55]=0;
|
|
wprintw (show_pad,"inode = %-8lu rec_len = %-4lu name_len = %-3lu name = %s\n", /* Display the various fields */
|
|
dir_entry_ptr->inode,dir_entry_ptr->rec_len,dir_entry_ptr->name_len,temp);
|
|
|
|
show_pad_info.max_line++;
|
|
|
|
if (info->dir_entry_num == file_info.dir_entry_num)
|
|
wattrset (show_pad,A_NORMAL);
|
|
|
|
return (CONTINUE); /* And pass to the next */
|
|
}
|
|
|
|
void type_dir___next (char *command_line)
|
|
|
|
/*
|
|
|
|
This function moves to the next directory entry. It just uses the current information and the entry command.
|
|
|
|
*/
|
|
|
|
{
|
|
int offset=1;
|
|
char *ptr,buffer [80];
|
|
|
|
ptr=parse_word (command_line,buffer);
|
|
|
|
if (*ptr!=0) {
|
|
ptr=parse_word (ptr,buffer);
|
|
offset*=atol (buffer);
|
|
}
|
|
|
|
sprintf (buffer,"entry %ld",file_info.dir_entry_num+offset);dispatch (buffer);
|
|
|
|
}
|
|
|
|
void type_dir___prev (char *command_line)
|
|
|
|
{
|
|
int offset=1;
|
|
char *ptr,buffer [80];
|
|
|
|
ptr=parse_word (command_line,buffer);
|
|
|
|
if (*ptr!=0) {
|
|
ptr=parse_word (ptr,buffer);
|
|
offset*=atol (buffer);
|
|
}
|
|
|
|
sprintf (buffer,"entry %ld",file_info.dir_entry_num-offset);dispatch (buffer);
|
|
}
|
|
|
|
void show_dir_status (void)
|
|
|
|
/*
|
|
|
|
Various statistics about the directory.
|
|
|
|
*/
|
|
|
|
{
|
|
long inode_num;
|
|
|
|
wmove (show_win,0,0);
|
|
wprintw (show_win,"Directory listing. Block %ld. ",file_info.global_block_num);
|
|
wprintw (show_win,"Directory entry %ld of %ld.\n",file_info.dir_entry_num,file_info.dir_entries_count-1);
|
|
wprintw (show_win,"Directory Offset %ld of %ld. ",file_info.file_offset,file_info.file_length-1);
|
|
|
|
inode_num=inode_offset_to_inode_num (file_info.inode_offset);
|
|
wprintw (show_win,"File inode %ld. Indirection level %ld.\n",inode_num,file_info.level);
|
|
|
|
refresh_show_win ();
|
|
}
|
|
|
|
void type_dir___remember (char *command_line)
|
|
|
|
/*
|
|
|
|
This is overridden here because we don't remember a directory - It is too complicated. Instead, we remember the
|
|
inode of the current directory.
|
|
|
|
*/
|
|
|
|
{
|
|
int found=0;
|
|
long entry_num;
|
|
char *ptr,buffer [80];
|
|
struct struct_descriptor *descriptor_ptr;
|
|
|
|
ptr=parse_word (command_line,buffer);
|
|
|
|
if (*ptr==0) {
|
|
wprintw (command_win,"Error - Argument not specified\n");wrefresh (command_win);
|
|
return;
|
|
}
|
|
|
|
ptr=parse_word (ptr,buffer);
|
|
|
|
entry_num=remember_lifo.entries_count++;
|
|
if (entry_num>REMEMBER_COUNT-1) {
|
|
entry_num=0;
|
|
remember_lifo.entries_count--;
|
|
}
|
|
|
|
descriptor_ptr=first_type;
|
|
while (descriptor_ptr!=NULL && !found) {
|
|
if (strcmp (descriptor_ptr->name,"ext2_inode")==0)
|
|
found=1;
|
|
else
|
|
descriptor_ptr=descriptor_ptr->next;
|
|
}
|
|
|
|
|
|
remember_lifo.offset [entry_num]=device_offset;
|
|
remember_lifo.type [entry_num]=descriptor_ptr;
|
|
strcpy (remember_lifo.name [entry_num],buffer);
|
|
|
|
wprintw (command_win,"Object %s in Offset %ld remembered as %s\n",descriptor_ptr->name,device_offset,buffer);
|
|
wrefresh (command_win);
|
|
}
|
|
|
|
void type_dir___set (char *command_line)
|
|
|
|
/*
|
|
|
|
Since the dir object doesn't have variables, we provide the impression that it has here. ext2_dir_entry was not used
|
|
because it is of variable length.
|
|
|
|
*/
|
|
|
|
{
|
|
int found=0;
|
|
unsigned char *ptr,buffer [80],variable [80],value [80],temp [80];
|
|
struct ext2_dir_entry_2 *dir_entry_ptr;
|
|
|
|
dir_entry_ptr=(struct ext2_dir_entry_2 *) (file_info.buffer+file_info.dir_entry_offset);
|
|
|
|
ptr=parse_word (command_line,buffer);
|
|
if (*ptr==0) {
|
|
wprintw (command_win,"Error - Missing arguments\n");refresh_command_win ();
|
|
return;
|
|
}
|
|
parse_word (ptr,buffer);
|
|
ptr=strchr (buffer,'=');
|
|
if (ptr==NULL) {
|
|
wprintw (command_win,"Error - Bad syntax\n");refresh_command_win ();return;
|
|
}
|
|
strncpy (variable,buffer,ptr-buffer);variable [ptr-buffer]=0;
|
|
strcpy (value,++ptr);
|
|
|
|
if (strcasecmp ("inode",variable)==0) {
|
|
found=1;
|
|
dir_entry_ptr->inode=atol (value);
|
|
wprintw (command_win,"Variable %s set to %lu\n",variable,dir_entry_ptr->inode);refresh_command_win ();
|
|
|
|
}
|
|
|
|
if (strcasecmp ("rec_len",variable)==0) {
|
|
found=1;
|
|
dir_entry_ptr->rec_len=(unsigned int) atol (value);
|
|
wprintw (command_win,"Variable %s set to %lu\n",variable,dir_entry_ptr->rec_len);refresh_command_win ();
|
|
|
|
}
|
|
|
|
if (strcasecmp ("name_len",variable)==0) {
|
|
found=1;
|
|
dir_entry_ptr->name_len=(unsigned int) atol (value);
|
|
wprintw (command_win,"Variable %s set to %lu\n",variable,dir_entry_ptr->name_len);refresh_command_win ();
|
|
|
|
}
|
|
|
|
if (strcasecmp ("name",variable)==0) {
|
|
found=1;
|
|
if (strlen (value) > dir_entry_ptr->name_len) {
|
|
wprintw (command_win,"Error - Length of name greater then name_len\n");
|
|
refresh_command_win ();return;
|
|
}
|
|
strncpy (dir_entry_ptr->name,value,strlen (value));
|
|
wprintw (command_win,"Variable %s set to %s\n",variable,value);refresh_command_win ();
|
|
|
|
}
|
|
|
|
if (found) {
|
|
wattrset (show_pad,A_REVERSE);
|
|
strncpy (temp,dir_entry_ptr->name,dir_entry_ptr->name_len);
|
|
temp [dir_entry_ptr->name_len]=0;
|
|
wmove (show_pad,file_info.dir_entry_num,0);
|
|
wprintw (show_pad,"inode = %-8lu rec_len = %-4lu name_len = %-3lu name = %s\n",
|
|
dir_entry_ptr->inode,dir_entry_ptr->rec_len,dir_entry_ptr->name_len,temp);
|
|
wattrset (show_pad,A_NORMAL);
|
|
show_pad_info.line=file_info.dir_entry_num-show_pad_info.display_lines/2;
|
|
refresh_show_pad ();
|
|
show_dir_status ();
|
|
}
|
|
|
|
else {
|
|
wprintw (command_win,"Error - Variable %s not found\n",variable);
|
|
refresh_command_win ();
|
|
}
|
|
|
|
}
|
|
|
|
void type_dir___writedata (char *command_line)
|
|
|
|
/*
|
|
|
|
We need to override this since the data is not in type_data. Instead, we have to write the buffer which corresponds
|
|
to the current block.
|
|
|
|
*/
|
|
|
|
{
|
|
low_write (file_info.buffer,file_system_info.block_size,file_info.global_block_offset);
|
|
return;
|
|
}
|