* Created LaTeX style documentation. All documentation in plain text files
were now moved to this LaTeX doc (man.tex). Currently, not everything is documented.
This commit is contained in:
parent
216c0d124d
commit
7e78d0f8a8
178
doc/ftpd.scm.doc
178
doc/ftpd.scm.doc
|
@ -1,178 +0,0 @@
|
|||
This file documents how to use the ftp-daemon ftpd
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Usage as a stand-alone daemon:
|
||||
|
||||
Start the daemon in a scsh (or with a script, see below) using
|
||||
|
||||
,config ,load modules.scm
|
||||
,open ftpd
|
||||
(ftpd <anonymous-home> [<port>])
|
||||
|
||||
(confirm open's question for opening the ftpd-structure)
|
||||
where <anonymous-home> is the root-directory of the ftp-server and
|
||||
<port> the port the server is listening to. Usage of relative paths in
|
||||
<anonymous-home> is not encouraged. <port> defaults to 21.
|
||||
|
||||
For example
|
||||
|
||||
(ftpd (cwd) 8080)
|
||||
|
||||
starts the server with the current directory as anonymous home and
|
||||
listening to port 8080.
|
||||
|
||||
|
||||
Usage with the collaboration of a daemon like inetd:
|
||||
|
||||
Instead of FTPD, inetd uses FTPD-INETD, for example:
|
||||
|
||||
(ftpd-inetd (cwd))
|
||||
|
||||
starts the server with the current directory as anonymous home and
|
||||
handling the connection (given from inetd) through the current input-
|
||||
and output-ports.
|
||||
|
||||
|
||||
Example
|
||||
|
||||
This is how archive.informatik.uni-tuebingen.de is called at the
|
||||
university of Tuebingen:
|
||||
|
||||
#!/bin/sh
|
||||
/afs/informatik.uni-tuebingen.de/rs_aix43/scsh-0.6-alpha/bin/scsh <<EOF
|
||||
,batch on
|
||||
,config ,load modules.scm
|
||||
,open ftpd
|
||||
,open threads
|
||||
(define (archive-ftpd args)
|
||||
(with-syslog-destination
|
||||
#f
|
||||
#f
|
||||
(syslog-facility local0)
|
||||
#f
|
||||
(lambda ()
|
||||
(ftpd "/afs/informatik.uni-tuebingen.de/data/archive/"))))
|
||||
(dump-scsh-program archive-ftpd "archive-ftpd.image")
|
||||
;; (dump-scsh "archive-ftpd.image")
|
||||
EOF
|
||||
|
||||
Note, that the options for the syslog are set via With
|
||||
WITH-SYSLOG-DESTINATION, a scsh-command. Here, the syslog-facility is
|
||||
set to local0. See man syslog for further details on syslog.
|
||||
|
||||
|
||||
SUPPORTED COMMANDS
|
||||
------------------
|
||||
|
||||
|
||||
ftpd supports following commands according to RFC 959:
|
||||
|
||||
ABOR - abort connection
|
||||
CDUP - move to parent directory
|
||||
CWD - move to specified directory (relative paths may be used)
|
||||
DELE - delete file
|
||||
LIST - list files in current directory (long format)
|
||||
MDTM - deliver modification time of a regular file
|
||||
MKD - make directory
|
||||
MODE - change mode (only stream mode (S) is supported)
|
||||
NLST - list files in current directory (short format)
|
||||
NOOP - do nothing
|
||||
PASS - read in passphrase
|
||||
PASV - change to passive mode
|
||||
PORT - change connection port
|
||||
PWD - return name of working directory (print working directory)
|
||||
QUIT - quit session
|
||||
RETR - return file (GET)
|
||||
RMD - remove directory
|
||||
RNFR - read in the name of a file to be renamed (use RNTO next)
|
||||
RNTO - rename file mentioned before in a RNFR command
|
||||
SIZE - return size of a regular file
|
||||
STOR - store file (PUT)
|
||||
STRU - change structure to transfer files
|
||||
(only the file structure is supported)
|
||||
SYST - return system type
|
||||
TYPE - change type (supported types: A = ascii mode, I, L8 = 8-bit
|
||||
binary mode)
|
||||
USER - login user (only anonymous logins allowed, use "anonymous" or
|
||||
"ftp" as user name)
|
||||
|
||||
|
||||
SYSLOG-MESSAGES
|
||||
---------------
|
||||
|
||||
ftpd outputs a lot of syslog-messages. A syslog-message looks like
|
||||
this:
|
||||
|
||||
Jul 24 18:34:52 axl ftpd: (thread 21) anonymous user login (230)
|
||||
|
||||
The log gives you following informations (including those delivered by
|
||||
the syslog-daemon):
|
||||
|
||||
* the date and time the log was made (here: Jul 24 18:34:52)
|
||||
* the machine the log was made on (here: axl)
|
||||
* the program, that output the log (ftpd)
|
||||
* the thread the message concerns (here thread 21)
|
||||
Each connection is linked with a thread, that handles the commands
|
||||
of this connection. When the thread is created, there is a log
|
||||
containing the remote address and the thread number, so in future
|
||||
logs the thread number labels the connection. As at any given time
|
||||
the thread number is unique, this is a bijection. (Note that the
|
||||
thread numbers are not unique over a period of time).
|
||||
* the log message (here: notification about an anonymous user login)
|
||||
* the reply code returned by ftpd, if any (here: 230)
|
||||
|
||||
|
||||
The Syslog-levels used:
|
||||
-----------------------
|
||||
|
||||
|
||||
Overview:
|
||||
|
||||
|
||||
As NOTICE are logged:
|
||||
|
||||
* messages concerning CONNECTIONS
|
||||
* the execution of the STOR command
|
||||
* internal errors
|
||||
* unix errors
|
||||
* reaching of actually unreachable case branches
|
||||
|
||||
|
||||
As INFO are logged:
|
||||
|
||||
* messages concerning all OTHER COMMANDS, including the RETR command
|
||||
|
||||
|
||||
As DEBUG are logged:
|
||||
|
||||
* all other messages, including debug messages
|
||||
|
||||
|
||||
Details:
|
||||
|
||||
Messages concerning connections (establishing connection, connection
|
||||
refused, closing connection due to timeout, etc.) are logged at
|
||||
notice-level.
|
||||
|
||||
The success of the STOR-command (PUT, i.e. somebody is putting
|
||||
something on your server via ftp) is also logged at notice-level. In
|
||||
fact, the log is made before the storing is started actually.
|
||||
|
||||
Internal errors, unix errors and the reaching of unreachable
|
||||
case-branches are also logged at notice-level.
|
||||
|
||||
Messages concerning all other commands including the RETR-command
|
||||
(GET) are logged at info-level.
|
||||
|
||||
All other messages including debugging-informations are logged at
|
||||
debug-level. If you want to debug ftpd, put all the messages in one
|
||||
single file, since the debug-messages may refer to messages of other
|
||||
levels.
|
||||
|
||||
Success (as long as interesting) and failure of commands are logged at
|
||||
info-level, except the success of the STOR-command, that is logged at
|
||||
notice-level (as mentioned above).
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
./man.aux
|
||||
./intro.aux
|
||||
./httpd.aux
|
||||
./cgi-server.aux
|
||||
./cgi-script.aux
|
||||
./ftpd.aux
|
||||
./ftp.aux
|
||||
./netrc.aux
|
||||
./uri.aux
|
||||
./rfc822.aux
|
||||
./ntp.aux
|
||||
./smtp.aux
|
||||
./pop3.aux
|
||||
./stringhax.aux
|
||||
./url.aux
|
||||
./toothless.aux
|
||||
./man.log
|
||||
./man.dvi
|
|
@ -0,0 +1,8 @@
|
|||
\section{CGI scripts}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] cgi-script.scm
|
||||
\item[Name of the package:] cgi-script
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,8 @@
|
|||
\section{CGI server}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] cgi-server.scm
|
||||
\item[Name of the package:] cgi-server
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,8 @@
|
|||
\section{CGI server}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] cgi-server.scm
|
||||
\item[Name of the package:] cgi-server
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,281 @@
|
|||
\makeatletter
|
||||
\def\ie{\mbox{\emph{i.e.}}} % \mbox keeps the last period from
|
||||
\def\Ie{\mbox{\emph{I.e.}}} % looking like an end-of-sentence.
|
||||
\def\eg{\mbox{\emph{e.g.}}}
|
||||
\def\Eg{\mbox{\emph{E.g.}}}
|
||||
\def\etc{{\em etc.}}
|
||||
|
||||
\def\Lisp{\textsc{Lisp}}
|
||||
\def\CommonLisp{\textsc{Common Lisp}}
|
||||
\def\Ascii{\textsc{Ascii}}
|
||||
\def\Ansi{\textsc{Ansi}}
|
||||
\def\Unix{{Unix}} % Not smallcaps, according to Bart.
|
||||
\def\Scheme{{Scheme}}
|
||||
\def\scm{{Scheme 48}}
|
||||
\def\RnRS{R5RS\ }
|
||||
\def\Posix{\textsc{Posix}}
|
||||
|
||||
\def\sharpf{\normalfont\texttt{\#f}}
|
||||
\def\sharpt{\normalfont\texttt{\#t}}
|
||||
\newcommand{\synteq}{\textnormal{::=}}
|
||||
|
||||
\def\maketildeother{\catcode`\~=12}
|
||||
\def\maketildeactive{\catcode`\~=13}
|
||||
\def\~{\char`\~}
|
||||
|
||||
\newcommand{\evalsto}{\ensuremath{\Rightarrow}}
|
||||
|
||||
% One-line code examples
|
||||
%\newcommand{\codex}[1]% One line, centred. Tight spacing.
|
||||
% {$$\abovedisplayskip=.75ex plus 1ex minus .5ex%
|
||||
% \belowdisplayskip=\abovedisplayskip%
|
||||
% \abovedisplayshortskip=0ex plus .5ex%
|
||||
% \belowdisplayshortskip=\abovedisplayshortskip%
|
||||
% \hbox{\ttt #1}$$}
|
||||
%\newcommand{\codex}[1]{\begin{tightinset}\ex{#1}\end{tightinset}\ignorespaces}
|
||||
\newcommand{\codex}[1]{\begin{leftinset}\ex{#1}\end{leftinset}\ignorespaces}
|
||||
|
||||
\def\widecode{\codeaux{\leftmargin=0pt\topsep=0pt}}
|
||||
\def\endwidecode{\endcodeaux}
|
||||
|
||||
% For multiletter vars in math mode:
|
||||
\newcommand{\var}[1]{\mbox{\frenchspacing\it{#1}}}
|
||||
\newcommand{\vari}[2]{\ensuremath{\mbox{\it{#1}}_{#2}}}
|
||||
\newcommand{\ovar}[1]{\mbox{\textnormal{[}\frenchspacing\it{#1}\textnormal{]}}}
|
||||
|
||||
%% What you frequently want when you say \tt:
|
||||
\def\ttchars{\catcode``=13\@noligs\frenchspacing}
|
||||
\def\ttt{\normalfont\ttfamily\ttchars}
|
||||
|
||||
% Works in math mode; all special chars remain special; cheaper than \cd.
|
||||
% Will not be correct size in super and subscripts, though.
|
||||
\newcommand{\ex}[1]{{\normalfont\texttt{\ttchars #1}}}
|
||||
|
||||
\newenvironment{inset}
|
||||
{\bgroup\parskip=1ex plus 1ex\begin{list}{}%
|
||||
{\topsep=0pt\rightmargin\leftmargin}%
|
||||
\item[]}%
|
||||
{\end{list}\leavevmode\egroup\global\@ignoretrue}
|
||||
|
||||
\newenvironment{leftinset}
|
||||
{\bgroup\parskip=1ex plus 1ex\begin{list}{}%
|
||||
{\topsep=0pt}%
|
||||
\item[]}%
|
||||
{\end{list}\leavevmode\egroup\global\@ignoretrue}
|
||||
|
||||
\newenvironment{tightinset}
|
||||
{\bgroup\parskip=0pt\begin{list}{}%
|
||||
{\topsep=0pt\rightmargin\leftmargin}%
|
||||
\item[]}%
|
||||
{\end{list}\leavevmode\egroup\global\@ignoretrue}
|
||||
|
||||
\newenvironment{tightleftinset}
|
||||
{\bgroup\parskip=0pt\begin{list}{}%
|
||||
{\topsep=0pt}%
|
||||
\item[]}%
|
||||
{\end{list}\leavevmode\egroup\global\@ignoretrue}
|
||||
|
||||
\long\def\remark#1{\bgroup\small\begin{quote}\textsl{Remark: } #1\end{quote}\egroup}
|
||||
\newenvironment{remarkenv}{\bgroup\small\begin{quote}\textsl{Remark: }}%
|
||||
{\end{quote}\egroup}
|
||||
\newcommand{\oops}[1]{\bgroup\small\begin{quote}\textsl{Oops: } #1\end{quote}\egroup}
|
||||
|
||||
\newcommand{\note}[1]{\{Note #1\}}
|
||||
|
||||
\newcommand{\itum}[1]{\item{\bf #1}\\*}
|
||||
|
||||
% For use in code. The \llap magicness makes the lambda exactly as wide as
|
||||
% the other chars in \tt; the \hskip shifts it right a bit so it doesn't
|
||||
% crowd the left paren -- which is necessary if \tt is cmtt.
|
||||
% Note that (\l{x y} (+ x y)) uses the same number of columns in TeX form
|
||||
% as it produces when typeset. This makes it easy to line up the columns
|
||||
% in your input. \l is bound to some useless command in LaTeX, so we have to
|
||||
% define it w/renewcommand.
|
||||
\let\oldl\l %Save the old \l on \oldl
|
||||
\renewcommand{\l}[1]{\ \llap{$\lambda$\hskip-.05em}\ (#1)}
|
||||
|
||||
% This one is for the rare (lambda x ...) case -- it doesn't have the
|
||||
% column-invariant property. Oh, well.
|
||||
\newcommand{\lx}[1]{\ \llap{$\lambda$\hskip-.05em}\ {#1}}
|
||||
|
||||
% For subcaptions
|
||||
\newcommand{\subcaption}[1]
|
||||
{\unskip\vspace{-2mm}\begin{center}\unskip\em#1\end{center}}
|
||||
|
||||
%%% T release notes stuff
|
||||
\newlength{\notewidth}
|
||||
\setlength{\notewidth}{\textwidth}
|
||||
\addtolength{\notewidth}{-1.25in}
|
||||
|
||||
%\newcommand{\remark} [1]
|
||||
% {\par\vspace{\parskip}
|
||||
% \parbox[t]{.75in}{\sc Remark:}
|
||||
% \parbox[t]{\notewidth}{\em #1}
|
||||
% \vspace{\parskip}
|
||||
% }
|
||||
|
||||
\newenvironment{optiontable}%
|
||||
{\begin{tightinset}\renewcommand{\arraystretch}{1.5}%
|
||||
\begin{tabular}{@{}>{\ttt}ll@{}}}%
|
||||
{\end{tabular}\end{tightinset}}%
|
||||
|
||||
\newenvironment{desctable}[1]%
|
||||
{\begin{inset}\renewcommand{\arraystretch}{1.5}%
|
||||
\begin{tabular}{lp{#1}}}%
|
||||
{\end{tabular}\end{inset}}
|
||||
|
||||
\def\*{{\ttt *}}
|
||||
|
||||
% Names of things
|
||||
|
||||
\newcommand{\keyword} [1]{\index{#1}{\normalfont\textsf{#1}}}
|
||||
|
||||
\newcommand{\evalto}{$\Longrightarrow$\ }
|
||||
\renewcommand{\star}{$^*$\/}
|
||||
\newcommand{\+}{$^+$}
|
||||
|
||||
% Semantic domains, used to indicate the type of a value
|
||||
|
||||
\newcommand{\sem}{\normalfont\itshape} %semantic font
|
||||
\newcommand{\semvar}[1]{\textit{#1}} %semantic font
|
||||
\newcommand{\synvar}[1]{\textrm{\textit{$<$#1$>$}}} %syntactic font
|
||||
\newcommand{\type}{\sem}
|
||||
\newcommand{\zeroormore}[1]{{\sem #1$_1$ \ldots #1$_n$}}
|
||||
\newcommand{\oneormore}[1]{{\sem #1$_1$ #1$_2$ \ldots #1$_n$}}
|
||||
|
||||
\newcommand{\proc} {{\sem procedure}}
|
||||
\newcommand{\boolean} {{\sem boolean}}
|
||||
\newcommand{\true} {{\sem true}}
|
||||
\newcommand{\false} {{\sem false}}
|
||||
|
||||
\newcommand{\num} {{\sem number}}
|
||||
\newcommand{\fixnum} {{\sem fixnum}}
|
||||
\newcommand{\integer} {{\sem integer}}
|
||||
\newcommand{\real} {{\sem real}}
|
||||
|
||||
\newcommand{\character} {{\sem character}}
|
||||
\newcommand{\str} {{\sem string}}
|
||||
\newcommand{\sym} {{\sem symbol}}
|
||||
|
||||
\newcommand{\location} {{\sem location}}
|
||||
\newcommand{\object} {{\sem object}}
|
||||
|
||||
\newcommand{\error} {{\sem error}}
|
||||
\newcommand{\syntaxerror} {{\sem syntax error}}
|
||||
\newcommand{\readerror} {{\sem read error}}
|
||||
\newcommand{\undefined} {{\sem undefined}}
|
||||
\newcommand{\noreturn} {{\sem no return value}}
|
||||
|
||||
\newcommand{\port} {{\sem port}}
|
||||
|
||||
% semantic variables
|
||||
|
||||
\newcommand{\identifier} {{\sem identifier}}
|
||||
\newcommand{\identifiers} {\zeroormore{\<ident>}}
|
||||
\newcommand{\expr} {{\sem expression}}
|
||||
\newcommand{\body} {{\sem body}}
|
||||
\newcommand{\valueofbody} {{\sem value~of~body}}
|
||||
\newcommand{\emptylist} {{\sem empty~list}}
|
||||
\newcommand{\car} {\keyword{car}}
|
||||
\newcommand{\cdr} {\keyword{cdr}}
|
||||
\newcommand{\TMPDIR}{\texttt{\$TMPDIR}}
|
||||
|
||||
% generally useful things
|
||||
|
||||
% For line-breaking \tt stuff.
|
||||
\renewcommand{\=}{\discretionary{-}{}{-}}
|
||||
\newcommand{\ob}{\discretionary{}{}{}} % Optional break.
|
||||
|
||||
\newcommand{\indx}[1]{#1 \index{ #1 }}
|
||||
%\newcommand{\gloss}[1]{#1 \glossary{ #1 }}
|
||||
|
||||
% This lossage produces #2 if #1 is zero length, otw #3.
|
||||
% We use it to conditionally add a space between the procedure and
|
||||
% the args in procedure prototypes, but only if there are any args--
|
||||
% we want to produce "(read)", not "(read )".
|
||||
\newlength{\voidlen}
|
||||
\newcommand{\testvoid}[3]{\settowidth\voidlen{#1}\ifdim\voidlen>0in{#3}\else{#2}\fi}
|
||||
|
||||
|
||||
% Typeset a definition prototype line, e.g.:
|
||||
% (cons <arg1> <arg2>) -> pair procedure
|
||||
%
|
||||
% Five args are: proc-name args ret-value(s) type index-entry
|
||||
\newcommand{\dfnix}[5]
|
||||
{\hbox to \linewidth{\ttchars%
|
||||
{\ttt(#1\testvoid{#2}{}{\ }{\sem{#2}}\testvoid{#2}{}{\/})\hskip 1em minus
|
||||
0.5em$\longrightarrow$\hskip 1em minus 0.5em{\sem{#3}}\hfill\quad\textnormal{#4}}}\index{#5}}
|
||||
|
||||
\newcommand{\dfnx}[4] {\dfnix{#1}{#2}{#3}{#4}{#1@\texttt{#1}}}
|
||||
|
||||
\newcommand{\dfn} {\par\medskip\dfnx} % Takes 4 args, actually.
|
||||
\newcommand{\dfni} {\par\medskip\dfnix} % Takes 5 args, actually.
|
||||
|
||||
\newcommand{\defvar} {\par\medskip\defvarx} % Takes 2 args, actually.
|
||||
\newcommand{\defvarx}[2]%
|
||||
{\index{#1}
|
||||
\hbox to \linewidth{\ttchars{{\ttt{#1}} \hfill #2}}}%
|
||||
|
||||
% Typeset the protocol line, then do the following descriptive text indented.
|
||||
% If you want to group two procs together, do the first one with a \dfn,
|
||||
% then the second one, and the documentation, with a \defndescx.
|
||||
|
||||
% This one doesn't put whitespace above. Use it immediately after a \dfn
|
||||
% to group two prototype lines together.
|
||||
\newenvironment{dfndescx}[4]%
|
||||
{\dfnx{#1}{#2}{#3}{#4}\begin{desc}}{\end{desc}}
|
||||
|
||||
\newenvironment{dfndesc}[4] % This one puts whitespace above.
|
||||
{\par\medskip\begin{dfndescx}{#1}{#2}{#3}{#4}}
|
||||
{\end{dfndescx}}
|
||||
|
||||
\newenvironment{desc}%
|
||||
{\nopagebreak[2]%
|
||||
\smallskip
|
||||
\bgroup\begin{list}{}{\topsep=0pt\parskip=0pt}\item[]}
|
||||
{\end{list}\leavevmode\egroup\global\@ignoretrue}
|
||||
|
||||
\newcommand{\defun} [3] {\dfn{#1}{#2}{#3}{procedure}} % preskip
|
||||
\newcommand{\defunx}[3]{\dfnx{#1}{#2}{#3}{procedure}} % no skip
|
||||
|
||||
\newenvironment{defundescx}[3]%
|
||||
{\begin{dfndescx}{#1}{#2}{#3}{procedure}}
|
||||
{\end{dfndescx}}
|
||||
|
||||
\newenvironment{defundesc}[3]%
|
||||
{\begin{dfndesc}{#1}{#2}{#3}{procedure}}
|
||||
{\end{dfndesc}}
|
||||
|
||||
|
||||
\newenvironment{column}{\begin{tabular}[t]{@{}l@{}}}{\end{tabular}}
|
||||
|
||||
\newenvironment{exampletable}%
|
||||
{\begin{leftinset}%
|
||||
\newcommand{\header}[1]{\multicolumn{2}{@{}l@{}}{##1}\\}%
|
||||
\newcommand{\splitline}[2]%
|
||||
{\multicolumn{2}{@{}l@{}}{##1}\\\multicolumn{2}{@{}l@{}}{\qquad\evalto\quad{##2}}}
|
||||
\begin{tabular}{@{}l@{\quad\evalto\quad}l@{}}}%
|
||||
{\end{tabular}\end{leftinset}}
|
||||
|
||||
% Put on blank lines in a code env to allow a pagebreak.
|
||||
\newcommand{\cb}{\pagebreak[0]}
|
||||
|
||||
\newenvironment{boxedcode}
|
||||
{\begin{inset}\tabular{|l|}\hline}
|
||||
{\\ \hline \end{tabular}\end{inset}}
|
||||
|
||||
% A ragged-right decl that doesn't redefine \\ -- for use in tables.
|
||||
\newcommand{\raggedrightparbox}{\let\temp=\\\raggedright\let\\=\temp}
|
||||
|
||||
\newenvironment{boxedfigure}[1]%
|
||||
{\begin{figure}[#1]\begin{boxedminipage}{\linewidth}\vskip 1.5ex}
|
||||
{\end{boxedminipage}\end{figure}}
|
||||
|
||||
%FIXME-command: types out the desired FIXME
|
||||
\newcommand{\FIXME}[1]%
|
||||
{\typeout{**********************************}%
|
||||
\typeout{FIXME: #1}%
|
||||
\typeout{**********************************}}
|
||||
|
||||
|
||||
\makeatother
|
|
@ -0,0 +1,257 @@
|
|||
\section{FTP client}
|
||||
\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. It \semvar{local-file} is
|
||||
\sharpt, output data to \ex{(current-output-file)}, 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: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}
|
||||
|
||||
|
||||
\subsubsection*{Unimplemented}
|
||||
|
||||
The following rfc959 commands are not implemented:
|
||||
|
||||
\begin{table}[htb]
|
||||
\begin{tabular}{|lp{10cm}|}
|
||||
\hline
|
||||
\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 \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
|
||||
|
||||
\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}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
\section{FTP server}
|
||||
|
||||
\begin{description}
|
||||
\item[Used files:] ftpd.scm
|
||||
\item[Name of the package:] ftpd
|
||||
\end{description}
|
||||
|
||||
\subsection{What users want to know}
|
||||
|
||||
\subsubsection*{Entry points}
|
||||
|
||||
\defun {ftpd} {anonymous-home \ovar{port}} {\noreturn}
|
||||
\begin{defundescx}{ftp-inetd} {anonymous-home} {\noreturn}
|
||||
\ex{ftpd} starts the server, using \semvar{anonymous-home} as the
|
||||
root directory of the server. Usage of relative paths is not
|
||||
encouraged. \semvar{port} specifies the port the server is
|
||||
listening for connections. It defaults to 21.
|
||||
|
||||
As the procedure does not return, you have to do a \ex{fork} in
|
||||
order to have a ``real'' daemon:
|
||||
\codex{(fork (lambda () (ftpd "/data/ftp" 8080)))}
|
||||
\ex{ftpd-inetd} is the version to be used with a daemon like
|
||||
\ex{inetd}. If the server is started this way, it handles the
|
||||
connection through the current standard output and input ports.
|
||||
\end{defundescx}
|
||||
|
||||
\subsubsection*{Examples}
|
||||
|
||||
To start the server with the current home directory as root directory
|
||||
and listening on port 8080, use
|
||||
\codex{(ftpd (cwd) 8080)}
|
||||
|
||||
This is how the ftp server at the computing faculty of the university
|
||||
of Tuebingen\footnote{\texttt{archive.informatik.uni-tuebingen.de}} is
|
||||
started:
|
||||
\begin{code}
|
||||
#!/bin/sh /scsh-0.6-alpha/bin/scsh <<EOF
|
||||
,batch on
|
||||
,config ,load modules.scm
|
||||
,open ftpd
|
||||
,open threads
|
||||
(define (archive-ftpd args)
|
||||
(with-syslog-destination
|
||||
#f
|
||||
#f
|
||||
(syslog-facility local0)
|
||||
#f
|
||||
(lambda ()
|
||||
(ftpd "/data/archive/"))))
|
||||
(dump-scsh-program archive-ftpd "archive-ftpd.image")
|
||||
;; (dump-scsh "archive-ftpd.image")
|
||||
EOF\end{code}
|
||||
|
||||
Perhaps you have noticed the \ex{with-syslog-destination} command.
|
||||
\ex{ftpd} generates syslog-messages that can be controlled via this
|
||||
command. The following section gives you an overview of what is logged
|
||||
at which level. See \ex{man 3 syslog} or the
|
||||
\ex{with-syslog-destination} command in the scsh-manual for further
|
||||
details.
|
||||
|
||||
\subsubsection*{Syslog messages}
|
||||
|
||||
\ex{ftpd} outputs a lot of syslog-messages. A syslog-message may look like
|
||||
this:
|
||||
\codex{Jul 24 18:34:52 axl ftpd: (thread 21) anonymous user login (230)}
|
||||
|
||||
The log gives you following informations (including those delivered by
|
||||
the syslog-daemon):
|
||||
|
||||
\begin{enumerate}
|
||||
\item The date and time the log was made (here: Jul 24 18:34:52)
|
||||
\item The machine the log was made on (here: axl)
|
||||
\item The program, that output the log (ftpd)
|
||||
\item The thread the message concerns (here thread 21)
|
||||
|
||||
Each connection is linked with a thread, that handles the commands
|
||||
of this connection. When the thread is created, there is a entry in
|
||||
the log file containing the remote address and the thread number, so
|
||||
in future logs the thread number labels the connection. As at any
|
||||
given time the thread number is unique, this is a bijection. (Note
|
||||
that the thread numbers are not unique over a period of time).
|
||||
\item The log message (here: notification about an anonymous user login)
|
||||
\item The reply code returned by ftpd, if any (here: 230)
|
||||
\end{enumerate}
|
||||
|
||||
\subsubsection*{The Syslog-levels used\footnote{For further details
|
||||
on syslog levels see \ex{man 3 syslog}}}
|
||||
|
||||
Following events are logged as
|
||||
\begin{description}
|
||||
|
||||
\item{\ex{NOTICE} level:}
|
||||
\begin{itemize}
|
||||
\item Messages concerning \emph{connections} (establishing connection,
|
||||
connection refused, closing connection due to timeout, etc.)
|
||||
\item The execution of the \ex{STOR} command. Its success (\ie
|
||||
somebody is putting something on your server via ftp, also known as
|
||||
\ex{PUT}) is also logged at notice-level. In fact, the log is made
|
||||
before the storing is started actually.
|
||||
\item Internal errors
|
||||
\item Unix errors
|
||||
\item Reaching of actually unreachable case branches
|
||||
\end{itemize}
|
||||
|
||||
\item{\ex{INFO} level:} Messages concerning all \emph{other commands},
|
||||
including the \ex{RETR} command.
|
||||
|
||||
\item{\ex{DEBUG} level:} All other messages, including debug messages.
|
||||
If you want to debug ftpd, put all the messages in one single file,
|
||||
since the debug-messages may refer to messages of other levels.
|
||||
\end{description}
|
||||
|
||||
Success (as long as interesting) and failure of commands are logged at
|
||||
info-level, except the success of the STOR-command, that is logged at
|
||||
notice-level (as mentioned above).
|
||||
\subsubsection*{Supported commands}
|
||||
|
||||
For those of you who are intrested, the table \ref{ftpd-commands}
|
||||
shows the list of supported commands by \ex{ftpd} according to
|
||||
RFC~959:
|
||||
|
||||
\FIXME{Can there be a pagebreak in a table?}
|
||||
|
||||
\begin{table}
|
||||
\label{ftpd-commands}
|
||||
\begin{tabular}{|lp{10cm}|}
|
||||
\hline
|
||||
\ex{ABOR} & abort connection \\
|
||||
\ex{CDUP} & move to parent directory \\
|
||||
\ex{CWD} & move to specified directory (relative paths may be used) \\
|
||||
\ex{DELE} & delete file \\
|
||||
\ex{LIST} & list files in current directory (long format) \\
|
||||
\ex{MDTM} & deliver modification time of a regular file \\
|
||||
\ex{MKD} & make directory \\
|
||||
\ex{MODE} & change mode (only stream mode (S) is supported) \\
|
||||
\ex{NLST} & list files in current directory (short format) \\
|
||||
\ex{NOOP} & do nothing \\
|
||||
\ex{PASS} & read in passphrase (\ex{ftpd} currently does not support
|
||||
non-anonymous logins) \\
|
||||
\ex{PASV} & change to passive mode \\
|
||||
\ex{PORT} & change connection port \\
|
||||
\ex{PWD} & return name of working directory (print working directory) \\
|
||||
\ex{QUIT} & quit session \\
|
||||
\ex{RETR} & return file (GET) \\
|
||||
\ex{RMD} & remove directory \\
|
||||
\ex{RNFR} & read in the name of a file to be renamed (use \ex{RNTO} next) \\
|
||||
\ex{RNTO} & rename file mentioned before in a \ex{RNFR} command \\
|
||||
\ex{SIZE} & return size of a regular file \\
|
||||
\ex{STOR} & store file (PUT) \\
|
||||
\ex{STRU}& change structure to transfer files
|
||||
(only the file structure is supported) \\
|
||||
\ex{SYST} & return system type \\
|
||||
\ex{TYPE} & change type (supported types: A is ascii mode,
|
||||
I or L8 are 8-bit binary mode) \\
|
||||
\ex{USER} & login user (only anonymous logins allowed,
|
||||
use ``anonymous'' or ``ftp'' as user name) \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{Supported RFC~959 commands by the server.}
|
||||
\end{table}
|
||||
|
||||
|
||||
%\subsection{What programmers want to know}
|
||||
|
||||
%Let me know what you want to know. As long as you are waiting for my
|
||||
%answer, have a look in the source file (I'm sorry).
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
|
@ -0,0 +1,8 @@
|
|||
\section{HTTP server}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] ftpd.scm
|
||||
\item[Name of the package:] ftpd
|
||||
\end{description}
|
||||
%
|
||||
Not documented yet.
|
|
@ -0,0 +1,133 @@
|
|||
\section{Overview}
|
||||
\subsection{What's in sunet?}
|
||||
|
||||
The Scheme Underground Network Package contains a set of libraries for
|
||||
doing Net hacking from Scheme/scsh. It includes:
|
||||
|
||||
\begin{description}
|
||||
\item{An smtp client library.}\\
|
||||
Forge mail from the comfort of your own Scheme process.
|
||||
|
||||
\item{rfc822 header library}\\
|
||||
Read email-style headers. Useful in several contexts (smtp, http,
|
||||
etc.)
|
||||
|
||||
\item{Simple structured HTML output library} \\
|
||||
Balanced delimiters, etc.
|
||||
|
||||
\item{The SU Web server}\\
|
||||
This is a complete implementation of an HTTP 1.0 server in Scheme.
|
||||
The server contains other standalone packages that may separately be
|
||||
of use:
|
||||
\begin{itemize}
|
||||
\item URI and URL parsers and unparsers.
|
||||
\item A library to help writing CGI scripts in Scheme.
|
||||
\item Server extensions for interfacing to CGI scripts.
|
||||
\item Server extensions for uploading Scheme code.
|
||||
\end{itemize}
|
||||
|
||||
The server has three main design goals:
|
||||
\begin{description}
|
||||
\item{Extensibility}\\
|
||||
The server is in fact nothing but extensions, using a mechanism
|
||||
called ``path handlers'' to define URL-specific services. It has a
|
||||
toolkit of services that can be used as-is, extended or built
|
||||
upon. User extensions have exactly the same status as the base
|
||||
services.
|
||||
|
||||
The extension mechanism allows for easy implementation of new
|
||||
services without the overhead of the CGI interface. Since the
|
||||
server is written on top of the Scheme shell, the full set of Unix
|
||||
system calls and program tools is available to the implementor.
|
||||
|
||||
\item{Mobile code}\\
|
||||
The server allows Scheme code to be uploaded for direct execution
|
||||
inside the server. The server has complete control over the code,
|
||||
and can safely execute it in restricted environments that do not
|
||||
provide access to potentially dangerous primitives (such as the
|
||||
``delete file'' procedure.)
|
||||
|
||||
\item{Clarity}\\
|
||||
I\footnote{That's Olin Shivers (\ex{shivers@ai.mit.edu},
|
||||
\ex{http://www.\ob{}ai.\ob{}mit.\ob{}edu/\ob{}people/\ob{}shivers/}).
|
||||
For the rest of the documentation, if not mentioned otherwise,
|
||||
`I' refers to him.} wrote this server to help myself understand
|
||||
the Web. It is voluminously commented, and I hope it will prove to
|
||||
be an aid in understanding the low-level details of the Web
|
||||
protocols.
|
||||
|
||||
The S.U. server has the ability to upload code from Web clients
|
||||
and execute that code on behalf of the client in a protected
|
||||
environment.
|
||||
|
||||
Some simple documentation on the server is available.
|
||||
\end{description}
|
||||
\end{description}
|
||||
|
||||
|
||||
\subsection{Obtaining the system}
|
||||
|
||||
The network code is available by
|
||||
ftp\footnote{\ex{ftp://ftp-swiss.ai.mit.edu/pub/scsh/contrib/net/net.tar.gz}}.
|
||||
To run the server, you need our 0.6 release of
|
||||
scsh\footnote{http://www.scsh.net}. Beyond actually running the
|
||||
server, the separate parser libraries and other utilites may be of use
|
||||
as separate modules.
|
||||
|
||||
The sunet package contains following parts:
|
||||
%
|
||||
\begin{itemize}
|
||||
\item Several servers (HTTP, CGI, FTP)
|
||||
\item Several clients (to FTP, SMTP, POP3, NTP)
|
||||
\item procedures to handle URIs
|
||||
\item procedures to handle RFC822 headers
|
||||
\item analogue of \verb|ls| for scsh
|
||||
\item {\dots}
|
||||
\end{itemize}
|
||||
|
||||
\subsection{What is in this docu?}
|
||||
%
|
||||
Unfortunately not all parts of sunet are documented here. If you miss
|
||||
something, have a look in the source files -- they are alle well
|
||||
documented (I hope so!).
|
||||
|
||||
Currently the ftp server, the ftp client, the modules containing the
|
||||
procedures handling URIs and URLs, the module handling RFC~822
|
||||
headers, the netrc package, the save evaluation environment
|
||||
\ex{toothless\=eval} and the obsolete library for using strings are
|
||||
documented.
|
||||
|
||||
\subsection{How to use the modules}
|
||||
%
|
||||
% I think it is a good idea to tell the people how to use
|
||||
% scsh / sunet as the docu of scsh does not really do this
|
||||
% (as long as concerning my experience). Additionally, possible
|
||||
% programmers should be introduced how to create own modules,
|
||||
% including those in sunet.
|
||||
%FIXME
|
||||
\FIXME{Does anybody have a good idea how to tell newbies how to use
|
||||
the packages? I do not feel capable enough for this.}
|
||||
|
||||
For the time being, it may help to look at the following. Scsh is started
|
||||
in the sunet directory. Then, the description file of the modules is
|
||||
loaded and the ftp-module is opened (to use a ftp client). After the
|
||||
things are done, scsh is finished via the \verb|,exit| command.
|
||||
\begin{code}
|
||||
atari-2600[72] scsh-0.6
|
||||
Welcome to scsh 0.6.0 (Chinese Democracy)
|
||||
Type ,? for help.
|
||||
> ,config ,load modules.scm
|
||||
modules.scm
|
||||
> ,open ftp
|
||||
Load structure ftp (y/n)? y
|
||||
[ecm-utilities ecm-utilities.scm]
|
||||
[netrc netrc.scm]
|
||||
[ftp ftp.scm]
|
||||
> ; do something nasty
|
||||
> ,exit
|
||||
atari-2600[73]\end{code}
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,34 @@
|
|||
\documentclass[11pt]{article}
|
||||
\usepackage[latin1]{inputenc}
|
||||
\usepackage{code}
|
||||
\date{28. Januar 2002}
|
||||
\author{composed by Andreas Bernauer\footnote{\texttt{bernauer@informatik.uni-tuebingen.de}}}
|
||||
\title{Documentation of the sunet-package}
|
||||
|
||||
\input{decls}
|
||||
|
||||
\begin{document}
|
||||
\maketitle
|
||||
\begin{abstract}
|
||||
This document contains informations for users and programmers using
|
||||
the sunet package.
|
||||
\end{abstract}
|
||||
\tableofcontents
|
||||
|
||||
\include{intro}
|
||||
\include{httpd}
|
||||
\include{cgi-server}
|
||||
\include{cgi-script}
|
||||
\include{ftpd}
|
||||
\include{ftp}
|
||||
\include{netrc}
|
||||
\include{uri}
|
||||
\include{url}
|
||||
\include{rfc822}
|
||||
\include{ntp}
|
||||
\include{smtp}
|
||||
\include{pop3}
|
||||
\include{stringhax}
|
||||
\include{toothless}
|
||||
\FIXME{Is there a possibility to get rid of the overfull \\hboxes?}
|
||||
\end{document}
|
|
@ -0,0 +1,142 @@
|
|||
\section{Reading netrc-files}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] netrc.scm
|
||||
\item[Name of the package:] netrc
|
||||
\end{description}
|
||||
%
|
||||
\subsection{Overview}
|
||||
This module provides procedures to parse authentication information
|
||||
contained in \ex{~/.netrc}.
|
||||
|
||||
On Unix systems the \ex{~/.netrc} file (in the user's home directory)
|
||||
may contain information allowing automatic login to remote hosts. The
|
||||
format of the file is defined in the \ex{ftp}(1) manual page. Example
|
||||
lines are
|
||||
\begin{code}
|
||||
machine ondine.cict.fr login marsden password secret
|
||||
default login anonymous password user@site
|
||||
\end{code}
|
||||
|
||||
The \ex{~/.netrc} file should be protected by appropriate permissions, and
|
||||
(like \ex{/usr/bin/ftp}) this library will refuse to read the file if it is
|
||||
badly protected. (unlike \ex{ftp} this library will always refuse
|
||||
to read the file -- \ex{ftp} refuses it only if the password is
|
||||
given for a non-default account). Appropriate permissions are set if
|
||||
only the user has permissions on the file.
|
||||
|
||||
Note following restrictions and differences:
|
||||
\begin{itemize}
|
||||
\item The macdef statement (defining macros) is not supported.
|
||||
\item The settings for one machine must be on a single line.
|
||||
\item The is no error proof while reading the file.
|
||||
\item Default need not be the last line of the netrc-file.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\subsection{Entry points}
|
||||
|
||||
What you probably want, is to read out the default netrc-file. Do the
|
||||
following:
|
||||
\begin{code}
|
||||
(let ((netrc-record (netrc:parse)))
|
||||
(netrc:lookup netrc-record "name of the machine"))
|
||||
\end{code}
|
||||
|
||||
and you will receive three values: \semvar{login-name},
|
||||
\semvar{password} and \semvar{account-name}. If you only want the
|
||||
login name or the password, use \ex{netrc:\ob{}lookup\=login} or
|
||||
\ex{netrc:\ob{}lookup\=password}, resp.
|
||||
|
||||
You will get either the login / password for the specified machine, or
|
||||
a default login / password if the machine is unknown.
|
||||
|
||||
|
||||
\begin{defundesc}{user-mail-address}{}{string}
|
||||
Calculate the user's email address, as per the Emacs function of the
|
||||
same name. Will take into account the environment variable
|
||||
\ex{REPLYTO}, if set. Otherwise the mail-address will look like
|
||||
\ex{user@\ob{}hostname}.
|
||||
\end{defundesc}
|
||||
|
||||
\defun{netrc:parse} {\ovar{filename \ovar{fallback-password
|
||||
\ovar{fallback-login}}}} {netrc-record}
|
||||
\begin{defundescx}{netrc:try-parse} {filename fallback-password
|
||||
fallback-login} {netrc-record}
|
||||
|
||||
\ex{netrc:parse} parses the netrc file and returns a \ex{netrc}
|
||||
record, containing all necessary information for the following
|
||||
procedures.
|
||||
|
||||
\semvar{filename} defaults to ``~/.netrc'',
|
||||
\semvar{fallback-password} defaults to the result of the call to
|
||||
\ex{user\=mail\=address} and \semvar{fallback-login} defaults to
|
||||
``anonymous''. If the netrc file does not provide a default password
|
||||
or a default login (stated by the ``default'' statement),
|
||||
\semvar{fallback-password} and \semvar{fallback-login} will be used
|
||||
as default password or login, respectively (thus,
|
||||
\ex{user\=mail\=address} is only called if the netrc file does not
|
||||
contain a default specification). If the netrc file does not exist,
|
||||
a netrc-record filled with default values is returned. If the netrc
|
||||
file does not have the correct permissions, a message is printed to
|
||||
the current error port and a netrc-record filled with default values
|
||||
is returned.
|
||||
|
||||
\ex{netrc:try-parse} does the same as \ex{netrc:\ob{}parse}, except
|
||||
of the following: if there is no file called \semvar{filename}, the
|
||||
according error will be raised and if the specified file does not
|
||||
have the correct permissions set, a \ex{netrc\=refuse\=warning} will
|
||||
be signalled. So, if you don't like the error handling and behavior
|
||||
of \ex{netrc:\ob{}parse}, use \ex{netrc:\ob{}try\=parse} and catch
|
||||
the signalled conditions. Note, that \ex{netrc:\ob{}parse} resolves
|
||||
\semvar{filename} for you, \ex{netrc:\ob{}try-parse} does not -- you
|
||||
have to do it on your own.
|
||||
\end{defundescx}
|
||||
|
||||
\defun{netrc:lookup}{netrc-record machine \ovar{default?}} {string
|
||||
string string}
|
||||
\defunx{netrc:lookup-password}{netrc-record machine
|
||||
\ovar{default?}}{string}
|
||||
\defunx{netrc:lookup-login}{netrc-record machine
|
||||
\ovar{default?}}{string}
|
||||
\begin{defundescx}
|
||||
Return the login, password and / or account information for
|
||||
\semvar{machine} specified by \semvar{netrc-record}, respectively.
|
||||
If \semvar{default?} is \sharpt, default values are returned if no
|
||||
such \semvar{machine} is specified in the \semvar{netrc-record}.
|
||||
Otherwise [\sharpf\ \sharpf\ \sharpf] or \sharpf\ is returned,
|
||||
respectively.
|
||||
\end{defundescx}
|
||||
|
||||
\defun{netrc:default-login}{netrc-record}{string}
|
||||
\begin{defundescx}{netrc:default-password}{netrc-record}{string}
|
||||
Return the default values for the login or the password, respectively,
|
||||
specified by \semvar{netrc-record}. If the netrc file did not
|
||||
specify a default login, ``anonymous'' is returned by
|
||||
\ex{netrc:\ob{}default\=login}. If the netrc file did not specify a
|
||||
default password, the result of the call to \ex{user\=mail\=address}
|
||||
is returned by \ex{netrc:\ob{}default\=password}.
|
||||
\end{defundescx}
|
||||
|
||||
\subsection{Related work}
|
||||
\begin{itemize}
|
||||
\item Graham Barr has written a similar library for Perl, called
|
||||
\ex{Netrc.pm}.
|
||||
\item \ex{ange-ftp.el} (transparent remote file access for Emacs)
|
||||
parses the user's netrc file.
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Desirable things}
|
||||
\begin{itemize}
|
||||
\item Remove restrictions (as stated in `\emph{Overview}') and behave like
|
||||
\ex{/usr/\ob{}bin/\ob{}ftp} behaves
|
||||
\item perhaps: adding case-insensitivity (for host names)
|
||||
\item perhaps: better record-disclosers for netrc-entry- and
|
||||
netrc-records
|
||||
\end{itemize}
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
|
@ -0,0 +1,8 @@
|
|||
\section{Using NTP}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] nettime.scm
|
||||
\item[Name of the package:] nettime
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,8 @@
|
|||
\section{Using POP3}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] pop3.scm
|
||||
\item[Name of the package:] pop3
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,170 @@
|
|||
\section{Handle RFC822 headers}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] rfc822.scm
|
||||
\item[Name of the package:] rfc822
|
||||
\end{description}
|
||||
%
|
||||
\subsection{What users want to know}
|
||||
|
||||
\subsubsection*{A note on line-terminators}
|
||||
Line-terminating sequences are always a drag, because there's no
|
||||
agreement on them -- the Net protocols and DOS use
|
||||
carriage-return/line-feed (\ex{cr}/\ex{lf}); Unix uses \ex{lf}; the
|
||||
Mac uses \ex{cr}. One one hand, you'd like to use the code for all of
|
||||
the above, on the other, you'd also like to use the code for strict
|
||||
applications that need definitely not to recognise bare \ex{cr}'s or
|
||||
\ex{lf}'s as terminators.
|
||||
|
||||
RFC 822 requires a \ex{cr}/\ex{lf} (carriage-return/line-feed) pair to
|
||||
terminate lines of text. On the other hand, careful perusal of the
|
||||
text shows up some ambiguities (there are maybe three or four of
|
||||
these, and I'm too lazy to write them all down). Furthermore, it is an
|
||||
unfortunate fact that many Unix apps separate lines of RFC~822 text
|
||||
with simple linefeeds (e.g., messages kept in \ex{/usr/spool/mail}).
|
||||
As a result, this code takes a broad-minded view of line-terminators:
|
||||
lines can be terminated by either \ex{cr}/\ex{lf} or just \ex{lf}, and
|
||||
either terminating sequence is trimmed.
|
||||
|
||||
If you need stricter parsing, you can call the lower-level procedure
|
||||
\ex{\%read\=rfc822\=field} and \ex{\%read\=rfc822\=headers}. They take
|
||||
the read-line procedure as an extra parameter. This means that you can
|
||||
pass in a procedure that recognises only \ex{cr}/\ex{lf}'s, or only
|
||||
\ex{cr}'s (for a Mac app, perhaps), and you can determine whether or
|
||||
not the terminators get trimmed. However, your read-line procedure
|
||||
must indicate the header-terminating empty line by returning \emph{either}
|
||||
the empty string or the two-char string \ex{cr}/\ex{lf} (or the EOF object).
|
||||
|
||||
\subsubsection*{Description of the procedures}
|
||||
|
||||
\defun{read-rfc822-field} {\ovar{port}} {name body}
|
||||
\begin{defundescx}{\%read-rfc822-field } {read-line port} {name body}
|
||||
|
||||
Read one field from the port, and return two values:
|
||||
|
||||
\begin{description}
|
||||
\item{\var{name}} Symbol such as \ex{'subject} or \ex{'to}. The
|
||||
field name is converted to a symbol using the Scheme
|
||||
implementation's preferred case. If the implementation reads
|
||||
symbols in a case-sensitive fashion (e.g., scsh), lowercase is
|
||||
used. This means you can compare these symbols to quoted constants
|
||||
using \ex{eq?}. When printing these field names out, it looks best
|
||||
if you capitalize them with \ex{(capitalize\=string (symbol->string field\=name))}.
|
||||
|
||||
\item{var{body}} List of strings which are the field's body, e.g.
|
||||
(``shivers\discretionary{@}{}{@}lcs.mit.edu''). Each list element is one line from
|
||||
the field's body, so if the field spreads out over three lines,
|
||||
then the body is a list of three strings. The terminating
|
||||
\ex{cr}/\ex{lf}'s are trimmed from each string. A leading space or
|
||||
a leading horizontal tab is also trimmed, but one and onyl one.
|
||||
\end{description}
|
||||
|
||||
When there are no more fields -- EOF or a blank line has terminated
|
||||
the header section -- then the procedure returns [\sharpf\ \sharpf].
|
||||
|
||||
The \ex{\%read-rfc822-field} variant allows you to specify your own
|
||||
read-line procedure. The one used by \ex{read-rfc822-field}
|
||||
terminates lines with either \ex{cr}/\ex{lf} or just \ex{lf}, and it
|
||||
trims the terminator from the line. Your read-line procedure should
|
||||
trim the terminator of the line, so an empty line is returned as an
|
||||
empty string.
|
||||
|
||||
The procedures raise an error if the syntax of the read field (the
|
||||
line returned by the read-line-function) is illegal (regarding
|
||||
RFC~822).
|
||||
\end{defundescx}
|
||||
|
||||
\defun{read-rfc822-headers} {\ovar{port}} {association list}
|
||||
\begin{defundescx}{\%read-rfc822-headers} {read-line port}
|
||||
{association list}
|
||||
|
||||
Read in and parse up a section of text that looks like the header
|
||||
portion of an RFC~822 message. Return an association list mapping a
|
||||
field name (a symbol such as 'date or 'subject) to a list of field
|
||||
bodies -- one for each occurence of the field in the header. So if
|
||||
there are five ``Received-by:'' fields in the header, the alist maps
|
||||
'received-by to a five element list. Each body is in turn
|
||||
represented by a list of strings -- one for each line of the field.
|
||||
So a field spread across three lines would produce a three element
|
||||
body.
|
||||
|
||||
The \ex{\%read-rfc822-headers} variant allows you to specify your
|
||||
own read-line procedure. See \emph{A note on line-terminators} above
|
||||
for reasons why.
|
||||
|
||||
Hint: If you want to get familiar with these procedures, you might
|
||||
find \ex{make\=string\=input\=port}, that makes a port out of a
|
||||
string, helpful.
|
||||
\end{defundescx}
|
||||
|
||||
\begin{defundesc}{rejoin-header-lines} {alist \ovar{seperator}}
|
||||
{association list}
|
||||
|
||||
Takes a field \var{alist} such as is returned by
|
||||
\ex{read-rfc822-headers} and returns an equivalent association list.
|
||||
Each body (\str list) in the input \var{alist} is joined into a
|
||||
single list in the output alist. \var{separator} is the string used
|
||||
to join these elements together; it defaults to a single space, but
|
||||
can usefully be ``\verb|\n|'' (linefeed) or ``\verb|\r\n|''
|
||||
(carriage-return/line-feed).
|
||||
|
||||
To rejoin a single body list, use scsh's \ex{join-strings}
|
||||
procedure.
|
||||
\end{defundesc}
|
||||
|
||||
For the following definitions' examples, let's use this set of of
|
||||
RFC~822 headers:
|
||||
\begin{code}
|
||||
From: shivers
|
||||
To: ziggy,
|
||||
newts
|
||||
To: gjs, tk\end{code}
|
||||
%
|
||||
|
||||
\begin{defundesc}{get-header-all} {headers name} {string list list}
|
||||
Returns all entries or \sharpf, e.g.\
|
||||
\codex{(get-header-all hdrs 'to)}
|
||||
results to
|
||||
\codex{'((" ziggy," " newts") (" gjs, tk"))}
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{get-header-lines} {headers name} {string list}
|
||||
Returns all lines of the first entry or \sharpf, e.g.\
|
||||
\codex{(get-header-lines hdrs 'to)}
|
||||
results to
|
||||
\codex{'(" ziggy," " newts")}
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{get-headers} {headers name \ovar{seperator}} {string}
|
||||
Returns the first entry with the lines joined together by seperator
|
||||
(newline by default), e.g.\
|
||||
\codex{(get-header hdrs 'to)}
|
||||
results to
|
||||
\begin{code}
|
||||
" ziggy,
|
||||
newts"\end{code}
|
||||
%
|
||||
Note, that \ex{newts} is led by two spaces.
|
||||
\end{defundesc}
|
||||
|
||||
|
||||
\begin{defundesc}{string->symbol-pref}{string}{symbol}
|
||||
Takes a \string and converts it to a symbol using the Scheme
|
||||
implementation's preferred case. (The preferred case is recognized by
|
||||
a doing once a \ex{symbol->string} conversion of \ex{'a}.)
|
||||
\end{defundesc}
|
||||
|
||||
\subsubsection*{Desireable functionalities}
|
||||
|
||||
\begin{itemize}
|
||||
\item Unfolding long lines.
|
||||
\item Lexing structured fields.
|
||||
\item Unlexing structured fields into canonical form.
|
||||
\item Parsing and unparsing dates.
|
||||
\item Parsing and unparsing addresses.
|
||||
\end{itemize}
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
|
@ -0,0 +1,8 @@
|
|||
\section{Section-Title}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:]
|
||||
\item[Name of the package:]
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,8 @@
|
|||
\section{Using SMTP}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] smtp.scm
|
||||
\item[Name of the package:] smtp
|
||||
\end{description}
|
||||
%
|
||||
Not implemented yet.
|
|
@ -0,0 +1,79 @@
|
|||
\section{Manipulating strings}
|
||||
|
||||
|
||||
\begin{description}
|
||||
\item[Used files:] stringhax.scm
|
||||
\item[Name of the package:] strings
|
||||
\end{description}
|
||||
|
||||
|
||||
\subsection*{Overview}
|
||||
|
||||
This module provides several procedures to manipulate strings.
|
||||
|
||||
\begin{defundesc}{string-map} {procedure string} {string}
|
||||
Does a map on each character of \semvar{string} and returns the
|
||||
result, a newly allocated string. \semvar{procedure} takes a
|
||||
character and should return a character.
|
||||
\end{defundesc}
|
||||
|
||||
\defun{downcase-string} {string} {string}
|
||||
\begin{defundescx}{upcase-string} {string} {string}
|
||||
Do what you expect: convert \semvar{string} to downcase or upcase
|
||||
using char-downcase or char-upcase, respectively. The result is a
|
||||
newly allocated string.
|
||||
\end{defundescx}
|
||||
|
||||
\defun{char-set-index} {string char-set \ovar{start}} {number}
|
||||
\begin{defundescx}{char-set-rindex} {string char-set \ovar{start}} {number}
|
||||
Returns the index of the first character that is in
|
||||
\semvar{char\=set}. \ex{char\=set\=index} searches from left to
|
||||
right, \ex{char\=set\=rindex} from right to left. \semvar{start} is
|
||||
the index from where to start from and defaults to 0 in
|
||||
\ex{char\=set\=index} and \ex{(string-length \semvar{string})} in
|
||||
\ex{char\=set\=rindex}. If the search fails, \sharpf{} is returned.
|
||||
\end{defundescx}
|
||||
|
||||
\begin{defundesc}{string-reduce} {default construct string} {string}
|
||||
Does a ``fold-right'' on \semvar{string}. It applies
|
||||
\semvar{construct} on every character of \semvar{string}.
|
||||
\semvar{construct} is initially invoked with the last character of
|
||||
string and \semvar{default}. In subsequent invocations, the last
|
||||
argument is the return value from the previous invocation of
|
||||
\semvar{construct} while the first argument is the character of
|
||||
\semvar{string} leading the previous used character. So, the string
|
||||
is traversed from right to left. The result of the application of
|
||||
\semvar{string-reduce} is the result of the last application of
|
||||
\semvar{construct}.
|
||||
|
||||
Example:
|
||||
\begin{code}
|
||||
(string-reduce
|
||||
""
|
||||
(lambda (char str)
|
||||
(string-append str (string (char-downcase char))))
|
||||
"DOWNCASE")\end{code}
|
||||
|
||||
results to ``downcase''.
|
||||
\end{defundesc}
|
||||
|
||||
\defun{string-prefix?} {prefix string} {boolean}
|
||||
\begin{defundescx}{string-suffix?} {suffix string} {boolean}
|
||||
Return \sharpt{} if \semvar{prefix}/\semvar{suffix} is a real
|
||||
\semvar{prefix}/\semvar{suffix} of \semvar{string}, otherwise return
|
||||
\sharpf. Real prefix/suffix means that \semvar{string} may not be a
|
||||
prefix/suffix of \semvar{prefix}/\semvar{suffix} (in other words:
|
||||
\semvar{prefix} and \semvar{suffix} have to be real shorter than
|
||||
\semvar{string} to be a real prefix or suffix.
|
||||
\end{defundescx}
|
||||
|
||||
\begin{defundesc}{skip-whitespace} {string} {number}
|
||||
Returns the index of the first character in \semvar{string} that is
|
||||
not a whitespace (as defined in \ex{char-set:whitespace}). If there
|
||||
isn't such a character, \sharpf{} is returned.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{trim-spaces} {string} {string}
|
||||
Returns a newly allocated string being \semvar{string} without
|
||||
leading or trailing spaces (not whitespaces!).
|
||||
\end{defundesc}
|
|
@ -0,0 +1,57 @@
|
|||
\section{Evaluating expression in ``safe'' environments}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] none, defined in modules.scm
|
||||
\item[Name of the package:] loser, toothless, toothless-eval \\
|
||||
(you want the last one)
|
||||
\end{description}
|
||||
%
|
||||
|
||||
\subsection{Overview}
|
||||
\FIXME{Is toothless really R5RS, too?}
|
||||
These modules define an environment that is \RnRS without features that
|
||||
could examine or effect the file system. You can also use it as a
|
||||
model of how to execute code in other protected environments in \scm.
|
||||
|
||||
\subsection{The \protect{\texttt{loser}} package}
|
||||
The \ex{loser} package exports only one procedure:
|
||||
|
||||
\begin{defundesc}{loser}{name}{nothing}
|
||||
Raises an error like ``Illegal call \var{name}''.
|
||||
\end{defundesc}
|
||||
|
||||
\subsection{The \protect{\texttt{toothless}} package}
|
||||
The \ex{toothless} package contains everything of \RnRS except
|
||||
that following procedure cause an error if called:
|
||||
\begin{itemize}
|
||||
\item \ex{call-with-input-file}
|
||||
\item \ex{call-with-output-file}
|
||||
\item \ex{load}
|
||||
\item \ex{open-input-file}
|
||||
\item \ex{open-output-file}
|
||||
\item \ex{transcript-on}
|
||||
\item \ex{with-input-from-file}
|
||||
\item \ex{with-input-to-file}
|
||||
\item \ex{eval}
|
||||
\item \ex{interaction-environment}
|
||||
\item \ex{scheme-report-environment}
|
||||
\end{itemize}
|
||||
|
||||
So, \ex{toothless} creates an environment as described in
|
||||
\emph{Overview} above.
|
||||
|
||||
\subsection{The \protect{\texttt{toothless-eval}} package}
|
||||
|
||||
\begin{defundesc}{eval-safely} {expression} {any result}
|
||||
Creates a brand new package, imports the \ex{toothless} structure,
|
||||
and evaluates \semvar{expression} in it. When the evaluation is
|
||||
done, the environment is thrown away, so \semvar{expression}'s
|
||||
side-effects don't persist from one \ex{eval\=safely} call to the
|
||||
next. If \semvar{expression} raises an error exception, we abort and
|
||||
return \sharpf.
|
||||
\end{defundesc}
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
|
@ -0,0 +1,222 @@
|
|||
\section{Handle URIs}\label{sec:uri}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] uri.scm
|
||||
\item[Name of the package:] uri
|
||||
\end{description}
|
||||
%
|
||||
|
||||
\subsection{Overview}
|
||||
A URI (Uniform Resource Identifier) is of following syntax:
|
||||
\begin{inset}
|
||||
\ovar{scheme\/} : \semvar{path} \ovar{{\normalfont?\/} search} \ovar{{\normalfont\#} fragmentid}
|
||||
\end{inset}
|
||||
Parts in brackets may be ommitted. The last part is usually referred
|
||||
to as fragid in this document.
|
||||
|
||||
As you see, the URI contains characters like \verb|:| to indicate its
|
||||
different parts. But what, if the \semvar{scheme} contains \verb|:| as
|
||||
part of its name? For this purpose, some special characters are
|
||||
\emph{escaped} if they are a regular part of a name and not indicators
|
||||
for the structure of a URI. Escape-sequences are of following scheme:
|
||||
\verb|\%hh| where \verb|h| is a hexadecimal digit. The hexadecimal
|
||||
number refers to the (US) ASCII code of the escaped character, e.g.\
|
||||
\ex{\%20} is space (ASCII character 32) and \ex{\%61} is `a' (ASCII
|
||||
character 97). This module provides procedures to escape and unescape
|
||||
strings that are meant to be used in a URI.
|
||||
|
||||
\subsection{Procedures}
|
||||
|
||||
\begin{defundesc}{parse-uri} {uri-string } {scheme path search
|
||||
frag-id} \label{proc:parse-uri}
|
||||
|
||||
Parses an \semvar{uri\=string} in the possible four fields, as
|
||||
mentioned above in \emph{Overview}. These four fields are returned
|
||||
as a multiple value. They are \emph{not} unescaped, as the rules for
|
||||
parsing the \semvar{path} component in particular need unescaped
|
||||
text, and are dependent on \semvar{scheme}. The URL parser is
|
||||
responsible for doing this. If the \semvar{scheme}, \semvar{search}\
|
||||
or \semvar{fragid} portions are not specified, they are \sharpf.
|
||||
Otherwise, \semvar{scheme}, \semvar{search}, and \semvar{fragid} are
|
||||
strings. \semvar{path} is a non-empty string list -- the path split
|
||||
at slashes.
|
||||
|
||||
For those of you who are interested, here is a description of the
|
||||
parsing technique. It is inwards from both ends.
|
||||
\begin{itemize}
|
||||
\item First we search forwards for the first reserved character
|
||||
(\verb|=|, \verb|;|, \verb|/|, \verb|#|, \verb|?|, \verb|:| or
|
||||
\verb|space|). If it's a colon, then that's the \semvar{scheme}
|
||||
part, otherwise we have no \semvar{scheme} part. At all events we
|
||||
remove it.
|
||||
\item Then we search backwards from the end for the last reserved
|
||||
char. If it's a sharp, then that's the \semvar{fragid} part --
|
||||
remove it.
|
||||
\item Then we search backwards from the end for the last reserved
|
||||
char. If it's a question-mark, then that's the \semvar{search}
|
||||
part -- remove it.
|
||||
\item What's left is the path. We split at slashes. The empty string
|
||||
becomes a list containing the empty string.
|
||||
\end{itemize}
|
||||
|
||||
This scheme is tolerant of the various ways people build broken
|
||||
URI's out there on the Net\footnote{So it is not absolutely conform
|
||||
with RFC~1630}, e.g. \verb|=| is a reserved character, but used
|
||||
unescaped in the search-part. It was given to me\footnote{That's
|
||||
Olin Shivers.} by Dan Connolly of the W3C and slightly modified.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{unescape-uri} {string \ovar{start \ovar{end}}} {string}
|
||||
Unescapes a string. This procedure should only be used \emph{after}
|
||||
the URL (!) was parsed, since unescaping may introduce characters
|
||||
that blow up the parse (that's why escape sequences are used in URIs
|
||||
;-). Escape sequences are of the scheme as described in ``Overview''.
|
||||
\end{defundesc}
|
||||
|
||||
|
||||
%\texttt{uri-escaped-chars} \hfill
|
||||
%\texttt{char-set}\index{\texttt{uri-escaped-chars}}
|
||||
\defvar{uri-escaped-chars}{char-set}
|
||||
\begin{desc}
|
||||
A set of characters that are escaped in URIs. These are the
|
||||
following characters: dollar (\verb|$|), minus (\verb|-|),%fool Xemacs$
|
||||
underscore (\verb|_|), at (\verb|@|), dot (\verb|.|), and-sign
|
||||
(\verb|&|), exclamation mark (\verb|!|), asterisk (\verb|*|),
|
||||
backslash (\verb|\|), double quote (\verb|"|), single quote
|
||||
(\verb|'|), open brace (\verb|(|), close brace (\verb|)|), comma
|
||||
(\verb|,|) plus (\verb|+|) and all other characters that are neither
|
||||
letters nor digits (such as space and control characters).
|
||||
\end{desc}
|
||||
|
||||
\begin{defundesc}{escape-uri} {string \ovar{escaped-chars}} {string}
|
||||
Escapes characters of \semvar{string} that are given with
|
||||
\semvar{escaped\=chars}. \semvar{escaped\=chars} default to
|
||||
\ex{uri\=escaped\=chars}. Be careful with using this procedure to
|
||||
chunks of text with syntactically meaningful reserved characters
|
||||
(e.g., paths with URI slashes or colons) -- they'll be escaped, and
|
||||
lose their special meaning. E.g.\ it would be a mistake to apply
|
||||
\ex{escape-uri} to
|
||||
``\ex{//lcs.\ob{}mit.\ob{}edu:8001\ob/foo\ob/bar.html}'' because the
|
||||
sla\-shes and co\-lons would be escaped. Note that \ex{esacpe-uri}
|
||||
doesn't check this as it would lose his meaning.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{resolve-uri} {cscheme cp scheme p} {scheme path}
|
||||
\FIXME{Sorry, I can't figure out what resolve-uri is inteded to do.
|
||||
Perhaps I find it out later.}
|
||||
|
||||
Nobody really knows what this procedure was intended to do.
|
||||
|
||||
The code seems to have a bug: In the body of receive, there's a
|
||||
loop. j should, according to the comment, count sequential \verb|/|.
|
||||
But \ex{j} counts nothing in the body. Either zero is added \ex{((lp
|
||||
(cdr cp-tail) (cons (car cp-tail) rhead) (+ j 0)))} or \ex{j} is
|
||||
set to 1 \ex{((lp (cdr cp-tail) (cons (car cp-tail) rhead) 1))}.
|
||||
Nevertheless, \ex{j} is expected to reach value \ex{numsl} that can
|
||||
be larger than one. So what? I am confused.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{split-uri-path} {uri start end} {list}
|
||||
Splits uri at slashes. Only the substring given with \semvar{start}
|
||||
(inclusive) and \semvar{end} (exclusive) as indices is considered.
|
||||
\semvar{start} and $\semvar{end} - 1$ have to be within the range of
|
||||
\semvar{uri}. Otherwise an index-out-of-range exception will be
|
||||
raised. Example: \codex{(split-uri-path "foo/bar/colon" 4 11)}
|
||||
results to \codex{'("bar" "col")}
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{uri-path-list->path} {plist} {string}
|
||||
Generates a path out of an uri-path-list by inserting slashes
|
||||
between the elements of \semvar{plist}. If you want to use the
|
||||
resulting string for further operation, you should escape the
|
||||
elements of \semvar{plist} in case the contain slashes. This doesn't
|
||||
escape them for you, you must do that yourself like
|
||||
\ex{(uri-path-list->path (map escape-uri pathlist))}.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{simplify-uri-path} {path} {list}
|
||||
Removes `\ex{.}' and `\ex{..}' entries from path. The result is
|
||||
a (maybe empty) list representing a path that does not contain any
|
||||
`\ex{.}' or `\ex{..}'\,. The list can only be empty if the path
|
||||
did not start with a slash (for the rare occasion someone wants to
|
||||
simplify a relative path). The result is \sharpf{} if the path tries
|
||||
to back up past root, for example by `\ex{/..}' or
|
||||
`\ex{/foo\ob/..\ob/..}' or just `\ex{..}'\,. `\ex{//}' may occur
|
||||
somewhere in the path referring to root but not being backed up.
|
||||
Examples:
|
||||
%FIXME: Can't we have a better environment for examples like these?
|
||||
\begin{code}
|
||||
(simplify-uri-path
|
||||
(split-uri-path "/foo/bar/baz/.." 0 15))\end{code}
|
||||
results to
|
||||
\codex{'("" "foo" "bar")}
|
||||
|
||||
\begin{code}
|
||||
(simplify-uri-path
|
||||
(split-uri-path "foo/bar/baz/../../.." 0 20))\end{code}
|
||||
results to
|
||||
\codex{'()}
|
||||
|
||||
\begin{code}
|
||||
(simplify-uri-path
|
||||
(split-uri-path "/foo/../.." 0 10))\end{code}
|
||||
results to
|
||||
\codex{\sharpf ; tried to back up root}
|
||||
|
||||
\begin{code}
|
||||
(simplify-uri-path
|
||||
(split-uri-path "foo/bar//" 0 9))\end{code}
|
||||
results to
|
||||
\codex{'("") ; "//" refers to root}
|
||||
|
||||
\begin{code}
|
||||
(simplify-uri-path
|
||||
(split-uri-path "foo/bar/" 0 8))\end{code}
|
||||
results to
|
||||
\codex{'("") ; last "/" also refers to root}
|
||||
|
||||
\begin{code}
|
||||
(simplify-uri-path
|
||||
(split-uri-path "/foo/bar//baz/../.." 0 19))\end{code}
|
||||
results to
|
||||
\codex{\sharpf ; tries to back up root}
|
||||
\end{defundesc}
|
||||
|
||||
\subsection*{Unexported names}
|
||||
|
||||
\defvar{uri-reserved}{char-set}
|
||||
\begin{desc}
|
||||
A list of reserved characters (semicolon, slash, hash, question
|
||||
mark, double colon and space).
|
||||
\end{desc}
|
||||
|
||||
\begin{defundesc}{hex-digit?} {character} {boolean}
|
||||
Returns \sharpt{} if character is a hexadecimal digit (i.e., one of 1--9,
|
||||
a--f, A--F), \sharpf{} otherwise.
|
||||
\end{defundesc}
|
||||
|
||||
|
||||
\begin{defundesc}{hexchar->int} {character} {number}
|
||||
Translates the given character to an integer, e.g. \ex{(hexchar->int
|
||||
\#a)} results to 10.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{int->hexchar} {integer} {character}
|
||||
Translates the given integer from range 1--15 into an hexadecimal
|
||||
character (uses uppercase letters), e.g. \ex{(int->hexchar 14)}
|
||||
results to `E'.
|
||||
\end{defundesc}
|
||||
|
||||
\begin{defundesc}{rev-append} {list-a list-b} {list}
|
||||
Performs a \ex{(append (reverse list-a) list-b)}. The comment says it
|
||||
should be defined in a list package but I am wondering how often
|
||||
this will be used.
|
||||
\end{defundesc}
|
||||
|
||||
%EOF
|
||||
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
|
@ -0,0 +1,116 @@
|
|||
\section{URL}
|
||||
%
|
||||
\begin{description}
|
||||
\item[Used files:] url.scm
|
||||
\item[Name of the package:] url
|
||||
\end{description}
|
||||
%
|
||||
\subsection{Overview}
|
||||
This modules contains procedures to parse and unparse URLs. Till now,
|
||||
only the parsing of http URLs is implemented.
|
||||
|
||||
\subsection{Entry points}
|
||||
\defun{make-userhost}{user password host port}{userhost-record}
|
||||
\defunx{userhost?}{thing}{boolean}
|
||||
\defunx{userhost:user}{userhost-record}{value}
|
||||
\defunx{userhost:password}{userhost-record}{value}
|
||||
\defunx{userhost:host}{userhost-record}{value}
|
||||
\defunx{userhost:port}{userhost-record}{value}
|
||||
\defunx{set-userhost:user}{userhost-record new-value}{void}
|
||||
\defunx{set-userhost:password}{userhost-record new-value}{void}
|
||||
\defunx{set-userhost:host}{userhost-record new-value}{void}
|
||||
\defunx{set-userhost:port}{userhost-record new-value}{void}
|
||||
\begin{desc}
|
||||
\ex{make\=userhost} creates a new \ex{userhost} record. This record
|
||||
describes path-prefixes of the form
|
||||
\semvar{user}:\semvar{password}@\semvar{host}:\semvar{port}. These
|
||||
are frequently used as the initial prefix of URL's describing
|
||||
Internet resources. Each slot is a decoded string or \sharpf (yes,
|
||||
\semvar{port} is also a string).
|
||||
|
||||
\ex{userhost?} is the corresponding predicate,
|
||||
\ex{userhost:\ob{}user}, \ex{userhost:\ob{}pass\ob{}word},
|
||||
\ex{userhost:\ob{}host} and \ex{userhost:\ob{}port} are the
|
||||
correspondig selectors and \ex{set\=userhost:\ob{}user},
|
||||
\ex{set\=userhost:\ob{}pass\ob{}word}, \ex{set\=userhost:\ob{}host}
|
||||
and \ex{set\=userhost:\ob{}port} the corresponding mutators. As you
|
||||
can store everything into the record fields, the selectors may
|
||||
return any type of value. However, under normal circumstances, only
|
||||
\str\ or \sharpf\ is returned.
|
||||
\end{desc}
|
||||
|
||||
\defun{parse-userhost}{path default}{userhost-record}
|
||||
\begin{defundescx}{userhost->string}{userhost-record}{string}
|
||||
\ex{parse\=userhost} parses a URI path (a list representing a path,
|
||||
not a string!) into a userhost record. Default values are taken from
|
||||
the userhost record \semvar{default} except for the host. The values
|
||||
are unescaped and stored into a userhost record that is returned.
|
||||
\ex{fatal\=syntax\=error} is called, if the specified path has no
|
||||
initial to slashes (i.e., it starts with `//\ldots').
|
||||
|
||||
\ex{userhost->string} just does the inverse job: it unparses
|
||||
\semvar{userhost-record} into a string. The elements of the record
|
||||
are escaped before the are put together.
|
||||
|
||||
For details about escaping and unescaping see section ``Handle
|
||||
URIs'' at page \pageref{sec:uri}.
|
||||
\end{defundescx}
|
||||
|
||||
|
||||
\defun{make-http-url}{userhost path search frag-id}{http-url-record}
|
||||
\defunx{http-url?}{thing}{boolean}
|
||||
\defunx{http-url:userhost}{http-url}{value}
|
||||
\defunx{http-url:path}{http-url}{value}
|
||||
\defunx{http-url:search}{http-url}{value}
|
||||
\defunx{http-url:frag-id}{http-url}{value}
|
||||
\defunx{set-http-url:userhost}{http-url new-value}{void}
|
||||
\defunx{set-http-url:path}{http-url new-value}{void}
|
||||
\defunx{set-http-url:search}{http-url new-value}{void}
|
||||
\defunx{set-http-url:frag-id}{http-url new-value}{void}
|
||||
\begin{desc}
|
||||
\ex{make\=http\=url} creates a new \ex{httpd\=url} record.
|
||||
\semvar{userhost} is a record, containing the initial part of the
|
||||
address (like
|
||||
\ex{ano\ob{}ny\ob{}mous@\ob{}clark.\ob{}lcs.\ob{}mit.\ob{}edu:\ob{}80}).
|
||||
\semvar{path} contains the URL's path split at slashes, e.g.\
|
||||
\ex{"foo/\ob{}bar/\ob{}baz/"} becomes \ex{'("foo" "bar" "baz" "")}.
|
||||
These elements are in raw, unescaped format. To convert them back to
|
||||
a string, use \ex{(uri\=path\=list->path (map escape\=uri
|
||||
pathlist))}. \semvar{search} and \semvar{frag\=id} are the last
|
||||
two parts of the URL (see section \ref{sec:uri} on page
|
||||
\pageref{sec:uri} about parts of an URI).
|
||||
|
||||
\ex{http\=url:userhost}, \ex{http\=url:path}, \ex{http\=url:search}
|
||||
and \ex{http\=url:frag\=id} are the corresponding selectors,
|
||||
\ex{set\=http\=url:userhost}, \ex{set\=http\=url:path},
|
||||
\ex{set\=http\=url:search} and \ex{set\=http\=url:frag\=id} the
|
||||
corresponding mutators. As you can store every type of value into
|
||||
the record fields, the selectors can return any type of value.
|
||||
However, \ex{http\=:userhost} usually returns a \ex{userhost}
|
||||
record, \ex{http\=:path} returns a list of \str{}s and
|
||||
\ex{http\=url:search} and \ex{http\=url:frag\=id} return both
|
||||
\str{}s.
|
||||
\end{desc}
|
||||
|
||||
\defun{parse-http-url}{path search frag-id}{http-url-record}
|
||||
\begin{defundescx}{http-url->string}{http-url-record}{string}
|
||||
The URI parser (\ex{parse\=uri} in \ex{uri.\ob{}scm}) maps a string
|
||||
to four parts: \semvar{scheme}, \semvar{path}, \semvar{search} and
|
||||
\semvar{frag-id} (see section \ref{proc:parse-uri} at page
|
||||
\pageref{proc:parse-uri} for details). If \semvar{scheme} is
|
||||
``http'', then the other three parts can be passed to
|
||||
\ex{parse\=http\=url}, which parses them into a \ex{http\=url}
|
||||
record. All strings come back from the URI parser encoded.
|
||||
\semvar{search} and \var{frag\=id} are left that way; this parser
|
||||
decodes the path elements. The first two list elements of the path
|
||||
indicating the leading double-slash are omitted.
|
||||
|
||||
\ex{http-url->string} just does the inverse job. It converts a
|
||||
\ex{http\=url} record into a \str.
|
||||
\end{defundescx}
|
||||
|
||||
|
||||
%%% Local Variables:
|
||||
%%% mode: latex
|
||||
%%% TeX-master: t
|
||||
%%% End:
|
|
@ -1,161 +0,0 @@
|
|||
This file documents names defined in rfc822.scm:
|
||||
|
||||
|
||||
|
||||
|
||||
NOTES
|
||||
|
||||
|
||||
|
||||
A note on line-terminators:
|
||||
|
||||
Line-terminating sequences are always a drag, because there's no
|
||||
agreement on them -- the Net protocols and DOS use cr/lf; Unix uses
|
||||
lf; the Mac uses cr. One one hand, you'd like to use the code for all
|
||||
of the above, on the other, you'd also like to use the code for strict
|
||||
applications that need definitely not to recognise bare cr's or lf's
|
||||
as terminators.
|
||||
|
||||
RFC 822 requires a cr/lf (carriage-return/line-feed) pair to terminate
|
||||
lines of text. On the other hand, careful perusal of the text shows up
|
||||
some ambiguities (there are maybe three or four of these, and I'm too
|
||||
lazy to write them all down). Furthermore, it is an unfortunate fact
|
||||
that many Unix apps separate lines of RFC 822 text with simple
|
||||
linefeeds (e.g., messages kept in /usr/spool/mail). As a result, this
|
||||
code takes a broad-minded view of line-terminators: lines can be
|
||||
terminated by either cr/lf or just lf, and either terminating sequence
|
||||
is trimmed.
|
||||
|
||||
If you need stricter parsing, you can call the lower-level procedure
|
||||
%READ-RFC-822-FIELD and %READ-RFC822-HEADERS procs. They take the
|
||||
read-line procedure as an extra parameter. This means that you can
|
||||
pass in a procedure that recognises only cr/lf's, or only cr's (for a
|
||||
Mac app, perhaps), and you can determine whether or not the
|
||||
terminators get trimmed. However, your read-line procedure must
|
||||
indicate the header-terminating empty line by returning *either* the
|
||||
empty string or the two-char string cr/lf (or the EOF object).
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINITIONS AND DESCRIPTIONS
|
||||
|
||||
|
||||
|
||||
(read-rfc822-field [port])
|
||||
(%read-rfc822-field read-line port)
|
||||
|
||||
Read one field from the port, and return two values [NAME BODY]:
|
||||
|
||||
- NAME Symbol such as 'subject or 'to. The field name is converted
|
||||
to a symbol using the Scheme implementation's preferred
|
||||
case. If the implementation reads symbols in a case-sensitive
|
||||
fashion (e.g., scsh), lowercase is used. This means you can
|
||||
compare these symbols to quoted constants using EQ?. When
|
||||
printing these field names out, it looks best if you capitalise
|
||||
them with (CAPITALIZE-STRING (SYMBOL->STRING FIELD-NAME)).
|
||||
|
||||
- BODY List of strings which are the field's body, e.g.
|
||||
("shivers@lcs.mit.edu"). Each list element is one line from
|
||||
the field's body, so if the field spreads out over three lines,
|
||||
then the body is a list of three strings. The terminating
|
||||
cr/lf's are trimmed from each string. A leading space or a
|
||||
leading horizontal tab is also trimmed, but one and onyl one.
|
||||
|
||||
When there are no more fields -- EOF or a blank line has terminated
|
||||
the header section -- then the procedure returns [#f #f].
|
||||
|
||||
The %READ-RFC822-FIELD variant allows you to specify your own
|
||||
read-line procedure. The one used by READ-RFC822-FIELD terminates
|
||||
lines with either cr/lf or just lf, and it trims the terminator from
|
||||
the line. Your read-line procedure should trim the terminator of the
|
||||
line, so an empty line is returned as an empty string.
|
||||
|
||||
The procedures raise an error if the syntax of the read field (the
|
||||
line returned by the read-line-function) is illegal (RFC822 illegal).
|
||||
|
||||
|
||||
|
||||
read-rfc822-headers [port]
|
||||
%read-rfc822-headers read-line port
|
||||
|
||||
Read in and parse up a section of text that looks like the header
|
||||
portion of an RFC 822 message. Return an alist mapping a field name (a
|
||||
symbol such as 'date or 'subject) to a list of field bodies -- one for
|
||||
each occurence of the field in the header. So if there are five
|
||||
"Received-by:" fields in the header, the alist maps 'received-by to a
|
||||
five element list. Each body is in turn represented by a list of
|
||||
strings -- one for each line of the field. So a field spread across
|
||||
three lines would produce a three element body.
|
||||
|
||||
The %READ-RFC822-HEADERS variant allows you to specify your own
|
||||
read-line procedure. See notes (A note on line-terminators) above for
|
||||
reasons why.
|
||||
|
||||
|
||||
|
||||
rejoin-header-lines alist [seperator]
|
||||
|
||||
Takes a field alist such as is returned by READ-RFC822-HEADERS and
|
||||
returns an equivalent alist. Each body (string list) in the input
|
||||
alist is joined into a single list in the output alist. SEPARATOR is
|
||||
the string used to join these elements together; it defaults to a
|
||||
single space " ", but can usefully be "\n" or "\r\n".
|
||||
|
||||
To rejoin a single body list, use scsh's JOIN-STRINGS procedure.
|
||||
|
||||
|
||||
|
||||
For the following definitions' examples, let's use this set of of
|
||||
RFC822 headers:
|
||||
From: shivers
|
||||
To: ziggy,
|
||||
newts
|
||||
To: gjs, tk
|
||||
|
||||
|
||||
|
||||
get-header-all headers name
|
||||
|
||||
returns all entries or #f, p.e.
|
||||
(get-header-all hdrs 'to) -> ((" ziggy," " newts") (" gjs, tk"))
|
||||
|
||||
|
||||
|
||||
get-header-lines headers name
|
||||
|
||||
returns all lines of the first entry or #f, p.e.
|
||||
(get-header-lines hdrs 'to) -> (" ziggy," " newts")
|
||||
|
||||
|
||||
|
||||
get-headers headers name [seperator]
|
||||
|
||||
returns the first entry with the lines joined together by seperator
|
||||
(newline by default (\n)), p.e.
|
||||
(get-header hdrs 'to) -> "ziggy,\n newts"
|
||||
|
||||
|
||||
|
||||
htab
|
||||
|
||||
is the horizontal tab (ascii-code 9)
|
||||
|
||||
|
||||
|
||||
string->symbol-pref
|
||||
|
||||
is a procedure that takes a string and converts it to a symbol
|
||||
using the Scheme implementation's preferred case. The preferred case
|
||||
is recognized by a doing a symbol->string conversion of 'a.
|
||||
|
||||
|
||||
|
||||
|
||||
DESIREABLE FUNCTIONALITIES
|
||||
|
||||
- Unfolding long lines.
|
||||
- Lexing structured fields.
|
||||
- Unlexing structured fields into canonical form.
|
||||
- Parsing and unparsing dates.
|
||||
- Parsing and unparsing addresses.
|
|
@ -1,79 +0,0 @@
|
|||
This file documents names specified in stringhax.scm.
|
||||
|
||||
|
||||
|
||||
|
||||
NOTES
|
||||
|
||||
stringhax.scm provides several string-hacking procedures.
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINITIONS AND DESCRIPTIONS
|
||||
|
||||
|
||||
procedure
|
||||
string-map procedure string --> string
|
||||
|
||||
Does a 'map' on each character of STRING and returns the result, a
|
||||
newly allocated string. PROCEDURE takes a character and should return
|
||||
a character.
|
||||
|
||||
|
||||
procedure
|
||||
downcase-string string --> string
|
||||
upcase-string string --> string
|
||||
|
||||
Do what you expect: converts STRING to downcase or upcase
|
||||
respectively, using char-downcase or char-upcase respectively. The
|
||||
result is a newly allocated string.
|
||||
|
||||
|
||||
procedure
|
||||
char-set-index string char-set [start] --> number
|
||||
char-set-rindex string char-set [start] --> number
|
||||
|
||||
Returns the index of the first character that is in
|
||||
char-set. char-set-index searches from left to r0.6/scsh/lib/char-package.scmight, char-set-rindex
|
||||
from right to left. START is the index from where to start from and
|
||||
defaults to 0 in char-set-index and (string-length STRING) in
|
||||
char-set-rindex. If the search fails, #f is returned.
|
||||
|
||||
|
||||
procedure
|
||||
string-reduce default construct string --> string
|
||||
|
||||
Does a "fold-right" on string. The resulting string is
|
||||
(CONSTRUCT ... (CONSTRUCT STRING[n-1] (CONSTRUCT STRING[n] DEFAULT)) ...)
|
||||
Example:
|
||||
|
||||
(string-reduce "" (lambda (char str)
|
||||
(string-append str (string (char-downcase char))))
|
||||
"DOWNCASE")
|
||||
|
||||
==> "downcase"
|
||||
|
||||
|
||||
procedure
|
||||
string-prefix? prefix string --> boolean
|
||||
string-suffix? suffix string --> boolean
|
||||
|
||||
Return #t if PREFIX/SUFFIX is a real prefix/suffix of STRING,
|
||||
otherwise return #f. Real prefix/suffix means that STRING may not be a
|
||||
prefix/suffix of PREFIX/SUFFIX.
|
||||
|
||||
|
||||
procedure
|
||||
skip-whitespace string --> number
|
||||
|
||||
Returns the index of the first character in STRING that is not a
|
||||
whitespace (as defined in char-set:whitespace). If there isn't such a
|
||||
character, #f is returned.
|
||||
|
||||
|
||||
procedure
|
||||
trim-spaces string --> string
|
||||
|
||||
Returns a newly allocated string being STRING without leading or
|
||||
trailing spaces (not whitespaces!).
|
|
@ -1,64 +0,0 @@
|
|||
This file documents names defined in toothless.scm
|
||||
|
||||
|
||||
|
||||
|
||||
NOTES
|
||||
|
||||
toothless.scm defines a Scheme 48 module that is R4RS without features
|
||||
that could examine or effect the file system. You can also use it as a
|
||||
model of how to execute code in other protected environments in S48.
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINITIONS AND DESCRIPTIONS
|
||||
|
||||
|
||||
structure
|
||||
loser-package
|
||||
|
||||
Exports:
|
||||
|
||||
procedure
|
||||
loser name --> error
|
||||
|
||||
Raises an error like "Illegal call NAME".
|
||||
|
||||
|
||||
structure
|
||||
toothless
|
||||
|
||||
Exports everything of R4RS. Following procedures are redefined, so
|
||||
they raise an error if the are called:
|
||||
|
||||
call-with-input-file
|
||||
call-with-output-file
|
||||
load
|
||||
open-input-file
|
||||
open-output-file
|
||||
transcript-on
|
||||
with-input-from-file
|
||||
with-input-to-file
|
||||
eval
|
||||
interaction-environment
|
||||
scheme-report-environment
|
||||
|
||||
toothless shall create an environment as described in NOTES.
|
||||
|
||||
|
||||
structure
|
||||
toothless-eval
|
||||
|
||||
Exports:
|
||||
|
||||
procedure
|
||||
eval-safely expression
|
||||
|
||||
Creates a brand new package, imports the TOOTHLESS structure, and
|
||||
evaluates EXP in it. When the evaluation is done, the environment is
|
||||
thrown away, so EXP's side-effects don't persist from one EVAL-SAFELY
|
||||
call to the next. If EXP raises an error exception, we abort and
|
||||
return #f.
|
||||
|
||||
|
152
doc/uri.scm.doc
152
doc/uri.scm.doc
|
@ -1,152 +0,0 @@
|
|||
This file documents names specified in uri.scm.
|
||||
|
||||
|
||||
|
||||
|
||||
NOTES
|
||||
|
||||
URIs are of following syntax:
|
||||
|
||||
[scheme] : path [? search ] [# fragmentid]
|
||||
|
||||
Parts in [] may be ommitted. The last part is usually referred to as
|
||||
fragid in this document.
|
||||
|
||||
|
||||
|
||||
DEFINITIONS AND DESCRIPTIONS
|
||||
|
||||
|
||||
char-set
|
||||
uri-reserved
|
||||
|
||||
A list of reserved characters (semicolon, slash, hash, question mark,
|
||||
double colon and space).
|
||||
|
||||
procedure
|
||||
parse-uri uri-string --> (scheme, path, search, frag-id)
|
||||
|
||||
Multiple-value return: scheme, path, search, frag-id, in this
|
||||
order. scheme, search and frag-id are either #f or a string. path is a
|
||||
nonempty list of strings. An empty path is a list containing the empty
|
||||
string. parse-uri tries to be tolerant of the various ways people
|
||||
build broken URIs out there on the Net (so it is not absolutely
|
||||
conform with RFC 1630).
|
||||
|
||||
|
||||
procedure
|
||||
unescape-uri string [start [end]] --> string
|
||||
|
||||
Unescapes a string. This procedure should only be used *after* the url
|
||||
(!) was parsed, since unescaping may introduce characters that blow
|
||||
up the parse (that's why escape sequences are used in URIs ;).
|
||||
Escape-sequences are of following scheme: %hh where h is a hexadecimal
|
||||
digit. E.g. %20 is space (ASCII character 32).
|
||||
|
||||
|
||||
procedure
|
||||
hex-digit? character --> boolean
|
||||
|
||||
Returns #t if character is a hexadecimal digit (i.e., one of 1-9, a-f,
|
||||
A-F), #f otherwise.
|
||||
|
||||
|
||||
procedure
|
||||
hexchar->int character --> number
|
||||
|
||||
Translates the given character to an integer, p.e. (hexchar->int \#a)
|
||||
=> 10.
|
||||
|
||||
|
||||
procedure
|
||||
int->hexchar integer --> character
|
||||
|
||||
Translates the given integer from range 1-15 into an hexadecimal
|
||||
character (uses uppercase letters), p.e. (int->hexchar 14) => E.
|
||||
|
||||
|
||||
char-set
|
||||
uri-escaped-chars
|
||||
|
||||
A set of characters that are escaped in URIs. These are the following
|
||||
characters: dollar ($), minus (-), underscore (_), at (@), dot (.),
|
||||
and-sign (&), exclamation mark (!), asterisk (*), backslash (\),
|
||||
double quote ("), single quote ('), open brace ((), close brace ()),
|
||||
comma (,) plus (+) and all other characters that are neither letters
|
||||
nor digits (such as space and control characters).
|
||||
|
||||
|
||||
procedure
|
||||
escape-uri string [escaped-chars] --> string
|
||||
|
||||
Escapes characters of string that are given with escaped-chars.
|
||||
escaped-chars default to uri-escaped-chars. Be careful with using this
|
||||
procedure to chunks of text with syntactically meaningful reserved
|
||||
characters (e.g., paths with URI slashes or colons) -- they'll be
|
||||
escaped, and lose their special meaning. E.g. it would be a mistake to
|
||||
apply escape-uri to "//lcs.mit.edu:8001/foo/bar.html" because the
|
||||
slashes and colons would be escaped. Note that esacpe-uri doesn't
|
||||
check this as it would lose his meaning.
|
||||
|
||||
|
||||
procedure
|
||||
resolve-uri cscheme cp scheme p --> (scheme, path)
|
||||
|
||||
Sorry, I can't figure out what resolve-uri is inteded to do. Perhaps
|
||||
I find it out later.
|
||||
|
||||
The code seems to have a bug: In the body of receive, there's a
|
||||
loop. j should, according to the comment, count sequential /. But j
|
||||
counts nothing in the body. Either zero is added ((lp (cdr cp-tail)
|
||||
(cons (car cp-tail) rhead) (+ j 0))) or j is set to 1 ((lp (cdr
|
||||
cp-tail) (cons (car cp-tail) rhead) 1))). Nevertheless, j is expected
|
||||
to reach value numsl that can be larger than one. So what? I am
|
||||
confused.
|
||||
|
||||
|
||||
procedure
|
||||
rev-append list-a list-b --> list
|
||||
|
||||
Performs a (append (reverse list-a) list-b). The comment says it
|
||||
should be defined in a list package but I am wondering how often this
|
||||
will be used.
|
||||
|
||||
|
||||
procedure
|
||||
split-uri-path uri start end --> list
|
||||
|
||||
Splits uri at /'s. Only the substring given with start (inclusive) and
|
||||
end (exclusive) is considered. Start and end - 1 have to be within the
|
||||
range of the uri-string. Otherwise an index-out-of-range exception
|
||||
will be raised. Example: (split-uri-path "foo/bar/colon" 4 11) ==>
|
||||
'("bar" "col")
|
||||
|
||||
|
||||
procedure
|
||||
simplify-uri-path path --> list
|
||||
|
||||
Removes "." and ".." entries from path. The result is a (maybe empty)
|
||||
list representing a path that does not contain any "." or "..". The
|
||||
list can only be empty if the path did not start with "/" (for the
|
||||
rare occasion someone wants to simplify a relative path). The result
|
||||
is #f if the path tries to back up past root, for example by "/.." or
|
||||
"/foo/../.." or just "..". "//" may occur somewhere in the path
|
||||
referring to root but not being backed up.
|
||||
Examples:
|
||||
(simplify-uri-path (split-uri-path "/foo/bar/baz/.." 0 15))
|
||||
==> '("" "foo" "bar")
|
||||
|
||||
(simplify-uri-path (split-uri-path "foo/bar/baz/../../.." 0 20))
|
||||
==> '()
|
||||
|
||||
(simplify-uri-path (split-uri-path "/foo/../.." 0 10))
|
||||
==> #f ; tried to back up root
|
||||
|
||||
(simplify-uri-path (split-uri-path "foo/bar//" 0 9))
|
||||
==> '("") ; "//" refers to root
|
||||
|
||||
(simplify-uri-path (split-uri-path "foo/bar/" 0 8))
|
||||
==> '("") ; last "/" also refers to root
|
||||
|
||||
(simplify-uri-path (split-uri-path "/foo/bar//baz/../.." 0 19))
|
||||
==> #f ; tries to back up root
|
|
@ -1,69 +0,0 @@
|
|||
This file documents names defined in url.scm
|
||||
|
||||
|
||||
|
||||
|
||||
NOTES
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINITIONS AND DESCRIPTIONS
|
||||
|
||||
|
||||
userhost record
|
||||
|
||||
A record containing the fields user, password, host and port. Created
|
||||
by parsing a string like //<user>:<password>@<host>:<port>/. The
|
||||
record describes path-prefixes of the form
|
||||
//<user>:<password>@<host>:<port>/ These are frequently used as the
|
||||
initial prefix of URL's describing Internet resources.
|
||||
|
||||
|
||||
parse-userhost path default
|
||||
|
||||
Parse a URI path (a list representing a path, not a string!) into a
|
||||
userhost record. Default values are taken from the userhost record
|
||||
DEFAULT except for the host. Returns a userhost record if it wins, and
|
||||
#f if it cannot parse the path. It is an error if the specified path
|
||||
does not begin with '//..' like noted at userhost.
|
||||
|
||||
|
||||
userhost-escaped-chars list
|
||||
|
||||
The union of uri-escaped-chars and the characters '@' and ':'. Used
|
||||
for the unparser.
|
||||
|
||||
|
||||
userhost->string userhost procedure
|
||||
|
||||
Unparses a userhost record to a string.
|
||||
|
||||
|
||||
http-url record
|
||||
|
||||
Record containing the fields userhost (a userhost record), path (a
|
||||
path list), search and frag-id. The PATH slot of this record is the
|
||||
URL's path split at slashes, e.g., "foo/bar//baz/" => ("foo" "bar" ""
|
||||
"baz" ""). These elements are in raw, unescaped format. To convert
|
||||
back to a string, use (uri-path-list->path (map escape-uri pathlist)).
|
||||
|
||||
|
||||
parse-http-url path search frag-id procedure
|
||||
|
||||
Returns a http-url record. path, search and frag-id are results of a
|
||||
parse-uri call on the initial uri. See there (uri.scm) for further
|
||||
details. search and frag-id are stored as they are. This parser
|
||||
decodes the path elements. It is an error if the path specifies an
|
||||
user or a password as this is not allowd at http-urls.
|
||||
|
||||
|
||||
default-http-userhost record
|
||||
|
||||
A userhost record that specifies the port as 80 and anything else as
|
||||
#f.
|
||||
|
||||
|
||||
http-url->string http-url
|
||||
|
||||
Unparses the given http-url to a string.
|
Loading…
Reference in New Issue