Пример #1
0
void type_dir___cd (char *command_line)


{
	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 ();
}
Пример #2
0
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 ();
}