/*

/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 <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 overrided 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;
}
