.alone←declaration(expurgate)=0;
.if alone then start
.require "<altosource>ttydefs.pub" source!file
.end
.every heading (|Alto Pup FTP|,|December 12, 1981|,{page})
.once center
Alto Pup File Transfer Program
.skip 3
~FTP~ is a Pup-based File Transfer Program for moving files to and from an Alto file system.  The program comes in 3 parts:

.begin indent 4,4,4
1)  An FTP Server, which listens for file transfer requests from other hosts,

2)  An FTP User, which initiates file transfers under control of either the keyboard or the command line, and

3)  A User Telnet for logging into a remote host using the Pup Telnet protocol.
.end

.sec |Concepts and Terminology|

Tranferring a file from one machine (or "host") to another over a network requires the active cooperation of programs on both machines.  In a typical scenario for file transfer, a human user (or a program acting on his behalf) invokes a program called an "FTP User" and directs it to establish contact with an "FTP Server" program on another machine.  Once contact has been established, the FTP User initiates requests and supplies parameters for the actual transfer of files, which the User and Server proceed to carry out cooperatively.  The FTP User and FTP Server roles differ in that the FTP User interacts with the human user (usually through some sort of keyboard interpreter) and takes the initiative in user/server interactions, whereas the FTP Server plays a comparatively passive role.

The question of which machine is the FTP User and which is the FTP Server is completely independent of the direction of file transfer.  The two basic file transfer operations are called "Retrieve" and "Store";  the Retrieve operation causes a file to move from Server to User, whereas Store causes a file to move from User to Server.

The Alto FTP subsystem contains both an FTP User and an FTP Server, running as independent processes.  Therefore, to transfer files between a pair of Altos, one should start up the FTP subsystem on both machines, then issue commands to the FTP User process on one machine directing it to establish contact with the FTP Server process in the other machine.  Subsequent file transfers are controlled entirely from the FTP User end, with no human intervention required at the Server machine.

Transferring files to or from a Maxc system or an IFS involves establishing contact with FTP Server processes that run all the time on those machines.  Hence, one may simply invoke the Alto FTP subsystem and direct its FTP User process to connect to the machine.

In the descriptions that follow, the terms "local" and "remote" are relative to the machine on which the FTP User program is active.  That is, we speak of typing commands to our "local" FTP User program and directing it to establish contact with an FTP Server on some "remote" machine.  A Retrieve command then copies a file from the "remote" file system to the "local" file system, whereas a Store command copies a file from the "local" file system to the "remote" file system.

Furthermore, we refer to "local" and "remote" filenames.  These must conform to the conventions used by the "local" and "remote" host computers, which may be dissimilar (for example, Alto versus Maxc).  The Alto FTP knows nothing about Maxc filename conventions or vice versa.

The Alto FTP subsystem also includes a third process, called a "User Telnet", which simulates a terminal in a manner exactly analogous to the Chat subsystem (though lacking some of its finer features).  By this means, you may log in to a file sytem machine to perform operations not directly available via the basic file transfer mechanisms.  If you log into Maxc, it is even possible to run "PupFTP", the Maxc FTP User program, and direct it to establish contact with the FTP Server in your own Alto.  You should probably not try this unless you really understand what you are doing, however, since the terms "local" and "remote" are relative to Maxc rather than to your Alto (since the FTP User program is running on Maxc in this case), which can be confusing.

.sec |Calling the FTP Subsystem|

A number of options are available when running FTP.  The program decides which parts of itself to enable and where user commands will come from by inspecting the command line.  The general form of the command line to invoke FTP looks like:

.begin center

FTP[/<Global-switches>] [<Host-name> [<Command-list>] ]

.end
The square brackets denote portions of the command line that are optional and may be omitted.

Global switches, explained below, select some global program options such as using the Trident disk instead of the Diablo.  The first token after the <global-switches>, if present, is assumed to be a <host-name> (a discussion of which appears later in the description of the "Open" command).  The User FTP will attempt to connect to the FTP Server on that host.  After connecting to the server, if a <command-list> is present, an interpreter is started which feeds these commands to the User FTP.  When the command list is exhausted, FTP returns to the Alto Executive.  If no command list is present, an interactive keyboard command interpreter is started.

Each global switch has a default value which is used if the switch is not explicitly set.  To set a switch to 'false' proceed it with a 'minus' sign (thus FTP/-S means 'no Server'), to set a switch to 'true' just mention the switch.

.begin indent 0,19 tabs 10,20
Switch\Default\Function

/S\true\[Server] starts the FTP Server.  The Server is not started if the User is enabled and is being controlled from the command line.

/U\true\[User] starts the FTP User.  As explained above, the interactive command interpreter or the command line interpreter will be started depending on the contents of the command line.

/C\true\[Chat] starts the Telnet.  The Telnet is not started if the User is enabled and is being controlled from the command line, or if the system disk is a Trident.

/T\false\[Trident] sets the system disk to be a Trident drive.  The default is 0, but can be changed by following the /T with a unit number.  The unit number is octal; the high byte is the logical filesystem number and the low byte is the physical drive number.  User and Server commands apply to files on this disk but command line input and log output use the Diablo drive.

/L\*\[Log] causes all output to the User FTP window to also go to the file "FTP.log" on DP0, overwriting the previous contents.  Log is true if the User is enabled and is being controlled from the command line.

/A\false\[AppendLog] enables the log but appends to FTP.log rather than overwriting it.

