Project design and structure.

We used Unix C for writing this project, compiled by cc on Linux platform with its string parsing and internet connection libraries. The design was hierarchical, attempting to make the new functions as small as possible, but still keeping every message passing significant. The structure of the program is following:

As you can see, bash reads from the prompt the command it receives. Then if it is a command that can use a remote file - cp, mv, rm, vi - it attempts to access the remote file through FTP connection with remote host it establishes. Then the requested files are being fetched or put. If the command was editor, the fetched file (copied into a location under /tmp/trftp/$user/) is loaded into the editor. Then, after the editing is finished, we attempt to remotely save the file, and if we fail - we offer to user to save it locally. The move, after first fetch/put, makes the second step - deleting of source file, locally or remotely (through the same connection). In all those cases, after remote action are done a QUIT command is being sent to FTP server to terminate the connection.

Other important issue is the tab completion of remote file names. It only works for an anonymous ftp access, yet it serves as a great search tool. The reason we are not using the completion for any user is that a regular user must issue a password for the FTP server and it breaks the mechanism of the completion and requires a rather tricky implementation.

We have also implemented an engine for error handling, based on FTP server protocol codes as in RFC959.

The project is in fact very divided into two parts - the modifying of BASH bashline.c, exec_cmd.c and other its files for handling remote file names and their tab completion, and on the other hand all the connection/fetching/putting/deleting mechanism.

The way things work

So, we're at bash prompt and we want to access a remote file. What do we do?

We give the remote filename as an argument in a form of
/remote-user%remote-host:pathname/filename
like it goes in the ange-ftp Emacs library. The different % is used instead of @ is because bash has its own completion for hostnames that uses @ and so we have a messy contradiction when attempting to complete a filename that contains a @.

Then, BASH knows to detect different fields of the given argument and pass them to connection and transfer routines, which work in a following way:
First, the ~/.netrc file is being scanned for a corresponding record and if found, the password is being substituted from this file.
Second, an attempt to establish a host connection and afterwards, if successful, to log into the remote FTP server comes up.
Then, if we're still successful, we issue the required data transfer command. If it is move or copy, we receive a fork() into two subprocesses, one of them receives data from the data socket established with server, other one controls it through control connection socket.More about it in the Network Interaction chapter.
We also add the feature of caching of last user password, so that when a user attempts to access a remote host under same remote user name, the cached password is being used instead of prompting for it the user.
Then, upon successful completion of the task we return to BASH prompt. If we had a failure at a step, one of the function fires back a faulty return code and we see what caused the mistake, or what it was and again return to BASH prompt.

Important functions and data structures

FTP connection:

Functions

netrc_proceed()

expect()

sendcmd()

initcomm()

ReceiveFile(), PutFile(), ListFile(), DeleteFile()

Data Structures

lastpass

fnlist

BASH

I. Execute and parse part. tftp_parse() in execute_cmd.c

II. Completion part. tftp_command_completion() in bashline.c