* 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