/E\true\[Error] causes FTP to ask you if you want to continue when a non-fatal error happens during execution of a command line.  FTP/-E will cause FTP to recover automatically from non fatal errors without consulting you.

/R\true\[Ram] allows FTP to use some microcode which speeds things up slightly.  If your Alto has no ram, this switch is ignored.

/D\false\[Debug] starts FTP in debug mode.
.end

The rest of the global switches are explained below under 'Server Options'.

.ssec |FTP User Log|

FTP can keep a log (typescript) file for the FTP User window.  The file name is 'FTP.log'.  It is always enabled when FTP is being controlled from the command line; otherwise it is controlled by the /L and /A global switches.

.ssec |Using a Trident Disk|

Starting FTP with the /T global switch causes FTP to store and retreive files from a Trident disk.  By default, FTP will open TP0; other disks may be opened by appending their unit numbers to the /T switch.  Thus "FTP/T1" will open TP1, and "FTP/T400" will open logical filesystem 1 on physical unit 0.

Accessing a file on a Trident requires more code and more free storage than accessing a file on the Diablo.  Since FTP is very short on space, only a User or a Server FTP is started when the /T switch is set.  The default is to start a User FTP, but specifying no user (FTP/T-U) or specifying a server (FTP/TS) will start a Server FTP instead.

.ssec |Server Options|

Server options are controlled by switches on the subsystem name and subcommands of the SERVER keyboard command.  There are currently four options:

.begin indent 0,19 tabs 10,20
switch\Default\Function

none\\If no server option is specified, retrieve requests (disk to net) are allowed.  Store requests (net to disk) are allowed unless the store would overwrite an existing file.  Delete and Rename are not permitted.

/P\false\[Protected]  Retrieve requests are allowed.  No stores are allowed.  Delete and Rename are not permitted.

/O\false\[Overwrite]  Retrieve requests are allowed.  Store requests can overwrite files.  Delete and rename are permitted.

/K\false\[Kill]  FTP will return to the Alto Exec when the server connection is closed.  A simple form of remote job entry can be performed by storing into Rem.cm.
.end

.sec |The FTP Display|

The top inch or so of the display contains a title line that displays the release date of that version of FTP, the current date and time, the machine's internetwork address, and the number of free pages on the disk.  A window is created below the title line for each part of FTP which is enabled during a session (server, user, and telnet).

If the FTP Server is enabled, it opens a window and identifies itself.  If a User FTP subsequently connects to this Server, the User's network address will be displayed.  The Server will log the commands it carries out on behalf of the remote User in this window.  The Server is not enabled when FTP is being controlled from the command line.

The FTP User opens the next window down and identifies itself.  The command herald is an asterisk.

The User Telnet opens the bottommost window, identifies itself, and waits for a host name to be entered.  The Telnet is not enabled when FTP is being controlled from the command line.

.sec |Keyboard Command Syntax|

FTP's interactive command interpreter presents a user interface very similar to that of the Alto Executive.  Its command structure is also very similar to that of the Maxc Pup FTP program (PupFTP), and the Maxc ArpaNet FTP program (FTP).  The standard editing characters, command recognition features, and help facility (via "?") are available.  When FTP is waiting for keyboard input, a blinking cursor appears at the next character position.

.ssec |Directing Keyboard input to the User and Telnet Windows|

The bottom two unmarked keys control which window gets characters from the keyboard.  Hitting the unmarked key to the right of 'right-shift' (also known as the 'Swat key') directs keyboard input to the Telnet window.  Hitting the unmarked key to the right of the 'return' key (also known as the 'Chat key') directs keyboard input to the FTP User window.  The window which currently owns the keyboard will blink a cursor at the next character position if it is waiting for type-in.

.ssec |Keyboard Commands|

.begin indent 5,5
.once indent 0
OPEN <host name>
.continue
Opens a connection to the FTP Server in the specified host.  FTP permits only one user connection at a time.  In most cases the word OPEN may be omitted:  i.e., a well formed <host name> is a legal command and implies a request to OPEN a connection.  FTP will try for one minute to connect to the specified host.  If you made a mistake typing the host name and wish to abort the connection attempt, hit the middle unmarked key (to the right of <return>).

Ordinarily, host name should be the name of the machine you wish to connect to (e.g., "Maxc").  Most Altos have names which are registered in Name Lookup Servers.  So long as a name lookup server is available, FTP is able to obtain the information necessary to translate a known host name to an inter-network address.

If the host name of the server machine is not known or if no name lookup servers are available, you may specify an inter-network address in place of the host name.  The general form of an inter-network address is:

.begin center

<network> # <host> # <socket>

.end
where each of the three fields is an octal number.  The <network> number designates the network to which the Server host is connected (which may be different from the one to which the User host is connected);  this (along with the "#" that follows it) may be omitted if the Server and User are known to be connected to the same network.  The <host> number designates the Server host's address on that network.  The <socket> number designates the actual Server process on that host; ordinarily it should be omitted, since the default is the regular FTP server socket.  Hence, to connect to the FTP server running in Alto host number 123 on the directly-connected Ethernet, you should say "OPEN 123#" (the trailing "#" is required).

.once indent 0
CLOSE
.continue
Closes the currently open User FTP connection.  CLOSE cancels any defaults set by CONNECT, DIRECTORY, DEVICE, BYTE, TYPE, or EOLC commands.

