264 lines
9.5 KiB
TeX
264 lines
9.5 KiB
TeX
\section{FTP client}\label{sec:ftp}
|
|
\begin{description}
|
|
\item[Used files:] ftp.scm
|
|
\item[Name of the package:] ftp
|
|
\end{description}
|
|
|
|
\subsection{What users want to know}
|
|
This module lets you transfer files between networked machines from
|
|
the Scheme Shell, using the File Transfer Protocol as described in
|
|
RFC~959. The protocol specifies the behaviour of a server machine,
|
|
which runs an ftp daemon (not implemented by this module), and of
|
|
clients (that's us) which request services from the server.
|
|
|
|
Some of the procedures in this module extract useful information from
|
|
the server's reply, such as the size of a file, or the name of the
|
|
directory we have moved to. These procedures return either the
|
|
extracted information, or \sharpf{} to indicate failure. Other
|
|
procedures return a ``status'', which is either the server's reply as
|
|
a string, or \sharpf{} to signify failure.
|
|
|
|
The server's response is always checked. If the server's response
|
|
doesn't match the expected code from the server, an catchable
|
|
\ex{ftp:error} is raised.
|
|
|
|
\FIXME{The source says you can look at pop3.scm to find out how to
|
|
catch the ftp:error raised by some procedures this. We have not had
|
|
a look there, yet.}
|
|
|
|
\subsubsection*{Entry points }
|
|
|
|
\defun{ftp:connect} {host \ovar{logfile}} {connection}
|
|
\begin{desc}
|
|
Open a command connection with the remote machine \semvar{host}.
|
|
Optionally start logging the conversation with the server to
|
|
\semvar{logfile}, which will be appended to if it already exists,
|
|
and created otherwise. Beware, the \semvar{logfile} contains
|
|
passwords in clear text (it is created with permissions
|
|
\ex{og-rxw})!
|
|
\end{desc}
|
|
|
|
\defun{ftp:login} {connection \ovar{login \ovar{passwd}}} {status}
|
|
\begin{desc}
|
|
Log in to the remote host. If a \semvar{login} and \semvar{password}
|
|
are not provided, they are first searched for in the user's
|
|
\~/.netrc file, or default to user ``anonymous'' and password
|
|
``user@host''
|
|
\end{desc}
|
|
|
|
\defun{ftp:type} {connection type} {status}
|
|
\begin{desc}
|
|
Change the transfer mode for future data connections. This may be
|
|
either \ex{'ascii }or \ex{'text}, respectively, for transfering text
|
|
files, or \ex{'binary} for transfering binary files. If
|
|
\semvar{type} is a string it is sent verbatim to the server.
|
|
\end{desc}
|
|
|
|
\defun{ftp:rename} {connection oldname newname} {status}
|
|
\begin{desc}
|
|
Change the name of \semvar{oldname} on the remote host to
|
|
\semvar{newname} (assuming sufficient permissions). \semvar{oldname}
|
|
and \semvar{newname} are strings; if prefixed with "/" they are
|
|
taken relative to the server's root, and otherwise they are relative
|
|
to the current directory. Note that in the case of anonymous ftp
|
|
(user ``anonymous'' or ``ftp''), the server root is different from
|
|
the root of the servers's filesystem.
|
|
\end{desc}
|
|
|
|
\defun{ftp:delete} {connection file} {status}
|
|
\begin{desc}
|
|
Delete \semvar{file} from the remote host (assuming the user has
|
|
appropriate permissions).
|
|
\end{desc}
|
|
|
|
\defun{ftp:cd} {connection dir} {status}
|
|
\begin{desc}
|
|
Change the current directory on the server.
|
|
\end{desc}
|
|
|
|
\defun{ftp:cdup} {connection} {status}
|
|
\begin{desc}
|
|
Move to the parent directory on the server.
|
|
\end{desc}
|
|
|
|
\defun{ftp:pwd} {connection} {string}
|
|
\begin{desc}
|
|
Return the current directory on the remote host, as a string.
|
|
\end{desc}
|
|
|
|
\defun{ftp:ls} {connection} {status}
|
|
\begin{desc}
|
|
Provide a listing of the current directory's contents, in short
|
|
format, \ie as a list of filenames.
|
|
\end{desc}
|
|
|
|
\defun{ftp:dir} {connection} {status}
|
|
\begin{desc}
|
|
Provide a listing of the current directory's contents, in long
|
|
format. Most servers (\Unix, MS Windows, MacOS) use a standard
|
|
format with one file per line, with the file size and other
|
|
information, but other servers (VMS, \ldots) use their own format.
|
|
\end{desc}
|
|
|
|
\defun{ftp:get} {connection remote-file \ovar{local-file}} {status $|$ string}
|
|
\begin{desc}
|
|
Download \semvar{remote-file} from the FTP server. If
|
|
\semvar{local-file} is a string, save the data to
|
|
\semvar{local-file} on the local host; otherwise save to a local
|
|
file named \semvar{remote-file}. \semvar{remote-file} and
|
|
\semvar{local-file} may be absolute file names (with a leading `/'),
|
|
or relative to the current directory. If \semvar{local-file} is
|
|
\sharpt, output data to \ex{(current-output-port)}, and if it is
|
|
\sharpf{} return the data as a string.
|
|
\end{desc}
|
|
|
|
\defun{ftp:put} {connection local-file \ovar{remote-file}} {status}
|
|
\begin{desc}
|
|
Upload \semvar{local-file} to the FTP server. If
|
|
\semvar{remote-file} is specified, then save the data to
|
|
\semvar{remote-file} on the remote host; otherwise save to a remote
|
|
file named \semvar{local-file}. \semvar{local-file} and
|
|
\semvar{remote-file} may be absolute file names (with a leading
|
|
`/'), or relative to the current directory.
|
|
\end{desc}
|
|
|
|
\defun{ftp:append}{connection local-file \ovar{remote-file}}{status}
|
|
\begin{desc}
|
|
Does the same as \ex{ftp:get}, but appends the data to the remote
|
|
file, if it exists.
|
|
\end{desc}
|
|
|
|
\defun{ftp:rmdir} {connection dir} {status}
|
|
\begin{desc}
|
|
Remove the directory \semvar{dir} from the remote host (assuming
|
|
sufficient permissions).
|
|
\end{desc}
|
|
|
|
\defun{ftp:mkdir} {connection dir} {status}
|
|
\begin{desc}
|
|
Create a new directory named \semvar{dir} on the remote host
|
|
(assuming sufficient permissions).
|
|
\end{desc}
|
|
|
|
\defun{ftp:modification-time} {connection file} {date}
|
|
\begin{desc}
|
|
Request the time of the last modification of \semvar{file} on the
|
|
remote host, and on success return a Scsh date record. This command
|
|
is not part of RFC~959 and is not implemented by all servers, but is
|
|
useful for mirroring.
|
|
\end{desc}
|
|
|
|
\defun{ftp:size} {connection file} {integer}
|
|
\begin{desc}
|
|
Return the size of \semvar{file} in bytes.
|
|
\end{desc}
|
|
|
|
\defun{ftp:abort} {connection} {status}
|
|
\begin{desc}
|
|
Abort the current data transfer. Not particularly useful with this
|
|
im\-ple\-men\-ta\-tion since the data transfer commands only return
|
|
once the transfer is complete.
|
|
\end{desc}
|
|
|
|
\defun{ftp:quit} {connection} {status}
|
|
\begin{desc}
|
|
Close the connection to the remote host. The \semvar{connection}
|
|
object is useless after a quit command.
|
|
\end{desc}
|
|
|
|
\defun{ftp:quot}{connection command}{status}
|
|
\begin{desc}
|
|
Send a \semvar{command} verbatim to the remote server and wait for a
|
|
response.
|
|
\end{desc}
|
|
|
|
|
|
\subsubsection*{Unimplemented}
|
|
|
|
The following rfc959 commands are not implemented:
|
|
|
|
\begin{tabular}{ll}
|
|
\ex{ACCT} & account; this is ignored by most servers) \\
|
|
\ex{SMNT} & structure mount, for mounting another filesystem \\
|
|
\ex{REIN} & reinitialize connection \\
|
|
\ex{LOGOUT} & quit without interrupting ongoing transfers \\
|
|
\ex{STRU} & file structure \\
|
|
\ex{ALLO} & allocate space on server \\
|
|
\end{tabular}
|
|
|
|
\subsection{What programmers want to know}
|
|
|
|
\subsection*{Overview}
|
|
Communication is initiated by the client. The server responds to each
|
|
request with a three digit status code and an explanatory message, and
|
|
occasionally with data (which is sent via a separate, one-off
|
|
channel). The client starts by opening a command connection to a well
|
|
known port on the server machine. Messages send to the server are of
|
|
the form
|
|
\codex{CMD [ <space> arg ] <CR> <LF>}
|
|
Replies from the server are of the form
|
|
\codex{xyz <space> Informative message <CR> <LF>}
|
|
where xyz is a three digit code which indicates whether the operation
|
|
succeeded or not, whether the server is waiting for more data, etc.
|
|
The server may also send multiline messages of the form
|
|
|
|
\begin{code}
|
|
xyz- <space> Start of multiline message <CR> <LF>
|
|
[ <space>+ More information ]* <CR> <LF>
|
|
xyz <space> End of multiline message <CR> <LF>%
|
|
\end{code}
|
|
|
|
For further informations have a look at the source file.
|
|
|
|
This module has no support for sites behind a firewall. It shouldn't
|
|
be very tricky; it only requires using passive mode. Might want to add
|
|
something like the \ex{/usr/bin/ftp} command \ex{restrict}, which
|
|
implements data port range restrictions.
|
|
|
|
|
|
\subsubsection*{Portablitity}
|
|
|
|
Items of the following list are necessary in order to use this module:
|
|
\begin{itemize}
|
|
\item The netrc.scm module for parsing ~/.netrc files.
|
|
\item Scsh socket code
|
|
\item Scsh records
|
|
\item Receive for multiple values
|
|
\item \scm{} signals/handlers
|
|
\end{itemize}
|
|
|
|
|
|
\subsubsection*{Related work}
|
|
|
|
\begin{itemize}
|
|
\item RFC~959 describes the FTP protocol; see \newline
|
|
\ex{http://www.cis.ohio-state.edu/htbin/rfc/rfc959.html}
|
|
\item \ex{/anonymous@sunsite.unc.edu:/pub/Linux/libs/ftplib.tar.gz} is
|
|
a library similar to this one, written in C, by Thomas Pfau
|
|
\item \ex{FTP.pm} is a Perl module with similar functionality
|
|
(available from \ex{http://www.perl.com/CPAN})
|
|
\item Emacs gets transparent remote file access from \ex{ange-ftp.el}
|
|
by Ange Norman. However, it cheats by using \ex{/usr/bin/ftp}.
|
|
\item Siod (a small-footprint Scheme implementation by George Carette)
|
|
comes with a file \ex{ftp.scm }with a small subset of these
|
|
functions defined.
|
|
\end{itemize}
|
|
|
|
\subsubsection*{TODO}
|
|
\begin{itemize}
|
|
\item Handle passive mode and firewalls.
|
|
\item Unix-specific commands such as \ex{SITE UMASK}, \ex{SITE CHMOD},
|
|
\ex{SITE IDLE}, \ex{SITE HELP}.
|
|
\item Object-based interface? (like SICP message passing).
|
|
\item Improved error handling.
|
|
\item A lot of the calls to format could be replaced by calls to
|
|
string-join. Maybe format is easier to read?
|
|
\item The \ex{ftp:rename} command should have an optional argument
|
|
\ex{:rename} which defaults to \sharpf, which would make us upload
|
|
to a temporary name and rename at the end of the upload. This
|
|
atomicity is important for ftp or http servers which are serving a
|
|
load, and to avoid problems with "no space on device".
|
|
\item Automatic relogin a la \ex{ang-ftp}.
|
|
\end{itemize}
|
|
|