.once indent 0
~LOGIN~ <user name> <password>
.continue
Supplies any login parameters required by the remote server before it will permit file transfers.  FTP will use the user name and password in the Operating System, if they are there.  Logging into FTP will set the user name and password in the OS (in the same manner as the Alto Executive's "Login" command).

When you issue the "Login" command, FTP will first display the existing user name known to the OS.  If you now type a space, FTP will prompt you for a password, whereas if you want to provide a different user name, you should first type that name (which will replace the previous one) followed by a space.  The command may be terminated by carriage return after entering the user name to omit entering the password.

The parameters are not immediately checked for legality, but rather are sent to the server for checking when the next file transfer command is issued.  If a command is refused by the server because the name or password is incorrect, FTP will prompt you as if you had issued the LOGIN command and then retry the transfer request.  Hitting delete in this context will abort the command.

A user name and password must be supplied when transferring files to and from a Maxc system or an IFS.  The Alto FTP Server requires a user-password to be supplied if the server machine's disk is password-protected and if the password in the server machine's OS does not match the password on the disk.  Thus if the OS was booted and FTP invoked because a Request-for-Connection was received (which bypasses password checking), FTP will refuse access to files unless a password is supplied.  However if the OS was booted normally, FTP assumes that the disk owner (who knew the password) will control access by using the server option switches.  The user-name is ignored.

.once indent 0
CONNECT <directory name> <password>
.continue
Requests the FTP server to "connect" you to the specified directory on the remote system, i.e., to give you owner-like access to it.  The password may be omitted by typing carriage return after the directory name.  As with LOGIN, these parameters are not verified until the next transfer command is issued.  CONNECT cancels the effect of any previous DIRECTORY command.  At present, the "Connect" command is meaningful only when transferring files to or from a Maxc system or an IFS; the Alto FTP server currently ignores connect requests.  If the "multiple directory" feature of the Alto Operating System ever comes into widespread use, this may be changed.

.once indent 0
COMPARE <remote filename>
.continue
Compares the contents of <remote filename> with a file in the local file system.  It tells you how long the files are if they are identical or the byte position of the first mismatch if they are not.  FTP will suggest a local filename based on the name body of <remote filename>.  If you like this name, type Carriage Return; if you wish to abort the compare command type Delete.  If you would like to compare against a local file by a different name, type the new name.  The old one will disappear, and you then have the same three choices as before.

.once indent 0
DIRECTORY <directory name>
.continue
Causes <directory name> to be used as the default remote directory in data transfer commands (essentially it causes <directory-name> to be attached to all remote filenames that do not explicitly mention a directory).  Specifying a default directory in no way modifies your access privileges, whereas CONNECTing gives you 'owner access' (and usually requires a password).  Explicitly mentioning a directory in a file name overrides the default directory, which overrides the connected directory, which overrides the login directory.  Punctuation separating <directory name> from other parts of a remote filename should not be included.  For example you might type "Directory Alto" not "Directory <Alto>".

.once indent 0
RETRIEVE <remote filename>
.continue
Initiates transfer of the specified remote file to the local host.  The syntax of <remote filename> must conform to the remote host's file system name conventions.  Before transferring a file, FTP will suggest a local-filename (generally the same as the remote-filename without directory or version), and will tell you whether or not the file already exists on your local disk.  At this point you may make one of three choices:

.begin indent 5,9 tabs 10
1.\Type Carriage Return to cause the data to be transferred to the local filename.

2.\Type Delete to indicate that the file is not to be transferred.

3.\Type any desired local filename followed by Return.  The previous local filename will disappear, the new filename will replace it, and FTP will tell you whether a file exists with that name.  This filename must conform to local conventions.  You now have the same three choices. 
.end

If the remote-filename designates multiple files (the remote host permits "*" or some equivalent in file names), each file will be transferred separately and FTP will ask you to make one of the above three choies for each file.  At present, only Maxc and IFS support this capability.  That is, you may supply "*"s in the remote-filename when retrieving files from a Maxc or an IFS, but not when retrieving files from another Alto.

.once indent 0
STORE <local filename>
.continue
Initiates transfer of the specified local file to the remote host.  Alto file name conventions apply to the <local filename>; "*" expansion is not supported.  FTP will suggest a remote-filename to which you should respond in a manner similar to that described under RETRIEVE except that if you supply a different filename, it must conform to the remote file system's conventions.  The default remote filename is one with the same name and extension as the local file; the remote server defaults other fields as necessary.  If the remote host is a Maxc system or an IFS, then the directory is that most recently supplied in LOGIN or CONNECT or DIRECTORY commands and the version is the next higher.

.once indent 0
DUMP <remote filename>
.continue
Bundles together a group of files from the local file system into a 'dump-format' file (see the Alto Executive documentation for the dump-file format and more on dump-files in general) and stores the result as <remote filename>.  FTP will ask you for the names of local files to include in the dump-file.  Terminate the dump by typing just <return> when FTP asks for another filename.  By convention, files in dump-format have extension '.dm'.

.once indent 0
LOAD <remote filename>
.continue
Performs the inverse operation of DUMP, unbundling a dump-format file from the remote file system and storing the constituent files in the local file system.  For each file in the dump-file, FTP will suggest a local file name and tell you whether a file by that name exists on your disk.  You should respond in the manner described under RETRIEVE.

.once indent 0
LIST <remote file designator>
.continue
Lists all files in the remote file system which correspond to <remote file designator>.  The remote file designator must conform to file naming conventions on the remote host, and may designate multiple files if "*" expansion or some equivalent is supported there.  If the <remote file designator> is terminated by <comma return> rather than just a <return>, FTP prints a prompt of "**" at the left margin and prepares to accept one or more subcommands.  These subcommands request printout of additional information about each file.  To terminate subcommand input, type a <return> in response to the subcommand prompt.  The subcommands are:

.begin group nofill tabs 25

Type\Print file type and byte size.
Length\Print length of file in bytes.
Creation\Print date of creation.
Write\Print date of last write.
Read\Print date of last read.
Times\Print times as well as dates.
Author\Print author (creator) of file.
Verbose\Same as Type+Write+Read+Author.
Everything\Print all information about the file.
.end

This information is only as reliable as the Server that provided it, and not all Servers provide all of these file properties.  Altos derive much of this information from hints, so do not be alarmed if it is sometimes wrong.

.once indent 0
DELETE <remote filename>
.continue
Deletes <remote filename> from the remote filesystem.  The syntax of the remote filename must conform to the remote host's file system name conventions.  After determining that the remote file exists, FTP asks you to confirm your intention to delete it.  If the remote filename designates multiple files (the remote host permits "*" or some equivalent in file names), FTP asks you to confirm the deletion of each file.  

.once indent 0
RENAME <old filename> <new filename>
.continue
Renames <old filename> in the remote filesystem to be <new filename>.  The syntax of the two filenames must conform to the remote host's file system name conventions, and each filename must specify exactly one file.

.once indent 0
QUIT
.continue
Returns control to the Alto Executive, closing all open connections.

.once indent 0
TYPE <data type>
.continue
Forces the data to be interpreted according to the specified <data type>, which may be TEXT or BINARY.  Initially the type is UNSPECIFIED, meaning that the source process should, if possible, decide on the appropriate type based on local information.

.once indent 0
BYTE-SIZE <decimal number>
.continue
Applicable only to files of type Binary, BYTE-SIZE specifies the logical byte size of the data to be transferred.  The default is 8.

.once indent 0
EOL <convention>
.continue
Applicable only to files of type Text, EOL specifies the End-of-Line Convention to be used for transferring text files.  The values for <convention> are CR, CRLF, and TRANSPARENT.  The default is CR.

.once indent 0
DEVICE <string>
.continue
Causes <string> to be used as the default device in data transfer commands (essentially it causes <device> to be attached to all remote filenames that do not explicitly mention one).  The punctuation separating <device> from the other components of a remote filename should not be included.  For example you might specify "Device DSK" to Tenex, not "Device DSK:"

.once indent 0
VERSION <string>
.continue
Causes <string> to be used as the default version in data transfer commands (essentially it causes the version string to be attached to all remote filenames that do not explicitly mention one).  The punctuation separating the version information from other components of a remote filename should not be included.  For example you might specify "Version 123", to IFS, not "Version !123"

.once indent 0
USER
.continue
Allows you to toggle switches which control operation of the FTP User.  There is currently only one: DEBUG, which controls display of protocol interactions.  Warning: this printout (and the corresponding one in the SERVER command below) sometimes includes passwords.

.once indent 0
SERVER
.continue
Allows you to toggle switches which control operation of the FTP Server.  The switches are PROTECTED, OVERWRITE, KILL, and DEBUG, corresponding to the global switches /P, /O, /K, and /D.

.once indent 0
TELNET
.continue
Allows you to toggle switches which control operation of the Telnet.  There is currently only one: CLOSE, which closes the Telnet connection if one is open.
.end

.sec |Command Line Syntax|

The User FTP can also be controlled from the command line.  As explained above, the first token after the subsystem name and server switches must be a legal host name; if the User FTP can't connect to the FTP Server on that host it will abort and return control to the Alto Executive.  If a command list follows the host name, the command line interpreter is invoked instead of the interactive keyboard interpreter.  This permits the full capabilities of the Alto Executive (filename recognition, "*" expansion, command files, etc.) to be used in constructing commands for FTP.

Each command is of the form:

.begin center

<Keyword>/<SwitchList> <arg> ... <arg>
.end

To get a special character (any one of "*#';") past the Alto Executive, it must be preceded by a single quote.  To get a "/" into an FTP argument, the "/" must be proceeded by two single quotes (the second one tells FTP to treat the "/" as an ordinary character in the argument, and the first one gets the second one past the Alto Executive).

Unambiguous abbreviations of command keywords (which in most cases amount to the first letter) are legal.  However, when constructing command files, you should always spell commands in full, since the uniqueness of abbreviations in the present version of FTP is not guaranteed in future versions.

A command is distinguished from arguments to the previous command by having a switch on it, so every command must have at least one switch.  The switch "/C" has no special meaning and should be used on commands where no other switches are needed or desired.

.ssec |Command Line Errors|

Command line errors fall into three groups: syntax errors, file errors, and connection errors.  FTP can recover from some of these, though it leaves the decision about whether to try up to you.

Syntax errors such as unrecognized commands or the wrong number of arguments to a command cause FTP's command interpreter to get out of sync with the command file.  FTP can recover from syntax errors by simply ignoring text until it encounters another command (i.e. another token with a switch).

File errors such as trying to retrieve a file which does not exist are relatively harmless.  FTP recovers from file errors by skipping the offending file.

Connection errors such as executing a store command when there is no open connection could cause FTP to crash.  FTP can't recover from connection errors.

When FTP detects an error, it displays an error message in the User window.  If the error is fatal, FTP waits for you to type any character and then aborts, causing the Alto Executive to flush the rest of the command line, including any commands to invoke other subsytems after FTP.  If FTP can recover from the error, it asks you to confirm whether you wish to continue.  If you confirm, it plunges on, otherwise it aborts.  The confirmation request can be bypassed by invoking FTP with the global error switch false (FTP/-E ...) in which case it will plunge on after all non fatal errors.  If you aren't around when an error happens and you have told FTP to get confirmation before continuing after an error, the remote Server will probably time out and close the connection.  If you then return and tell FTP to continue, it will get a fatal connection error and abort.

.ssec |Command Line Switches|

Most commands take local switches.  These switches have default values which are used if the switch is not mentioned.  Proceeding a switch with a minus sign inverts its sense: Retrieve/-O means retrieve but don't overwrite.  While the interpretation of a switch sometimes depends on the command, the general idea is:

.begin indent 0,19 tabs 10,20
Switch\Default\Function

/C\--\[Command] null switch which tells the command line parser that this token is a command.

/S\false\[Selective] the remote and local file names differ.  The LOAD command uses this switch slightly differently.

/D\update\[Dates] show file creation dates.

/V\false\[Verify] request confirmation from the keyboard.

/O\true\[Overwrite] allow overwriting existing files.

.end

Transfers may be conditioned upon comparison of the creation dates of corresponding local and remote files.  The comparison is <source file> <operator> <destination file>.  For STORE, the source file is the local file; for RETRIEVE, the source file is the remote file.  The operators are:

.begin indent 0,9 tabs 10
Switch\Function

/#\[NotEqual] transfer the file if the creation dates are not equal. This must be quoted (/'#) to keep it out of the clutches of the Alto Exec.

/=\[Equal] transfer the file if the creation dates are equal.

/>\[Greater] transfer the file if the source's creation date is greater than the destination's.

/<\[Less] transfer the file if the source's creation date is less than the destination's.

/U\[Update] same as /> (for backward compatibility).

/A\[All] transfer the file even if no corresponding file exists in the other file system.

.end

If more than one switch is present, they are ORed together, so, for example, "/>=" means transfer the file if the source's creation date is greater than or equal to the destination's.

The sense of a switch is inverted if it is preceeded by a minus sign.  Thus:

.begin verbatim
	/-= is equivalent to /#,
	/-# is equivalent to /=,
	/-< is equivalent to />=, and
	/-> is equivalent to /<=.
.end
Note that a minus sign inverts the sense of the immediately following character, not the entire operator expression.

.ssec |Command Line Commands|

.begin indent 5,5
.once indent 0
OPEN/C <host name>
.continue
See description in "Keyboard commands".  The first token after the subsystem name and global switches is assumed to be a host name and no OPEN verb is required (in fact if you supply it, FTP will try to make a connection the host named OPEN which is almost certainly not what you want).

.once indent 0
CLOSE/C
.continue
Closes the currently open User FTP connection.

.once indent 0
LOGIN/C <user name> <password>
.continue
See description in "Keyboard commands".  The <password> may be omitted.

.once indent 0
LOGIN/Q <user name>
.continue
Causes FTP to prompt you for the password.  This form of LOGIN should be used in command files since including passwords in command files is a bad practice.

.once indent 0
CONNECT/C <directory name> <password>
.continue
See description in "Keyboard commands".  The <password> may be omitted.

.once indent 0
CONNECT/Q <directory name>
.continue
Causes FTP to prompt you for the password needed to connect to the specified <directory name>.  This form of CONNECT should be used in command files since including passwords in command files is a bad practice.

.once indent 0
DIRECTORY/C <default directory>
.continue
See discription in "Keyboard commands".

.once indent 0
RETRIEVE/C <remote filename> ... <remote filename>
.continue
Retrieves each <remote filename>, constructing a local file name from the actual remote file name as received from the Server.  FTP will overwrite an existing file unless the /N (No overwrite) switch is appended to the RETRIEVE command keyword.

If the remote host allows "*" (or some equivalent) in a filename, a single remote filename may result in the retrieval of several files.  (Note that you must quote the "*" to get it past the Alto Executive's command scanner.)  As mentioned previously, this capability is implemented only by Maxc and IFS FTP Servers at present.

.once indent 0
RETRIEVE/S <remote filename> <local filename>
.continue
Retrieves <remote filename> and names it <local filename> in the local file system.  This version of RETRIEVE must have exactly two arguments.  FTP will overwrite an existing file unless the /-O (No Overwrite) switch is also appended to the RETRIEVE command keyword.  The remote filename should not cause the server to send multiple files.

.once indent 0
RETRIEVE/> <remote filename> ... <remote filename>
.continue
Retrieves <remote filename> if its creation date is greater than that of the local file.  If the corresponding local file doesn't exist, the remote file is not retrieved.  This option can be combined with RETRIEVE/S to rename the file as it is transferred.

.once indent 0
RETRIEVE/>A <remote filename> ... <remote filename>
.continue
Same as RETRIEVE/> except if the corresponding local file doesn't exist, the remote file is retrieved anyway.

.once indent 0
RETRIEVE/V 
.continue
Requests confirmation from the keyboard before writing a local file.  This option is useful in combination with the Update option since creation date is not a fool-proof criterion for updating a file.

.once indent 0
RETRIEVE/-O
Retrieves a file only if the corresponding local file doesn't exist.

.once indent 0
STORE/C <local filename> ... <local filename>
.continue
Stores each <local filename> on the remote host, constructing a remote filename from the name body of the local filename.  A local filename may contain "*", since it will be expanded by the Alto Executive into the actual list of filenames before the FTP subsystem is invoked.

.once indent 0
STORE/S <local filename> <remote filename>
.continue
Stores <local filename> on the remote host as <remote filename>.  The remote filename must conform to the file name conventions of the remote host.  This version of store must have exactly two arguments.

.once indent 0
STORE/> <local filename> ... <local filename>
.continue
Stores each <local filename> on the remote host if the local file's creation date is greater than the remote file's.  If the corresponding remote file doesn't exist, the local file is not stored.  This option can be combined with STORE/S to rename the file as it is transferred.

.once indent 0
STORE/>A <local filename> ... <local filename>
.continue
Same as STORE/> except if the corresponding remote file doesn't exist, the local file is stored anyway.

.once indent 0
STORE/V
.continue
Requests confirmation from the keyboard before writing a remote file.  This option is useful in combination with the Update option since creation date is not a fool-proof criterion for updating a file.

.once indent 0
DUMP/C <remote filename> <local filename>...<local filename>
.continue
See the description in "keyboard Commands".

.once indent 0
LOAD/C <remote filename> ... <remote filename>
.continue
See the description in "keyboard Commands".  If the /V switch is appended to the LOAD command keyword, FTP will request confimation before writing each file.  Type <return> to write the file, <del> to skip it.  FTP will overwrite an existing file unless the /N (No overwrite) switch is appended to the LOAD command keyword.

.once indent 0
LOAD/> <remote filename> ... <remote filename>
.continue
Loads files from <remote filename> if their creation dates are greater than the corresponding creation dates of local files.  If the corresponding local file doesn't exist, the remote file is not loaded.

.once indent 0
LOAD/>A <remote filename> ... <remote filename>
.continue
Same as LOAD/> except if the corresponding local file doesn't exist, the remote file is loaded anyway

.once indent 0
LOAD/S <remote filename> <filename 1> ... <filename n>
.continue
Loads files from <remote filename> if their names are in the list <filename 1> ... <filename n>.  Files within the dump file that are not in the list are skipped.  This option can be combined with the /U, /V, and /N options.

.once indent 0
LIST/C <remote filename> ... <remote filename>
.continue
See the description in "Keyboard Commands".  The subcommands are specified by local switches:

.begin group nofill tabs 15

/T\Type,
/L\Length in bytes,
/D\Creation date (see below),
/W\Write date,
/R\Read date,
/A\Author (creator),
/V\Verbose = /TWRA, and
/E\Everything = /TLDWRA.
.end

Dates always include times.  /C should have been the creation date but that collides with the use of /C to mean no local options (sigh).

.once indent 0
DELETE/C <remote filename>
.continue
See the description in "Keyboard Commands".  If the /V switch is appended to the DELETE command keyword, FTP will request confirmation before deleting each file.  Type <return> to delete the file, and <del> (oops!) if you don't want to delete it.

.once indent 0
COMPARE/C <remote filename>...<remote filename>
.continue
Compares the contents of <remote filename> with the file by the same name in the local file system.  It tells you how long the files are if they are identical or the byte position of the first mismatch if they are not.

.once indent 0
COMPARE/S <remote filename> <local filename>
.continue
Compares <remote filename> with <local filename>.  The remote filename must conform to the file name conventions of the remote host.  This version of COMPARE must have exactly two arguments.

.once indent 0
COMMENT/S <arbitrary text>
.continue
The <arbitrary text> is ignored until a token with an imbedded "/" is encountered.  This token is taken as the next command.  The quote character is a single quote.  Thus "foo'/bar" does not terminate a comment.

.once indent 0
RENAME/C <old filename> <new filename>
.continue
See the description in "Keyboard Commands".

.once indent 0
TYPE/C <data type>
.continue
See the description in "Keyboard Commands".

.once indent 0
BYTE-SIZE/C <decimal number>
.continue
See the description in "Keyboard Commands".

.once indent 0
EOL/C <convention>
.continue
See the description in "Keyboard Commands".

.once indent 0
DEVICE/C <string>
.continue
See the description in "Keyboard Commands".

.once indent 0
VERSION/C <string>
.continue
See the description in "Keyboard Commands".

.once indent 0
DEBUG/C
.continue
See the description of the DEBUG subcommand under the USER command in "Keyboard Commands".
.end

.ssec |CLI Examples|

To transfer files FTP.run and FTP.syms from the Alto called "Michelson" to the Alto called "Morley", one might start up FTP on Michelson (to act as an FTP Server), then walk over to Morley and type:

.once indent 5,5,5
FTP Michelson Retrieve/C FTP.run FTP.syms

Alternatively, one could start an FTP server on Morley (invoking it by "FTP/O" to permit files to be overwritten on Morley's disk), then issue the following command to Michelson:

.once indent 5,5,5
FTP Morley Store/C FTP.run FTP.syms

The latter approach is recommended for transferring large groups of files such as "*.run" (since expansion of the "*" will be performed by the Alto Executive).

To retrieve User.cm from the FTP server running on Alto serial number 123 (name unknown, but it is on the local Ethernet):

.once indent 5,5,5
FTP 123'# Retrieve/C User.cm

Note that the "#" must be preceded by a single quote when included in a command line, since otherwise the Alto Executive does funny things with it.  (Quotes are not necessary when typing to FTP's interactive keyboard interpreter).

To start FTP, have the FTP User connect to Maxc, and then accept further commands from the keyboard:

.once indent 5,5,5
FTP Maxc

To retrieve <System>Pup-Network.txt from Maxc and store it on the Alto as PupDirectory.bravo, and store PupRTP.bcpl, Pup1b.bcpl, and PupBSPStreams.bcpl on <DRB> with their names unchanged:

.once indent 5,5,5 nojust
FTP Maxc Connect/C drb mypassword Retrieve/S <System>Pup-Network.txt PupDirectory.bravo Store/C PupRTP.bcpl Pup1b.bcpl PupBSPStreams.bcpl

To retrieve the latest copy of all .RUN files from the <alto> directory, overwriting copies on the Alto disk (The single quote is necessary to prevent the Alto Executive from expanding the "*"):

.once indent 5,5,5
FTP Maxc Retrieve/C <alto>'*.run

To update the Alto disk with new copies of all <alto> files whose names are contained in file UpdateFiles.cm, requesting confirmation before each retrieval:

.once indent 5,5,5
FTP Maxc Directory/C Alto Ret/>V @UpdateFiles.cm@

To store all files with extension .BCPL from the local Alto disk to your login directory on Maxc (the Alto Executive will expand "*.bcpl" before invoking FTP):

.once indent 5,5,5
FTP Maxc Store/C *.bcpl

To retrieve <System>Host-name/descriptor-file.txt;43 (two single quotes are necessary to get the "/" past the Alto Executive and the FTP command scanner, and one quote is necessary to get the ";" past the Alto Executive):

.once indent 5,5,5
FTP Maxc Ret/C <System>Host-name''/descriptor-file.txt';43

To cause Memo.press to be spooled for printing by the Maxc printing system:

.once indent 5,5,5
FTP Maxc Store/S Memo.press LPT:

This also works unformatted text files if you know what you are doing.  It does not do the right thing for Bravo-format files.

To use FTP as a stop-gap IFS:

.once indent 5,5,5
FTP/T-UO

This starts only a server with overwriting of existing files permitted.  When using the trident, there isn't enough space to start both a User and a Server.

.sec |File Property Defaulting|

Without explicit information from the file system, it is often difficult to determine whether a file is Binary or Text, if Binary, what its byte-size is, and if Text, what End-Of-Line convention is used.  The User and Server FTPs use some simple heuristics to determine the correct manner in which to transfer a file.  The heuristics generally do the right thing in the face of incomplete information, and can be overridden by explicit commands from a human user who knows better.

The FTP protocol specifies a standard representation for a file while in transit over a network.  If the file is of type Binary, each logical byte is packed right-justified in an integral number of 8-bit bytes.  The byte-size is sent as a property along with the file.  If the file is of type Text, each character is sent right-justified in an 8-bit byte.  An EOL convention may be sent as a file property.  The default is that <return> marks the end of a line.

.ssec |File Types|

FTP determines the type of a local file by reading it and looking for bytes with the high-order bit on.  If any byte in the file has a high-order bit on, the file is assumed to be Type Binary, otherwise it is assumed to be Type Text.  FTP will generate a warning, but allow you to send what it thinks to be a text file as type Binary, since no information is lost.  It will refuse to send a binary file as type text.

.begin indent 9,9
Don't specify a Type unless you know what you are doing.  The heuristic will not lose information.
.end

.ssec |Byte-Size|

If a file is type Binary, the byte-size is assumed to be 8 unless otherwise specified.  The FTP User and Server will both accept binary files of any byte-size and write them as 8 bit bytes on the disk.  No transformation is done on the data as it is written to the disk: it is stored in network default format.  Since there is no place in the Alto file system to save the byte-size property, it is lost.

Similarly, requests for Binary files will be honored with any byte size, and whatever is on the disk will be sent to the net without transformation.  Since Alto files have no byte size information, the byte-size property will be defaulted to 8 unless otherwise specified (by the BYTE command), in which case whatever was otherwise specified will be sent as the byte size.

.begin indent 9,9
Don't specify a Byte-size unless you know what you are doing.  Alto-Alto transfers can't go wrong.  Alto-Maxc transfers with weird byte-sizes will not work unless the byte-size specified in the Alto to Maxc direction is the same as the byte-size in which the file was stored on the Alto.  If it isn't, the Alto will not give any error indication, but the result will be garbage.
.end

.ssec |End-of-Line Conventions|

FTPs are expected to be able to convert text files between the local file system End-Of-Line (EOL) convention and the network convention.  Conveniently enough, the Alto file system's internal representation of a text file is the same as the network standard (a bare <return> marks the end of a line).  The Alto FTP does not do any transformations on text files.  It will refuse to store a text file coming in from the net whose EOL convention is CRLF.

As an escape to bypass conversion and checking, EOL convention 'transparent' tells both ends NOT to convert to network standard, but rather send a file 'as is'.  This is included for Lisp files which contain internal character pointers that are messed up by removing line feed characters.

.begin indent 9,9
Don't specify an EOL convention unless you know what you are doing.  If your text file is a Lisp source file, specify EOL convention 'Transparent'.
.end

.ssec |File Dates|

The Alto file system keeps three dates with each file: Creation, Read, and Write.  FTP treats the read and write dates as properties describing the local copy of a file: when the file was last read and written in the local file system.  FTP treats the creation date as a property of the file contents:  when the file contents were originally created, not when the local copy was created.  Thus when FTP makes a file on the local disk, the creation date is set to the creation date supplied by the remote FTP, the write date is set to 'now' and the read date is set to 'never read'.

.sec |Abort and Error messages|

The most common Abort message is "Timeout.  Good bye", generated when a server process has not received any commands for a long time (typically 3 minutes).

The most common Error message is "Port IQ overflow" indicating a momentary shortage of input buffers at the remote host.  Receiving an Error Pup does not imply that the file in transit has been damaged.  Loss of or damage to a file will be indicated by an explicit message in the User FTP window.  The next iteration of Pup will probably rename 'Error Pups' to be 'Information Pups'.

.sec |Telnet|

FTP provides a simple User Telnet as a convenience for logging into a remote host (e.g., Maxc) to poke around without having to leave the FTP subsystem and start Chat.  It lacks most of the creature comforts Chat provides, such as automatic attaching to detached jobs, automatic logging in, etc.  The Telnet is not enabled when the User FTP is being controlled from the command line.  When the Telnet does not have an open connection, it waits for you to type a host name with the syntax explained above for the OPEN command, and then attempts to connect to the specified host.  If you wish to abort the connection attempt, hit the bottom unmarked key (opposite right-shift).  You can get a larger Telnet window by not starting a server (type FTP/-S to the Executive).

.sec |Revision History|

April 1976

First release.

May 1976

/Q switch added to CONNECT.  Connection requests to the User FTP and Telnet can be aborted.  Login prompt changed.  1 minute Timeout added when waiting to finish after a command line error.  User FTP automatically recovers from more "No" responses from the remote server.

June 1976

Dos version released.  DIRECTORY and LIST, commands added.  Update (/U) option added.  File creation dates added.  3 minute no-activity timeout added to FTP Server.  FTP version, time-of-day, and machine address added in top window.  "Ding" now flashes only the affected window instead of the whole display.

August 1976

RDos version released.  Same as June release for Dos and Alto.

October 1976

DUMP and LOAD commands added to user FTP.  KILL command added.  Free disk page count added to the title line.  Verify (/V) switch added to the RETRIEVE command.

November 1976

Bug fixes to the October release.

May 1977

This version was only released to friends.  KILL command removed and turned into a server option.  DEBUG command moved into new USER and SERVER commands.  Trident disk option (/T) added.  User LIST command improved and Server LIST response implemented.  Password checking by the FTP server implemented.  Telnet window enlarged at the expense of possibly losing information from the top of the window if the lines are very full.  DELETE, RENAME, and DEVICE commands implemented.  Much internal reorganization so that the protocol modules could be used in IFS and released as a package.

July 1977

Global switches changed.  <Shift-Swat> should work more reliably now.  User LIST command further improved.  Keyboard command interpreter is much more robust and consistant.  Command line STORE and DUMP go much faster since they look up files using MDI.  FTP/Tx opens Trident unit 'x'.  LOGIN command added to command line interpreter.

November 1977

Microcode added to speed up execution.

March 1978

User log option added (see /L and /A switches and 'FTP User Log' section).  AllocatorDebug switch removed.  New command line commands COMPARE, OPEN, and CLOSE added.  Command line errors are handled differently (see /E global switch and 'Command Line Errors' section).  When using a Trident, either a User or a Server FTP is started but not both (see the section on Trident disks).

September 1979

This is a maintenance release coordinated with OS17, fixing a few bugs and reloading with current packages.  CONNECT cancels any previous DIRECTORY.  CLOSE cancels any previous CONNECT, DIRECTORY, DEVICE, TYPE, BYTE, or EOLC.  Multiple logical file systems on a T-300 can now be addressed: Ftp/T400 opens logical filesystem 1 on physical unit 0.

October 1979

The command line version of the OPEN command retries failed connection attempts every five seconds under control of the error flag.  Ftp.boot is now a type B boot file.  It EtherBoots faster and consumes less disk space in boot servers.  It now works with all Alto file system configurations.

June 1980

New command line commands: LIST, LOAD/U and LOAD/S.  Ftp handles file creation dates in dump-format files.  Subcommand mode in the keyboard LIST command is the same as Maxc and IFS, namely one terminates the filename with <comma carriage-return>, and the VERBOSE option includes file lengths.  The keyboard DIRECTORY and DEVICE commands display their previous values.  STORE and RETRIEVE report bits per second.  The TFS option now works on Alto/Sugart systems.

September 1980

New commands STORE/U, STORE/V, COMMENT/C, and VERSION.  /A switch during date controlled transfers controls whether to transfer a file when the corresponding file in the other filesystem doesn't exist.  /D switch controls display of file creation dates.

October 1980

New switches: /=, /#, />, /<, which generalize date-controlled transfers (see section 5.2).  When Ftp finishes, it only updates the username and password in the OS if no password was present when it started.  Thus, if you log in as "guest" to access a file on a foreign file server, Ftp won't clobber your real identity.

December 1981

New keyboard command COMPARE.  The keyboard and command line COMPARE commands now give the exact byte position of the first difference.  Store and retrieve go faster.