Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v29i062: libftp - C library for FTP client access, V5.0, Part01/08

104 views
Skip to first unread message

Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 62
Archive-Name: libftp-5.0/part01

LIBFTP Version 5.0

Oleg Orel
or...@oea.ihep.su
or...@cern.ch

December 13,1995

License

This library is designed for free, non-commercial software creation. It
is changeable and can be improved. The author would greatly appreciate any
advises, new components and patches of the existing programs. Commercial
usage is also possible with participation of it's author

Introduction

The basic orientation of this library is making user's programs which
trans- port les via TCP/IP network. It contains set of functions, starting
from prim- itive, such as opening FTP connection to the server, and nishing
by high-level functions, such as functions which retrieve les via network,
making and clos- ing channels to the server. All functions have prototypes
in common header le named FtpLibrary.h, which must be available in standard
headers direc- tory. Those prototypes almost fully describe orientation and
arguments of all functions, but common ideology and library components
should be mentioned.

This library is a client and uses standard FTPD from the other side.

There are problems of errors processing in many operating systems
includ- ing input/output errors. The mutual mechanism of value returning of
all func- tions is used in this library. (EXIT macros, dened in le
FtpLibrary.h). This mechanism allows, after the denition of the error
processing functions, write programs, considering the conditions to be
ideal. Data transfer functions have possibility to preset data stream
expectation timeout. When the set time ex- pires, previously set function
will be called.

Last major changes

Last time to library was added several extensions for high level
operations: such as FtpStat, which extract maximum of information about
speciefed files(s) and FtpHTTPGet, which receive files using as gateway
HTTP-server.

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./doc`
then
mkdir ./doc
echo "mkdir ./doc"
fi
if `test ! -s ./doc/libftp.tex`
then
echo "writing ./doc/libftp.tex"
cat > ./doc/libftp.tex << '\End\Of\Shar\'
\documentstyle[cxx,fancyheadings,twoside,epsf,indentfirst]{article}
% Vertical sizes
%\vsize=20cm
%\voffset=-2.3cm
%\topmargin=0cm
%\headheight=0.9cm
%\footskip=1cm
%\footheight=0.9cm
%\textheight=16cm
%\headrulewidth 0.01cm
%\footrulewidth 0.0cm
% 0 sizes
%\hsize=30cm
%\hoffset=-4.3cm
%\hoffset=-2.3cm
%\textwidth=13cm
% Modes
% \special{landscape}
\pagestyle{empty}
\pagestyle{fancyplain}
\newcommand{\tit}[1]{#1}
\rhead[\fancyplain{}{\tit{\leftmark}}]{\fancyplain{}{\tit{\rightmark}}}
\lhead[\fancyplain{}{\tit{\rightmark}}]{\fancyplain{}{\tit{\leftmark}}}
\chead{\hfill}
\lfoot[\fancyplain{}{\tit{\thepage}}]{\fancyplain{}{\hfill}}
\rfoot[\fancyplain{}{\hfill}]{\fancyplain{}{\tit{\thepage}}}
\cfoot{\hfill}
\renewcommand{\sectionmark}[1]{\markboth{#1}{\ }}
\renewcommand{\subsectionmark}[1]{\markright{\ }}
\newcommand{\look}[1]{(Chapter~\ref{#1}, page~\pageref{#1})}
\newcommand{\toindex}[1]{\underline{\bf#1}\index{#1}}
\newcommand{\add}[1]{\symbol{64}}
\newcommand{\ps}[1]{\symbol{37}s}
\newcommand{\twcol}[4]{
\noindent\parbox[t]{#1\textwidth}{#3} \hfill \parbox[t]{#2\textwidth}{#4\hfill}\\
}
\newcommand{\tc}[2]{\twcol{0.49}{0.49}{#1}{#2}}
\newcommand{\tcc}[2]{\twcol{0.49}{0.49}{\toindex{#1}}{#2}}
\newcommand{\ttt}[2]{\bigskip

{\bf#1}

#2}
\newcommand{\ts}[1]{{\underline{\bf#1}}}
\newcommand{\dl}[2]{\parbox[t]{0.4\textwidth}{#1\hfill}\hfill
\parbox[t]{0.4\textwidth}{#2\hfill}}
\makeindex
\begin{document}
\title{{\bf\it{}LIBFTP User's guide}\\Version 5.0}
\author{Oleg Orel\\\\\\or...@oea.ihep.su\\or...@cern.ch}
\date{December 13,1995}
\newpage
\maketitle

\section*{License}

This library is designed for free, non-commercial software creation.
It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.
Commercial usage is also possible with participation of it's author
\footnote{For use this library for commercial purpose need to buy license, for do it
need to contact with author}

\section*{Introduction}

The basic orientation of this library is making user's programs which transport
files via TCP/IP network. It contains set of functions,
starting from primitive, such as opening FTP connection to the server,
and finishing by high-level functions, such as functions which retrieve files
via network, making and closing channels to the server. All functions have
prototypes in common header file named \toindex{FtpLibrary.h},
which must be
available in standard headers directory
\footnote{for example ``/usr/include''}.
Those prototypes almost fully
describe orientation and arguments of all functions,
but common ideology and library components should be mentioned.

This library is a client and uses standard FTPD from the other side.

There are problems of errors processing in many operating systems including input/output errors.
The mutual mechanism of value returning of all functions is used in this library.
(EXIT macros, defined in file FtpLibrary.h). This mechanism allows,
after the definition of the error processing functions, write programs,
considering the conditions to be ideal.
Data transfer functions have possibility to preset data stream
expectation timeout.
When the set time expires, previously set function will be called.

\section*{Last major changes}

Last time to library was added several extensions for high level operations: such as
FtpStat \look{FtpStat} which extract maximum of information about specie-fed file(s)
and FtpHTTPGet\look{FtpHttpGet} which receive files using as gateway HTTP-server.

\section{Variables and definitions}

\subsection{Some definitions in libftp's header file (FtpLibrary.h)}

\ttt{\toindex{EXIT}}{Main macro for return value from library's functions with
calling handlers if it's need}

\ttt{\toindex{MAX\_ANSWERS}}{Number of possible good answers from FTPD for one request}

\ttt{\toindex{FTP\_NFDS}}{Maximum numbers of one-time opened files in system}

\ttt{\toindex{FTPBUFSIZE}}{Size of block for transmit data via network.
By default equivalence \toindex{BUFSIZ}}

\ttt{\toindex{LQUIT}}{Error status of local functions. If you give this status
from libftp's function you must use perror for expand diagnostic.}

\ttt{\toindex{QUIT}}{Error status of network operation. Use perror.}

\ttt{\toindex{Ctrl}(char)}{Return control character code}

\ttt{\toindex{FtpString}}{Special type for strings, entering for readable}

\ttt{\toindex{STATUS}}{Special type for returned value, if function return value such type,
it is mean that you must check returned value and compare it with OK, QUIT, LQUIT
if handlers wasn't preseted}

\ttt{\toindex{FREE}(data)}{Fill data by zero}

\ttt{\toindex{FtpError}(libftp's call)}{Special macro for diagnostic bad conditions}

\ttt{\toindex{FtpAssert}(libftp's call)}{Special macro for automatically return from
this function if status is bad}

\ttt{\toindex{FtpStatus}(FTP *,libftp's call)}{This macro executes specified function
and return his status, without interruption to handlers inside if last one was set}

\subsection{Libftp's file specification}

All files which must be interprets as local interprets as libftp's files.
LIBFTP responds to three types of files such
as local file, FTP's files and program
pipes. All files can be described as next syntax:

\ttt{$\mid$string}{interprets string as shell command, which must be
executed with appropriate input/output for file. It depends where
this file is specified.}

\ttt{*STDIN*, *STDOUT*, *STDERR* or char '-'}{opened standard streams}

\ttt{anything else}{local file}


\subsection{The FTP data structure} \label{FTP}

\subsubsection{The members of FTP structure}

\tc{FILE *\toindex{sock}\footnote{You can use macro FTPCMD(ftp) for extract
this members, using this macro for making your program more compatibility
with next versions of this library}}
{--- command channel to the server;}

\tc{FILE *\toindex{data}\footnote{You can use macro FTPDATA(ftp) for extract
this members, using this macro for making your program more compatibility
with next versions of this library}}
{--- pointer to data structure, which describes data channel to the server;}

\tc{int \toindex{errno}}{ --- last returned value. When value is lower than 1, an error occurred;}

\tc{char \toindex{mode}}{--- type of transfer (valid values: 'A' 'I' ....);}

\tc{int \toindex{ch}}{--- help variable. Is used to convert ASCII files,
user of library for cleaning your problems must forget about this member;}

\tc{STATUS (*\toindex{error})()}{--- pointer to an error handler. It is called
when status from the server is bad;}
\tc{STATUS (*\toindex{debug})()}{--- pointer to a debug handler. Is called from
functions of sending/receiving messages to/from server;}

\tc{STATUS (*\toindex{IO})()}{--- pointer to Input/Output error handler. Is called when
channel to server is broken.}

\tc{STATUS (*\toindex{hash})()}{--- pointer to function, which must compute
summary traffic. This function can take one argument which describe
how many bytes
now received of sended to/from server. If the argument is equivalence
to zero, then counter must be reset to zero. But of course user can use
this handler for another properties of herself program, for example for
perriodicaly called anything else for checking other conditions, because
the transfer procedure can take large time from user's program.}

\tc{int \toindex{seek}}{--- the first byte in file for transfer. This option
can use for re-transfer file again after connection is broken}

\tc{int \toindex{flags}}{--- the option list for transfer procedures such as:
\\
\begin{itemize}
\item[FTP\_REST] Turn on re-transfer file using method of compare size of files
in both sides.
\item[FTP\_NOEXIT] Don't exit from standard error and IO handlers
\item[FTP\_HANDLERS] Enable to call handlers for errors and debug events.
Set by default.
\end{itemize}}

\tc{struct timeval \toindex{timeout}}{--- Timeout for send/receive procedures}

\tc{int \toindex{port}}{--- Port for making command connection}

\tc{FtpString \toindex{title}}{--- Connection identification}

\tc{unsigned long \toindex{counter}}{--- counter of already transferred bytes}

\subsubsection{Initialization of FTP structure}

This library have two special objects: procedure FtpCreateObject and external
static structure FtpInit. The procedure FtpCreateObject called from
FtpConnect. The structure FtpInit can be modified by hand or by using special
macros such as \toindex{FtpSetFlag}, \toindex{FtpClearFlag}, \toindex{FtpTestFlag}, \toindex{FtpSetPort}, \toindex{FtpSetTimeout}, \toindex{FtpSetErrorHandler}, \toindex{FtpSetDebugHandler}, \toindex{FtpSetIOHandler}, \\
\toindex{FtpSetHashHandler},\toindex{FtplibDebug}.

\subsection{The \toindex{ARCHIE} data structure}

The \ts{ARCHIE} data structure using only with function FtpArchie for extract
result of works one. This structure have four members such as:

\tc{struct tm \toindex{createtime}}{Time of file creation.}

\tc{unsigned long \toindex{size}}{size of file.}

\tc{FtpString \toindex{host}}{Host which file is located}

\tc{FtpString \toindex{file}}{Full path in pointed host of this file}


\subsection{The \toindex{FTP\_STAT} data structure}\label{FtpStat}

The \ts{FTP\_STAT} data structure using with function \toindex{FtpStat} and \toindex{FtpStatFree} for get file's properties in remote server. Using this functions and this structure you can get size of files, protection, owners and types for file.

\tc{FtpString \toindex{name}}{Name of file which described in current structure}

\tc{char \toindex{type}}{Type of file: '-' - regular file, 'd' - directory, 'l' - symbolic link}

\tc{int \toindex{mode}}{Protection of file.}

\tc{int \toindex{inodes}}{Number of references to this file}

\tc{FtpString \toindex{user}}{Owner's name of this file}

\tc{FtpString \toindex{group}}{Group's name of this file}

\tc{unsigned long \toindex{size}}{Size of file in bytes}

\tc{int \toindex{month}}{Month of creation file}

\tc{int \toindex{day}}{Day of creation file}

\tc{FtpString \toindex{time}}{Time of creation file in string format}

\tc{FtpString \toindex{link}}{If file is symbolic link, here is name of pointed file}

\tc{FTP\_STAT *\toindex{next}}{Pointer to next same structure, otherwise NULL }

\section{Library's routines}

\subsection{Connection/Disconnection with server}

\ttt{STATUS \toindex{FtpConnect}(FTP~**, char~*hostname
\footnote{The name of the host may be symbolic (for example \ts{dxcern.cern.ch}) or numeric (for example \ts{128.141.201.96})}
)}
{
Makes channel to the server, at the ``hostname'' machine.
Creates FTP data structure and returns pointer to it. If the procedure \toindex{FtplibDebug}(1)
was previously called, \ts{FtpConnect} calls automatically \ts{FtpDebug} for the \ts{debug mode} to be turned on.
\look{debug}.
}
\ttt{STATUS \toindex{FtpUser}(FTP~*, char~*user)}
{
Sends the name of the user to the server. The connection must be done before it.
}

\ttt{STATUS \toindex{FtpPassword}(FTP~*, char~*password)}
{
Sends \ts{password} to the server. The function \ts{FtpUser} must be called before it.
}

\ttt{STATUS \toindex{FtpAccount}(FTP~*, char~*account)}
{
Sends a name of the account to the server. The name of the account is not standard
attribute for many systems, so this function is used very seldom.
The function \ts{FtpPassword} must be called before it.
}

\ttt{
STATUS \toindex{FtpLogin}(FTP~**, char~*hostname, char~*user, char~*password, char~*account)}
{
Executes functions \ts{FtpConnect}, \ts{FtpUser}, \ts{FtpPassword},
\ts{FtpAccount} (if necessary) consistently. If the name of the account is absent,
replaces it with the \ts{NULL} value.
}

\ttt{STATUS \toindex{FtpBye}(FTP~*)}
{ Finishes work with the server and closes all channels.
\footnote{You can see from the description of connect/disconnect functions, that you can create
more than one connection to servers simultaneously.}
}

\ttt{STATUS \toindex{FtpQuickBye}(FTP~*)}
{ Fast close data and command connection to server without delays for waiting
server's confirmation and destroying the FTP object.
}

\ttt{STATUS \toindex{FtpAbort}(FTP~*)}
{ Abort last command passed to server}


\subsection{The debugging} \label{debug}

There is a possibility to predefine few functions,
such as:~\footnote{If the \ts{NULL} value is transferred as a parameter \ts{``function''} to the functions, described below,
the handling will be turned off.}

\ttt{\toindex{FtpSetDebugHandler}(FTP *,function)}
{ Predefines function of protocol debugging.
After the function is predefined, it is called with every
sending/receiving messages from the server.
The function, defined as a debug handler must do returns to the calling
functions (\ts{FtpSendMessage}/\ts{FtpGetMessage}), but can also abort the program.

}

\ttt{\toindex{FtpSetErrorHandler}(FTP *,function)}
{
Predefines error handler. If the server's answer means, that the operation is not finished
correctly, this function will be called.
The result code is negative, if an error is occurs.
}
\ttt{\toindex{FtpSetIOHandler}(FTP *,function)}
{
Predefines handler of Input/Output processing. This function is called, when a connection to the
server is broken. For example, when the network or the remote host is down. This handler also is
called after the \toindex{timeout} of one character waiting expires.
}

\ttt{\toindex{FtpDebug}(FTP *)}
{
Turns on all standard debugging functions.

\tc{\toindex{FtpDebugError}}{--- prints a string, taken from the server, and aborts the program;}
\tc{\toindex{FtpDebugDebug}}{--- prints a string, taken from the server;}
\tc{\toindex{FtpDebugIO}}{--- prints string \ts{strerror(errno)} and aborts the program.}
}


All function for debugging have three arguments:\\
1. Pointer to FTP data structure;\\
2. Last returned value from the server. When errors occur, the value is less than 1;\\
3. Diagnostic string.(char *)

\ttt{\toindex{FtplibDebug}(yes|no)}
{ Turns on/off autostart debug mode, when connection is established.
}

\ttt{\toindex{FtpSetHashHandler}(FTP *,function)}
{
Predefines handler of function which must compute traffic size. This
function have only one argument which describe number of transferred bytes.
If this argument is zero counter must be reset to zero.
}


\ttt{\toindex{FtpLog}(char *name\_of\_log, char *message)}
{ Print message to user's screen in libftp's standard format,
name\_of\_log must be your program name (if this function called
from standard handlers then this string is title from FTP structure) and
message with diagnostic string from anywhere.}


\subsection{Data transfer procedures}

\ttt{STATUS \toindex{FtpRetr}(FTP~*, char~*command, char~*inp, char~*out)}
{
This is basically and single procedure in the library for transfer
file from the server. One check many option with customizing its style
of working. This options basically is members of FTP structure such
as timeout, all handlers, mode, seek. If in continue of working this
function happen timeout or network broked then this function
automatically called I/O or error handler, if one is preseted.
If handler is not set then FtpRetr return
status QUIT or LQUIT as signal of type of error (LQUIT is specify
error happen with local filesystem). \\

}

\ttt{\toindex{FtpGet}(FTP~*, char~*in, char~*out)}
{
Calls \ts{FtpRetr} with adaptation arguments to transfer file
}

\ttt{\toindex{FtpDirectory}(FTP~*, char~*pat\footnote{This is the first argument for \ts{``ls''} command}, char~*out)}
{
Transfers files listing from the server, described by \ts{pat}, to the local file \ts{out}.
}

\ttt{\toindex{FtpDir}(FTP~*, char~*out)}
{
Transfers files listing of the current directory from the server to the local file \ts{out}.
}

\ttt{\toindex{FtpStor}(FTP~*, char~*command, char~*inp, char*~out)}
{
Store file to the server. Works like FtpRetr.
}

\ttt{\toindex{FtpPut}(FTP~*, char~*in, char~*out)}
{
Calls \ts{FtpStor} adaptation arguments to transfer file
}

\ttt{\toindex{FtpCopy}(FTP~*ftp\_from, FTP~*ftp\_to, char~*in, char~*out)}
{
Transfer file between two server without connection to client's host
}

\ttt{\toindex{FtpLink}(FTP~*ftp1, FTP~*ftp2)}
{
Make data chanel between both servers.
}

\ttt{\toindex{FtpPassiveTransfer}(FTP~*ftp\_from, FTP~*ftp\_to, char~*in, char~*out)}
{
Transfer file between two server via client's cache.
}

\subsection{Server's files read/write procedures}

This library contains special functions for remote files reading and
writing, without copy in advance them to local files. The functions,
which are described below, do it. After the data channel
to a remote file is created, it becomes possible to read and write
characters using standard Input/Output functions
or using special functions \ts{FtpRead}/\ts{FtpWrite} and/or
\ts{FtpGetc}/\ts{FtpPutc}, which reorganize stream for standard text file,
under condition that the \ts{ASCII} mode is set.
\footnote{Of course, such functions as \ts{seek}, \ts{ioctl}, ....
can not be used.}

\ttt{\toindex{FtpData}(FTP~*, char~*command, char~*param, char~*mode)}
{ Makes data transfer channel, with presending command composed from \ts{command} and \ts{param}.
The mode must be \ts{``r''} or \ts{``w''}}

\ttt{\toindex{FtpOpenRead}(FTP~*,char~*filename)}
{ Opens file named \ts{filename} for reading on server}

\ttt{\toindex{FtpOpenWrite}(FTP~*,char~*filename)}
{ Creates and opens file named \ts{filename} for writing on server}

\ttt{\toindex{FtpOpenAppend}(FTP~*,char~*filename)}
{ Creates and opens file named \ts{filename} for appending on server}

\ttt{\toindex{FtpOpenDir}(FTP~*, char~*files)}
{
Creates channel for directory list reading, described by argument \ts{files}.
}

\ttt{STATUS \toindex{FtpRead}(FTP~*)}{
Reads character from data stream. If \ts{ASCII} mode is set\footnote{By default} converts new line markers.
When the end of file is detected or channel is broken, returns \toindex{EOF}}

\ttt{\toindex{FtpWrite}(FTP~*, char~c)}{
Writes single character to stream, if \ts{ASCII} mode is set converts new line markers.
When channel is broken, returns \toindex{EOF}}

\ttt{int \toindex{FtpGetc}(FTP~*,FILE~*fp)}{
Reads character from data stream specified by fp. Using macros FTPDATA and FTPCMD you can specify stream need for reading. \footnote{Functions FtpGetc and FtpPutc ignores data stream mode, works as binary always}
}

\ttt{STATUS \toindex{FtpPutc}(FTP~*,FILE~*fp, char c)}{
Writes character to data stream specified by fp. Using macros FTPDATA and
FTPCMD you can specify stream need for reading. \footnote{Functions
FtpGetc and FtpPutc ignores data stream mode, works as binary always}
}


\ttt{\toindex{FtpClose}(FTP~*)}
{Closes opened channel to server}

\subsection{Other commands for server}

\ttt{\toindex{FtpCommand}(FTP~*, char~*command, char~*param, int~ok1, ok2, ok3, ..., okN, EOF)}
{ Sends a command, composed from \ts{command} and \ts{param} using \ts{sprintf} function.
Reads an answer from the server.
When return code from the server is not included to \ts{ok-list}(\ts{ok1},\ts{ok2}...) the sign of code
will be inverted.}


\ttt{\toindex{FtpType}(FTP~*,char~mode)}
{Sets transfer mode, such as \ts{'A'},\ts{'I'},\ts{'S'},etc...}

\ttt{\toindex{FtpBinary}(FTP~*)}
{Sets binary mode}

\ttt{\toindex{FtpAscii}(FTP~*)}
{Sets \ts{ASCII} mode}


\ttt{\toindex{FtpMkdir}(FTP~*,char *dirname)}
{Makes directory on server}

\ttt{\toindex{FtpChdir}(FTP~*,char *dirname)}
{Changes working directory on server}

\ttt{\toindex{FtpChmod}(FTP~*,char *file, int mode)}
{Changes protection of file at remote server, argument mode is protection like inside regular stat's structure.}

\ttt{\toindex{FtpRm}(FTP~*,char *filename)}
{Removes file on server}

\ttt{char~*\toindex{FtpPwd}(FTP~*)}
{Returns the name of working directory on server}

\ttt{int \toindex{FtpSize}(FTP~*,char *filename)}
{Returned size (in bytes) of description's file.}

\ttt{STATUS \toindex{FtpStat}(FTP~*,char~*paten,FTP\_STAT **stat\_list)}
{Get information about files specified by ``paten''. This function is parser
of text output of command ls or dir on UNIX's, VMS's and MSDOS's operating systems.
The basic problem of realization last one is very different syntaxes of output of
different realization of UNIX's, ftp's daemons and programs such as ``ls'' for making
output list. So.... This function give your garanty of right work only if you use
Berkeley's ftpd or wuftpd on UNIX, PC TCP/IP on MSDOS and Multinet on AXP and VAX VMS's
systems, otherwise function returns empty list}

\ttt{STATUS \toindex{FtpStatFree}(FTP\_STAT *)}
{Free memory from data structures}

\ttt{char *\toindex{FtpSyst}(FTP~*)}{FtpStat return name of operating system on remote server}


\ttt{\toindex{FtpMove}(FTP~*,char *oldfilename, char *newfilename)}
{Renames file from \ts{oldfilename} to \ts{newfilename}}

\ttt{\toindex{FtpPort}(FTP~*, int~a, int~b, int~c, int~d, int~e, int~f)
\footnote{Recommended in non-trivial situations}
}
{ A command for the server for making a new data channel. \ts{a.b.c.d} is an IP address of a client(i.e. your IP address),
\ts{e*256+f} is a port number}


\ttt{struct hostent *\toindex{FtpGetHost}(char *hostname)
\footnote{Extension of standard function ``gethostbyname''}
}
{Returned pointer to structure \ts{hostent} creating using string
\ts{hostname}, which contains name of the computer or its IP
address~\footnote{For example''dxunk8.oea.ihep.su'' or ``192.102.229.71''}
}


\subsection{Functions for sending/receiving control messages to/from server}

\ttt{\toindex{FtpSendMessage}(FTP~*, char~*message)}
{Sends a message to the server}

\ttt{int \toindex{FtpGetMessage}(FTP~*)}
{Receives a message from the server.}

\ttt{\toindex{FtpMessage}(int Number)}
{Gets a message by code.}

\ttt{\toindex{FtpNumber}(char *Message)}
{Extract message's number from string.}

\subsection{High-level functions}

\ttt{FILE *\toindex{FtpFullOpen}(char *filename,char *mode)}
{
Parses string \ts{filename}, which must contain a string in format or \\
\ts{host/user/password:filename} or \ts{filename},
what corresponds to remote or local file. The second argument is the type of opening, divided into two characters:
first --- the mode of opening \ts{``r''}, \ts{``w''} or \ts{``a''}, second is the transfer type , if contains character \ts{``b''},
then the mode is binary.
}

\ttt{STATUS \toindex{FtpFullClose}(FILE *)}
{
Close file opened by FtpFullOpen.
}

\ttt{STATUS \toindex{FtpFullSyntax}(FtpString source,FtpString host,FtpString user,FtpString password,FtpString file)}
{Make out string ``source'' for next four parameters.}

\ttt{FILE *\toindex{Ftpfopen}(char *file, char *mode)}
{
Open file specified in libftp's file specification. Works like
\ts{fopen}. \look{FTP}
}

\ttt{STATUS \toindex{Ftpfclose}(FILE *fp)}
{
Close file which opened using Ftpfopen. Works like fclose.
}

\ttt{STATUS \toindex{FtpArchie}
\footnote{FtpArchie for making list and specification of searched files runs
``archie'' which must be accessible for execution in one of directories listed in PATH environment variable}
(char *what, ARCHIE *result, int number)}{
Find \ts{number} entrys in Archie's database enrolls described by \ts{what}
argument. \ts{result} must be pointer to array of Archie's structures number
of which must be equivalence or higher than \ts{number}. This call return
number of entrys which found in database. If FtpArchie return value lower
than zero then pointed target not found or archie isn't works}

\ttt{STATUS \toindex{FtpHttpGet}(char *server, int port, char *spec, char *out)}
\label{FtpHttpGet}
{
This function transfers file from remote computer thru HTTP-server, which must
be described by two firsts arguments server and port. Object which must be took
(probably ftp's file) must be described as HTTP objects. This function always returns
one of several answers such as:

\begin{itemize}
\item[OK] Object was transfered correctly.
\item[QUIT] Socket's communication problem, need to repeat request again.
\item[LQUIT] Problems with opening local file,
probably no disk space or permitions problems, need to check regular errno
variable.
\item[ENOENT] Specified object doesn't exists.
\end{itemize}
}


\section{Simple example of using LIBFTP}

Next example demonstrate very simple using library calls only Ftpfopen
and Ftpfclose functions which discriminate libftp's file specification:

\input example

For tests works this program you can try run one as:

\bigskip

\% example username/password@hostname:filename myfile.out

\% example myfile.input username/password@hostname:filename.out


\newpage
\input libftp.ind
\newpage
\tableofcontents
\end{document}


\End\Of\Shar\
else
echo "will not over write ./doc/libftp.tex"
fi
echo "Finished archive 1 of 8"
exit


Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 64
Archive-Name: libftp-5.0/part03

#!/bin/sh
# to extract, remove the header and type "sh filename"

if `test ! -d ./utils`
then
mkdir ./utils
echo "mkdir ./utils"
fi
if `test ! -s ./utils/uftp_tab.c`
then
echo "writing ./utils/uftp_tab.c"
cat > ./utils/uftp_tab.c << '\End\Of\Shar\'
#include <uftp.h>

TOKEN *root = NULL;

TOKEN *get_pointer(TOKEN*,char*);


TOKEN *new_token()
{
TOKEN *n=(TOKEN *)malloc(sizeof(TOKEN));

bzero(n,sizeof(TOKEN));

return n;
}



load_key(char *s)
{
TOKEN *cur=root,*prev=NULL;
char *cw;
int i;

for (i=1; (*(cw=word(s,i))) != '\0'; i++)
{
if (cur==NULL)
{
cur=new_token();

if (root==NULL) root=cur;

if (prev!=NULL) prev->shift=cur;

strcpy(cur->word,cw);
prev=cur;
cur=cur->shift;
}
else
{
while ( strcmp(cur->word,cw) !=0 && cur->next != NULL &&
cur->word[0]!=0 )
cur=cur->next;

if (strcmp(cur->word,cw)==0 || cur->word[0]==0)
{
strcpy(cur->word,cw);
prev=cur;
cur=cur->shift;
continue; /* Take next word from string */
}

cur->next=new_token();
cur=cur->next;
strcpy(cur->word,cw);
prev=cur;
cur=cur->shift;

}
}
}

load_link(char *s1,char *s2)
{
TOKEN *t1,*t2;

load_key(s1);
load_key(s2);

t1=get_pointer(root,s1);
t2=get_pointer(root,s2);

if (t1->shift==NULL) t1->shift=new_token();
if (t2->shift!=NULL) free(t2->shift);
t2->shift=t1->shift;
}

compctl_hook(char *buf, int plen, int *loc)
{
TOKEN *cur=root;
int i,ii,lc;
TOKEN *nw;
LIST *list=NULL;
char *cw,*p;

for (i=1;/**/;i++)
{
FtpString r={0};

cw=word(buf,i);

if ((nw=get_pointer(cur,cw))!=NULL &&
(*word(buf,i+1)!=0 || buf[strlen(buf)-1]==' '))
{
cur=nw->shift;
continue;
}

if (*word(buf,i+1)!=0)
return;

for (;cur!=NULL;cur=cur->next)
if (strncmp(cur->word,cw,strlen(cw))==0)
list_add(&list,cur->word);

lc = list_count(&list);

if (lc==0)
return;


if (lc==1)
{
for (ii=1;ii<i;ii++) strcpy(r,makestr(r,word(buf,ii),NULL));
strcpy(r,makestr(r,list->item,NULL));

for (ii=i+1;*(p=word(buf,ii))!=0;ii++)
strcpy(r,makestr(r,word(buf,ii),NULL));

strcpy(buf,r);
strcat(buf," ");
break;
}

if (*(char*)word(buf,i+1)!=0)
{
cur=nw->shift;
continue;
}

printlist(&list);

for (ii=1;ii<i;ii++) strcpy(r,makestr(r,word(buf,ii),NULL));

strcpy(buf,makestr(r,p=common_space(list,cw),NULL));

if (*p==0 && *cw==0 ) strcat(buf," ");

break;
}

if ( strlen(buf) == 1 && buf[0]==' ') buf[0]=0;

*loc=strlen(buf);

gl_redraw_r();
return -2;

}

print_ctl(char *msg1, TOKEN *t)
{
FtpString tmp;

if (t==NULL) t=root;

for (;t!=NULL;t=t->next)
{
sprintf(tmp,"%s %s",msg1,t->word);

if (t->shift!=0)
print_ctl(tmp,t->shift);
else
puts(tmp);
}
}

TOKEN *get_pointer(TOKEN *cur,char *cw)
{
while (cur!=NULL)
{
if (strcmp(cur->word,cw)==0) return cur;
cur=cur->next;
}
return NULL;
}

char *common_space(LIST *valid, char *item)
{
LIST *new=NULL;
LIST *t;
int i,item_len=strlen(item);
static FtpString result;

result[0]=0;

for (t=valid;t!=NULL;t=t->next)
if (!strncmp(item,t->item,item_len))
list_add(&new,t->item);


if (new!=NULL)
for (i=0; ;i++) /* Compared space */
for(t=new;t!=NULL;t=t->next)
if (new->item[i]!=t->item[i] || t->item[i]==0 )
{
if (i>0)
{
strcpy(result,new->item);
result[i]=0;
}
list_init(&new);
return result;
}
return result;
}

printlist(LIST **list)
{
LIST *t;
int maxlen,n,ncols;
FtpString format;

gl_char_cleanup();
fputc ('\n',stderr);

list_sort(list);

for(maxlen=0,t=(*list);t!=NULL;t=t->next)
if ((n=strlen(t->item))>maxlen) maxlen=n;

maxlen++;

ncols=winsize/maxlen;

if (ncols==0) ncols=1;

sprintf(format,"%%-%ds",maxlen);

for (n=0,t=(*list);t!=NULL;t=t->next,n++,n%=ncols)
{
fprintf(stderr,format,t->item);
if (n+1==ncols) fputc('\n',stderr);
}

if (n!=0) fputc('\n',stderr);

gl_char_init();
gl_redraw_r();
}

\End\Of\Shar\
else
echo "will not over write ./utils/uftp_tab.c"
fi
if `test ! -s ./utils/uftpcmd.c`
then
echo "writing ./utils/uftpcmd.c"
cat > ./utils/uftpcmd.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: uftpcmd.c,v 5.0 1995/12/10 10:34:21 orel Exp $";

/*
$Log: uftpcmd.c,v $
* Revision 5.0 1995/12/10 10:34:21 orel
* LIBFTP Version 5.0 (Distributed revision)
*
* Revision 4.6 1995/12/02 11:24:01 orel
* pathes for proxy get thru www-daemon
*
* Revision 4.5 1995/11/19 09:50:08 orel
* Modify flag for reopen
* modify reopen itself
* for remaking connection when last lost
*
* Revision 4.4 1995/09/09 09:51:49 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.3 1995/09/09 07:48:33 orel
* Some corrections for trafic log file
*
* Revision 4.2 1995/08/19 18:42:25 orel
* *** empty log message ***
*
* Revision 4.1 1995/07/17 15:27:59 orel
* Correct bug in help command
*
* Revision 4.0 1995/07/11 14:51:08 orel
* Libftp version 4.0
*
* Revision 3.4 1995/07/04 13:37:12 orel
* chenge compctl function
*
* Revision 3.3 1995/07/02 08:39:06 orel
* remove alias for "user" as "login"
*
* Revision 3.2 1995/06/21 09:28:34 orel
* Porting to AIX and some modification..........
*
* Revision 3.1 1995/06/20 15:54:28 orel
* Porting to AIX
*
* Revision 3.0 1995/03/20 05:26:29 orel
* *** empty log message ***
*
* Revision 2.17 1995/03/20 05:17:54 orel
* *** empty log message ***
*
* Revision 2.16 1995/03/20 05:17:31 orel
* *** empty log message ***
*
* Revision 2.16 1995/03/20 05:17:31 orel
* *** empty log message ***
*
* Revision 2.15 1995/03/16 09:38:04 orel
* modify help
* add save(s) funcs
* replace readline to getline
* etc...
*
* Revision 2.14 1995/03/07 16:01:40 orel
* *** empty log message ***
*
* Revision 2.13 1995/03/05 15:02:08 orel
* *** empty log message ***
*
* Revision 2.12 1995/02/26 16:41:21 orel
* add recursive rm and recursive put
*
* Revision 2.11 1995/02/26 12:44:02 orel
* *** empty log message ***
*
* Revision 2.10 1995/02/18 15:42:27 orel
* add recursive mget
*
* Revision 2.9 1995/02/17 12:53:18 orel
* add parallel put
*
* Revision 2.8 1995/02/17 12:47:14 orel
* add parallel mget
*
* Revision 2.7 1995/02/13 16:05:10 orel
* add setargs call
*
* Revision 2.7 1995/02/13 16:05:10 orel
* add setargs call
*
* Revision 2.6 1995/02/13 12:08:16 orel
* Add save sets
*
* Revision 2.5 1995/02/08 17:31:53 orel
* *** empty log message ***
*
* Revision 2.4 1995/02/04 09:12:51 orel
* rcs id
*
* Revision 2.4 1995/02/04 09:12:51 orel
* rcs id
*

*/
#include "uftp.h"

jmp_buf connectstack;

Ftp_connect_hook(FTP *ftp,int code, char *msg)
{
FtpLog(ftp->title,msg);
longjmp(connectstack,1);

}

Ftp_connect(ARGS)
{
STATUS (*func1)(),(*func2)();

if (*w2==0)
{
w2=getline("Host:");
if (strchr(w2,'\n')!=NULL)
*(char *)strchr(w2,'\n')=0;
else
longjmp(start,1);
}

if (FtpGetHost(w2)==NULL && FtpInit.IO != NULL)
{
char *msg;
extern int h_errno;

switch(h_errno)
{
case HOST_NOT_FOUND: msg = "Host unknown"; break;
case TRY_AGAIN: msg = "Hostname lookup failure";break;
default: msg = "gethostbyname failure";
}
return (*FtpInit.IO)(LINK,QUIT,msg);
}

newframe(0);

func1 = FtpInit.error;
func2 = FtpInit.IO;

if (trymode)
{
FtpSetErrorHandler(&FtpInit,Ftp_connect_hook);
FtpSetIOHandler(&FtpInit,Ftp_connect_hook);
setjmp(connectstack);
}

list_add(&hosts,w2);

FtpConnect(&LINK,w2);
strcpy(iftp[frame].host,FtpGetHost(w2)->h_name);

FtpSetErrorHandler(LINK,func1);
FtpSetErrorHandler(&FtpInit,func1);
FtpSetIOHandler(LINK,func2);
FtpSetIOHandler(&FtpInit,func2);

return;
}

Ftp_preconnect(ARGS)
{
FtpString host;
FtpString pass;

gethostname(host, sizeof host);
strcpy(host,FtpGetHost(host)->h_name);
sprintf(pass,"%s@%s",getpwuid(getuid())->pw_name,host);

newframe(0);


if (*w2==0)
{
w2=getline("Host:");
if (strchr(w2,'\n')!=NULL)
*(char *)strchr(w2,'\n')=0;
else
longjmp(start,1);
}
strcpy(iftp[frame].host,w2);

if (*w3==0)
w3=defaultuser;
strcpy(iftp[frame].user,w3);

if (*w4==0)
w4=pass;
strcpy(iftp[frame].pass,w4);

if (*w5==0)
w5=".";

strcpy(iftp[frame].pwd,w5);

iftp[frame].lock=0;

ftp[frame]=FtpCreateObject();

}


Ftp_user(ARGS)
{
FtpString tmp;

if (*w2==0)
{
sprintf(tmp,"login (default %s):",defaultuser);
w2=getline(tmp);
if (strchr(w2,'\n')!=NULL)
*(char *)strchr(w2,'\n')=0;
else
longjmp(start,1);
if (*w2==0)
w2=defaultuser;
}
strcpy(iftp[frame].user,w2);
strcpy(iftp[frame].pass,w3);
if (FtpUser(LINK,w2)==331) Ftp_pass("",w3,"","","","");
}

Ftp_pass(ARGS)
{
FtpString tmp;

if (*w2==0)
{
FtpString pass;
FtpString host;

gethostname(host, sizeof host);
strcpy(host,FtpGetHost(host)->h_name);
sprintf(pass,"%s@%s",getpwuid(getuid())->pw_name,host);
sprintf(tmp,"Password (default %s):",pass);
w2=(char*)getpass(tmp);
if (*w2==0) w2=pass;
}

strcpy(iftp[frame].pass,w2);
FtpPassword(LINK,w2);
strcpy(iftp[frame].pwd,FtpPwd(LINK));
}


Ftp_HTTP_open(ARGS)
{
int c;
FtpString protocol,host,path,file;
FTP_STAT *stat=NULL;
char *p;

/* ftp://hostname.domain/path/file */

if ( (c=sscanf ( w2, "%[^:]://%[^/]/%s", protocol, host, path )) <2 )
return 0;

if (strcasecmp(protocol,"ftp")!=0) return 0;

if (c==2) strcpy(path,"/");

if ((p=strrchr(path,'/'))!=NULL)
{
strcpy(file,p+1);
*(p-1)=0;
}
else
{
strcpy(file,path);
strcpy(path,"/");
}

if (!*path) strcpy(path,"/");

Ftp_ftp("ftp",host,path,"","","");

FtpStat(LINK,file,&stat);

if (stat==NULL) return 1;

if (stat->type=='d') Ftp_cd(LINK,file,"","","","");
if (stat->type=='-')
{
Ftp_get("get",file,"","","","");
if (!interactive) Ftp_quit("","","","","","");
}
return 1;
}

Ftp_open(ARGS)
{

STATUS (*err)();

/* There two possibilities to describe future connection:
1st: host user passwd dir
1nd: HTML-spec

*/

if (Ftp_HTTP_open(w1,w2,"","","",""))
return;


Ftp_connect("",w2,"","","","");
Ftp_user("",w3,w4,"","","" );
if (ifalias("autologin")) execute("autologin");
if (*w5)
Ftp_cd("cd",w5,"","","","");
}

Ftp_reopen(ARGS)
{
FtpString host,user,pass,pwd;

strcpy(host,iftp[frame].host);
strcpy(user,iftp[frame].user);
strcpy(pass,iftp[frame].pass);
strcpy(pwd,iftp[frame].pwd);


if ( host[0]!=0 )
{
Ftp_close(NULLARGS);
Ftp_open("",host,user,pass,pwd,"");
}
else
{
log("Need at least hostname");
}
}

Ftp_ftp(ARGS)
{
FtpString pass;
FtpString host;

/* There two possibilities to describe future connection:
1st: host dir
1nd: HTML-spec

*/

if (Ftp_HTTP_open(w1,w2,"","","",""))
return;


gethostname(host, sizeof host);
strcpy(host,FtpGetHost(host)->h_name);
sprintf(pass,"%s@%s",getpwuid(getuid())->pw_name,host);

Ftp_open("",w2,"anonymous",pass,w3,"");
return;
}

Ftp_quit(ARGS)
{
quit(0);
}

Ftp_mput_handler()
{
log("File(s) or directory not found");
longjmp(start,1);
}


Ftp_lcd(ARGS)
{
glob_t gl;
FtpString tmp;

bzero(&gl,sizeof gl);

glob(w2,GLOB_BRACE|GLOB_TILDE|GLOB_QUOTE,
Ftp_mput_handler, &gl);


if (gl.gl_matchc<1 || chdir(*gl.gl_pathv))
perror(w2);

fprintf(stderr,"Local directory is \"%s\"\n",getwd(tmp));
}

Ftp_close(ARGS)
{
register int i;

if (isdigit(*w2))
{
i=atoi(w2);
}
else
{
i=frame;
}

FtpQuickBye(ftp[i]);

iftp[i].host[0]=0;
iftp[i].pwd[0]=0;
ftp[i]=NULL;
newframe(1);
}


INLINE SetLogicalVar(char arg, int * var, char *msg)
{
switch(arg)
{

case 'y':

*var=1;
break;

case 'n':

*var=0;
break;

default:

(*var)?(*var=0):(*var=1);
break;
}
}

Ftp_set(ARGS)
{
if (!strcmp("frame",w2))
return atoi(w3)<NFRAMES?frame=atoi(w3):0;

if (!strcmp("timeout",w2))
{
FtpSetTimeout(&FtpInit,atoi(w3));
if (LINK!=0)
FtpSetTimeout(LINK,atoi(w3));
return;
}

if (!strcmp("sleep",w2))
{
sleeptime=atoi(w3);
return;
}

if (!strcmp("debug",w2))
{
if ( *w3=='y' || *w3==0)
{
if (LINK!=NULL) FtpSetDebugHandler(LINK,FtpDebugDebug);
FtpSetDebugHandler(&FtpInit,FtpDebugDebug);
return;
}
if ( *w3 == 'n')
{
if (LINK!=NULL) FtpSetDebugHandler(LINK,NULL);
FtpSetDebugHandler(&FtpInit,NULL);
return;
}
}

if (!strcmp("bin",w2))
{
if ( *w3=='y' || *w3==0)
{
FtpInit.mode='I';
return;
}
if ( *w3 == 'n')
{
FtpInit.mode='A';
return;
}
}

if (!strcmp("try",w2))
return SetLogicalVar(*w3,&trymode,"Try mode");
if (!strcmp("hash",w2))
return SetLogicalVar(*w3,&hashmode,"Hash mode");
if (!strcmp("rest",w2)||!strcmp(w2,"restore"))
return SetLogicalVar(*w3,&restmode,"Restore mode");

if (!strcmp("prompt",w2))
{
strcpy(prompt,w3);
return;
}

if (!strcmp("port",w2))
{
if ( isdigit(*w3))
return FtpSetPort(&FtpInit,atoi(w3));
return;
}

if (!strcmp("wwwport",w2))
{
if ( isdigit(*w3))
return www_port=atoi(w3);
return;
}

if (!strcmp("wwwgateway",w2))
{
strcpy(www_gateway,w3);
return;
}

if (!strcmp("noopinterval",w2)||!strcmp("noop",w2))
{
if ( isdigit(*w3))
return noopinterval=(time_t)atoi(w3);
fputs("Time must be number\n",stderr);
return;
}

if (!strcmp("nooptimeout",w2))
{
if ( isdigit(*w3))
return nooptimeout=(time_t)atoi(w3);
fputs("Time must be number\n",stderr);
return;
}

if (!strcmp("user",w2))
{
strcpy(defaultuser,w3);
return;
}

if (!strcmp("",w2))
{

fprintf(stderr,"frime %d\n",frame);
fprintf(stderr,"timeout %d secs\n",FtpInit.timeout.tv_sec);
fprintf(stderr,"sleep time %d secs\n",sleeptime);
fprintf(stderr,"debug %s\n",(FtpInit.debug!=NULL)?"enable":"disable");
fprintf(stderr,"try mode %s\n",trymode?"enable":"disable");
fprintf(stderr,"hash mode %s\n",hashmode?"enable":"disable");
fprintf(stderr,"restore mode %s\n",restmode?"enable":"disable");
fprintf(stderr,"automatic binary mode %s\n",(FtpInit.mode=='I')?"enable":"disable");
fprintf(stderr,"prompt \"%s\"\n",prompt);
fprintf(stderr,"port %d\n",FtpInit.port);
fprintf(stderr,"noop interval %d\n",noopinterval);
fprintf(stderr,"noop timeout %d\n",nooptimeout);
fprintf(stderr,"wwwgateway %s\n",www_gateway);
fprintf(stderr,"wwwport %d\n",www_port);
fprintf(stderr,"Default login name \"%s\"\n",defaultuser);
fflush(stderr);
return;
}
return puts("arg 2 unknown");

}

jmp_buf getstack;

Ftp_get_hook(FTP *con,int code, char *msg)
{

if ( abs(code)==553 || (abs(code)==550 && FtpBadReply550(msg)) )
{
FtpLog(con->title,msg);
log("Transfer cancel");
longjmp(getstack,2);
}

if ( code == LQUIT )
{
log(msg);
log("Transfer leave after I/O error with local file");
longjmp(getstack,2);
}



FtpLog(con->title,msg);
FtpQuickBye(LINK);
LINK=NULL;

log("sleeping......");
sleep(sleeptime);
log("try again...");

longjmp(getstack,1);

}

void Ftp_get_intr(int sig)
{
signal(SIGINT,intr);
log("Transfer interupt");
Ftp_abort();
longjmp(start,3);
}

Ftp_get(ARGS)
{
FTP OldInit;
register int status=0;
char *in="",*out="";
FtpString myhostname;



OldInit=FtpInit;

if (restmode)
FtpSetFlag(LINK,FTP_REST);
else
FtpClearFlag(LINK,FTP_REST);

if (trymode)
{
FtpSetErrorHandler(LINK,Ftp_get_hook);
FtpSetIOHandler(LINK,Ftp_get_hook);
FtpInit= (*LINK);
FTPCMD(&FtpInit)=FTPCMD(&OldInit);
FTPDATA(&FtpInit)=FTPDATA(&OldInit);
}

signal(SIGINT,Ftp_get_intr);
FtpSetHashHandler(LINK,NULL);


if ((status=setjmp(getstack))==2||status==3)
goto done;

if ((LINK==NULL)||(LINK->sock==FtpInit.sock))
{
FtpLogin(&LINK,iftp[frame].host,iftp[frame].user,
iftp[frame].pass,NULL);
FtpChdir(LINK,iftp[frame].pwd);
}

if ((hashmode && isatty(fileno(stderr)) &&
strstr(w1,"dir")==NULL && strstr(w1,"ls")==NULL))
FtpSetHashHandler(LINK,myhash);
else
FtpSetHashHandler(LINK,NULL);

myhash(LINK,0);

gethostname(myhostname, sizeof myhostname);

if (strstr(w1,"get")!=NULL)
{
FtpGet(LINK,in=w2,out=makefilename(w2,w3));
log_traffic(LINK->title,myhostname,in,out,LINK->counter);
}

if (strstr(w1,"put")!=NULL)
{
FtpPut(LINK,in=w2,out=makefilename(w2,w3));
log_traffic(myhostname,LINK->title,in,out,LINK->counter);
}

if (strstr(w1,"dir")!=NULL)
FtpRetr(LINK,(*w2==0)?"LIST":"LIST %s",makestr(w2,w3,w4,w5,w6,NULL),"-");

if (strstr(w1,"ls")!=NULL)
FtpRetr(LINK,(*w2==0)?"NLST":"NLST %s",makestr(w2,w3,w4,w5,w6,NULL),"-");

if (LINK->debug!=NULL) log("Transfer complete");


done:

if (LINK!=NULL)
{
FtpSetHashHandler(LINK,NULL);
FtpSetErrorHandler(LINK,my_error);
FtpSetIOHandler(LINK,my_error);
FtpClearFlag(LINK,FTP_REST);
}
FtpInit=OldInit;
}


Ftp_mget(ARGS)
{
FTP_STAT *ftpstat, *first;
FtpString local;
FtpString pwd;

if (LINK==NULL || FTPCMD(LINK)==NULL )
Ftp_reopen(NULLARGS);

while (FtpError(FtpStatus(LINK,FtpStat(LINK,w2,&ftpstat))))
{
FtpStatFree(ftpstat);
Ftp_reopen(NULLARGS);
}

first = ftpstat;

strcpy(pwd,FtpPwd(LINK));
strcpy(iftp[frame].pwd,pwd);
getcwd(local,sizeof local);

while (ftpstat!=NULL)
{

if (ftpstat->type=='-')
{
FtpString tmp;
struct stat st;

if (stat(ftpstat->name,&st)==-1 || st.st_size < ftpstat->size)
{

sprintf(tmp,"get %s/%s",pwd,ftpstat->name);
log(tmp);
Ftp_get("get",ftpstat->name,"","","","");
chmod(ftpstat->name,ftpstat->mode);
}
}

if (ftpstat->type=='l')
symlink(ftpstat->link,ftpstat->name);

ftpstat=ftpstat->next;
}

ftpstat=first;

while(ftpstat!=NULL)
{
if ( ftpstat -> type == 'd' &&
strcmp(ftpstat->name,".")!=0 &&
strcmp(ftpstat->name,"..")!=0 &&
((mkdir(ftpstat->name,ftpstat->mode),chdir(ftpstat->name))!=-1) &&
!FtpError(FtpStatus(LINK,FtpChdir(LINK,ftpstat->name))))
{
Ftp_mget(NULLARGS);
FtpChdir(LINK,pwd);
}

chdir(local);
ftpstat=ftpstat->next;

}


strcpy(iftp[frame].pwd,pwd);

FtpStatFree(first);

}

Ftp_proxyget(ARGS)
{
switch (FtpHttpGet(www_gateway,www_port,w2,""))
{

case LQUIT:
FtpLog("proxyget","error util work with local file");
break;

case QUIT:
FtpLog("proxyget","communication problem");
break;

case OK:
FtpLog("proxyget","Transfer complete");
break;

case ENOENT:
FtpLog("proxyget","No such file or directory (on remote host)");
break;

default:
FtpLog("proxyget","strange answer from libftp");
}
}

Ftp_rm(ARGS)
{
FTP_STAT *ftpstat, *first;
FtpString local;
FtpString pwd,tmp;

while (FtpError(FtpStatus(LINK,FtpStat(LINK,w2,&ftpstat))))
{
FtpStatFree(ftpstat);
Ftp_reopen(NULLARGS);
}

first = ftpstat;

strcpy(pwd,FtpPwd(LINK));
strcpy(iftp[frame].pwd,pwd);
getcwd(local,sizeof local);

for (;ftpstat!=NULL;ftpstat=ftpstat->next)
if (ftpstat->type!='d')
FtpStatus(LINK,FtpRm(LINK,ftpstat->name)),
sprintf(tmp,"rm %s/%s",pwd,ftpstat->name),
log(tmp);

for (ftpstat=first;ftpstat!=NULL;ftpstat=ftpstat->next)
if ( ftpstat -> type == 'd' &&
!FtpError(FtpStatus(LINK,FtpChdir(LINK,ftpstat->name))))
{
Ftp_rm(NULLARGS);
chdir(local);
FtpChdir(LINK,pwd);
FtpStatus(LINK,FtpCommand(LINK,"XRMD %s",ftpstat->name,0,EOF));
}

strcpy(iftp[frame].pwd,pwd);
FtpStatFree(first);

}

Ftp_copy(ARGS)
{
char *p;
int in,out;

if ( !*w2 || !*w3 ) return puts("Must pass two args");

if ((p=strchr(w2,'!'))!=NULL)
{
*p=0;
in=atoi(w2);
w2=p+1;
}
else
in=frame;

if ((p=strchr(w3,'!'))!=NULL)
{
*p=0;
out=atoi(w3);
w3=p+1;
}
else
in=frame;

if (in==out) return puts("Files must been from different frames");

FtpCopy(ftp[in],ftp[out],w2,w3);
}

Ftp_ccopy(ARGS)
{
char *p;
int in,out;

if ( !*w2 || !*w3 ) return puts("Must pass two args");

if ((p=strchr(w2,'!'))!=NULL)
{
*p=0;
in=atoi(w2);
w2=p+1;
}
else
in=frame;

if ((p=strchr(w3,'!'))!=NULL)
{
*p=0;
out=atoi(w3);
w3=p+1;
}
else
in=frame;

if (in==out) return puts("Files must been from different frames");

FtpPassiveTransfer(ftp[in],ftp[out],w2,w3);
}

Ftp_bin(ARGS)
{
FtpBinary(LINK);
}

Ftp_ascii(ARGS)
{
FtpAscii(LINK);
}

Ftp_cd(ARGS)
{
FtpChdir(LINK,w2);
strcpy(iftp[frame].pwd,FtpPwd(LINK));
if (ifalias("autocd")) execute("autocd");
}


Ftp_dup(ARGS)
{
LINKINFO oldinfo;
FTP oldftp;

oldinfo=iftp[frame];
oldftp=(*LINK);

newframe(0);
puts("Make alternative connection...");
Ftp_open("",oldinfo.host,oldinfo.user,oldinfo.pass,"","");
if (strcmp(oldinfo.pwd,iftp[frame].pwd))
Ftp_cd("",oldinfo.pwd,"","","","");
if (LINK->mode!=oldftp.mode)
FtpType(LINK,oldftp.mode);
LINK -> timeout = oldftp.timeout;
LINK -> flags = oldftp.flags;
FtpSetDebugHandler(LINK,oldftp.debug);
FtpSetErrorHandler(LINK,oldftp.error);
FtpSetIOHandler(LINK,oldftp.IO);
FtpSetHashHandler(LINK,oldftp.hash);
}


Ftp_bg(ARGS)
{
FtpString tmp;

if (fork())
{
log(makestr("Backgrounding \"",w2,w3,w4,w5,w6,"\"",NULL));
return;
}
else
{
int i=frame;

lastcmd=1;

/* Ignoring keypad */

alarm (0);
signal(SIGALRM,SIG_IGN);
signal(SIGURG,SIG_IGN);
signal(SIGPIPE,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGCHLD,SIG_IGN);
signal(SIGIO,SIG_IGN);

/* Droping output*/

sprintf(tmp,"/tmp/uftp-%s",getpwuid(getuid())->pw_name);
mkdir(tmp,0700);
sprintf(tmp,"/tmp/uftp-%s/logfile.XXXXXX",getpwuid(getuid())->pw_name);
mktemp(tmp);
close(0);close(1);close(2);
open(tmp,O_RDWR|O_TRUNC|O_CREAT,0600);
dup(0);dup(0);

if (LINK!=NULL)
{
Ftp_dup(NULLARGS);
free(ftp[i]);
ftp[i]=NULL;
}

executev(w2,w3,w4,w5,w6,"");
exit(0);
}
}

Ftp_list()
{
register int i;

#define _FMT "%-5s %-15s %-10s %-25s %-7s %-4s\n"
#define FMT "%-5d %-15s %-10s %-25s %-7d %-4d\n"

fprintf(stderr,_FMT,"Frame","Host name","User's name","Working directory","Timeout","Port");

for ( i = 0 ; i < NFRAMES ; i++ )
if (ftp[i]!=NULL)
fprintf(stderr,FMT,i,iftp[i].host,iftp[i].user,iftp[i].pwd,
ftp[i]->timeout.tv_sec,ftp[i]->port);
fflush(stderr);
return;
}

Ftp_abort(ARGS)
{
time_t save;

if (LINK!=NULL)
{
save = LINK ->timeout.tv_sec;
LINK->timeout.tv_sec = nooptimeout;
FtpAbort(LINK);
LINK->timeout.tv_sec = save;
}
}

Ftp_type(ARGS)
{
FtpGet(LINK,w2,"*STDOUT*");
}


Ftp_page(ARGS)
{
register char *pager;
FtpString out={'|',0};

if ((pager=(char *)getenv("PAGER"))==NULL)
pager="more";

strcat(out,pager);
FtpGet(LINK,w2,out);
}


Ftp_mkdir(ARGS)
{
FtpMkdir(LINK,w2);
}

Ftp_move(ARGS)
{
FtpMove(LINK,w2,w3);
}

Ftp_help(ARGS)
{
LIST *list=NULL;
register int i,ii,w2_len=strlen(w2);

if ( !*w2 )
{
for ( i = 0 ; cmds[i].cmd!=NULL ; i++)
list_add(&list,cmds[i].cmd);
}

else

for ( i = 0 ; cmds[i].cmd!=NULL; i++)
{
int len=strlen(cmds[i].cmd);
if (!strncmp(cmds[i].cmd,w2,MIN(len,w2_len)))
list_add(&list,cmds[i].help);
}

list_sort(&list);
printlist(&list);
list_init(&list);
}

Ftp_quote(ARGS)
{
FtpString new;

new[0]=0;

strcpy(new,makestr(w2,w3,w4,w5,w6,NULL));
FtpCommand(LINK,new,"",0,EOF);
}

Ftp_alias(ARGS)
{
ALIAS *a=firstalias;

if ( *w2==0 )
{
while (a!=NULL)
{
fprintf(stderr,"%s=%s\n",a->name,a->str);
a=a->next;
}
return;
}


while (1)
{

if ( a == NULL )
{
firstalias = a = (ALIAS *) malloc(sizeof(ALIAS));
memset(a,0,sizeof(ALIAS));
a -> next = NULL;
break;
}

if (!strcmp(a->name,w2))
break;

if ( a->next == NULL)
{
a -> next = (ALIAS *) malloc(sizeof(ALIAS));
a = a->next;
memset(a,0,sizeof(ALIAS));
a -> next = NULL;
break;
}
a=a->next;
}

strcpy(a -> name,w2);
strcpy(a -> str,makestr(w3,w4,w5,w6,NULL));
}

Ftp_mkalias(ARGS)
{
FtpString new;

if (!*w2) return puts("Arg must present\n");

sprintf(new,"open \"%s\" \"%s\" \"%s\" \"%s\"",
iftp[frame].host,iftp[frame].user,
iftp[frame].pass,iftp[frame].pwd);

Ftp_alias("alias",w2,new,"","","");
}

Ftp_unalias(ARGS)
{
ALIAS *cur,*prev;

cur=prev=firstalias;

while ( cur != NULL )
{
if (!strcmp(cur->name,w2))
{
if ( cur == firstalias )
{
firstalias = cur->next;
free(cur);
return;
}
prev -> next = cur -> next;
free(cur);
}
prev=cur;
cur=cur->next;
}
}


Ftp_save_aliases(ARGS)
{
ALIAS *a=firstalias;
FILE *out;

if ((out=fopen (getaliasrcname(),"w"))==NULL)
{
perror(getaliasrcname());
return;
}

while (a!=NULL)
{
fprintf(out,"alias %s '%s'\n",a->name,a->str);
a=a->next;
}

fclose(out);

chmod ( getaliasrcname(), 0600);
}

Ftp_save_sets(ARGS)
{
FILE *out;
FtpString newprompt;
char *p1=prompt, *p2=newprompt;

if ((out=fopen (getsetsrcname(),"w"))==NULL)
{
perror(getaliasrcname());
return;
}

fprintf(out,"set timeout %d\n",FtpInit.timeout.tv_sec);
fprintf(out,"set sleep %d\n",sleeptime);
fprintf(out,"set debug %c\n",(FtpInit.debug!=NULL)?'y':'n');
fprintf(out,"set try %c\n",trymode?'y':'n');
fprintf(out,"set hash %c\n",hashmode?'y':'n');
fprintf(out,"set rest %c\n",restmode?'y':'n');
fprintf(out,"set bin %c\n", (FtpInit.mode=='I')?'y':'n');

while (*p1)
{
if (*p1=='>'||*p1=='<') *p2++='\\';
*p2++ = *p1++;
}

*p2=0;

fprintf(out,"set prompt '%s'\n",newprompt);

fprintf(out,"set port %d\n",FtpInit.port);
fprintf(out,"set noopinterval %d\n",noopinterval);
fprintf(out,"set nooptimeout %d\n",nooptimeout);
fprintf(out,"set user '%s'\n",defaultuser);

fclose(out);

chmod ( getsetsrcname(), 0600);

}


#define ARCHIE_MAX_TARGETS 20

Ftp_acd(ARGS)
{
static int targets=0;
static FtpString what={0};
static ARCHIE result[ARCHIE_MAX_TARGETS];
FtpString tmp;

int i, selected_target;

char *p;


if ( (what[0] == 0 || strcmp(w2,what) != 0) && *w2!=0 )
{
if ((targets=FtpArchie(w2,result,ARCHIE_MAX_TARGETS))<1)
return puts("Archie failure or target not found");
strcpy(what,w2);
}

for (i=0;i<targets;i++)
fprintf(stderr,"%2d %s:%s\n",i,result[i].host,result[i].file);

if (strcmp(w1,"archie")==0)
return;


p = getline("Your selection? ");

if (strchr(p,'\n')!=NULL)
*(char *)strchr(p,'\n')=0;
else
longjmp(start,1);

if (*word(p,1)==0) return;

selected_target = atoi(p);


if (strcmp(w1,"acd")==0 || *(strrchr(result[selected_target].file,'/')+1)=='\0' )
{
strcpy(tmp,result[selected_target].file);
*(char*)strrchr(tmp,'/')=0;

Ftp_ftp("ftp",result[selected_target].host,tmp,"","","");
}
else
{
Ftp_ftp("ftp",result[selected_target].host,"","","","");
Ftp_get("get",result[selected_target].file,"","","","");
}

}

Ftp_aaget(ARGS)
{
ARCHIE result[ARCHIE_MAX_TARGETS];
int targets;
int maxsize;
register int i;
FtpString pass,host,tmp;
FTP save;

if (*w2==0)
{
printf("%s <filename>\n",w1);
return;
}

if ((targets=FtpArchie(w2,result,ARCHIE_MAX_TARGETS))<1)
{
printf("Specified file not found by archie\n");
return;
}

gethostname(host, sizeof host);
sprintf(pass,"%s@%s",getpwuid(getuid())->pw_name,FtpGetHost(host)->h_name);

for (i=0,maxsize=0;i<targets;i++)
if (result[i].size>maxsize) maxsize=result[i].size;

for (i=0; ; i++,(i==targets)?i=0:i)
{
FTP *ftp;

if (result[i].size<maxsize) continue;

save=FtpInit;

FtpSetIOHandler(&FtpInit,NULL);
FtpSetErrorHandler(&FtpInit,NULL);

sprintf(tmp,"Retrive file %s from %s.....",result[i].file,result[i].host);
FtpLog("aaget",tmp);


if (FtpError(FtpLogin(&ftp,result[i].host,"anonymous",pass,NULL)) ||
FtpError(FtpGet(ftp,result[i].file,strrchr(result[i].file,'/')+1)))
{
FtpQuickBye(ftp);
continue;
}
FtpQuickBye(ftp);
break;
}

FtpInit=save;

}


INLINE char filetype(char *name)
{
struct stat st;

if (stat(name,&st)==-1) return '0';

if ( S_IFREG == (st.st_mode & S_IFMT)) return '-';
if ( S_IFDIR == (st.st_mode & S_IFMT)) return 'd';

return '?';
}

Ftp_mput(ARGS)
{
glob_t gl;
char **args;
int nargs;
int chmod_status=0;
FtpString local,pwd;
FtpString tmp;

glob((*w2==0)?"*":w2,GLOB_BRACE|GLOB_TILDE|GLOB_QUOTE,
Ftp_mput_handler, &gl);

nargs=gl.gl_matchc;
args=gl.gl_pathv;

while(nargs--)
{
if (filetype(*args)=='-')
{
struct stat st;

getcwd(local,sizeof local);

sprintf(tmp,"put %s/%s",local,*args);
log(tmp);

Ftp_get("put",*args,"","","","");
stat(*args,&st);
if (chmod_status>=0)
chmod_status=FtpStatus(LINK,FtpChmod(LINK,*args,st.st_mode&0777));
}
args++;
}

nargs=gl.gl_matchc;
args=gl.gl_pathv;

while(nargs--)
{
if (filetype(*args)=='d')
{
getcwd(local,sizeof local);

if (chdir(*args)==-1) continue;

strcpy(pwd,iftp[frame].pwd);

FtpStatus(LINK,FtpMkdir(LINK,*args));

if (!FtpError(FtpStatus(LINK,FtpChdir(LINK,*args))))
{
Ftp_mput(NULLARGS);
FtpChdir(LINK,pwd);
}

chdir(local);
}
args++;
}
}


Ftp_env(ARGS)
{

if (!strcmp(w1,"setenv")) return setenv(w2,w3);
if (!strcmp(w1,"unsetenv")) return unsetenv(w2);
if (!strcmp(w1,"env")) return printenv();
}

Ftp_compctl(ARGS)
{
if (*w2==0) return print_ctl("compctl",NULL);
load_key(makestr(w2,w3,w4,w5,w6,NULL));
}


CMDS cmds[]={

"compctl", Ftp_compctl, 0,
"compctl command arg1 arg2... - load complition map",

"connect", Ftp_connect, 0,
"connect <hostname> - make new ftp connection",

"preconnect", Ftp_preconnect, 0,
"preconnect <hostname> <user> <password> <path> - make fictivity ftp connection",

"open", Ftp_open, 0,
"open <hostname> <user> <pass> <directory> - login to server",

"reopen", Ftp_reopen, 0,
"reopen - Open again connection with existing frame information",

"ftp", Ftp_ftp, 0,
"ftp <hostname> - anonymously login to server",

"close", Ftp_close, 1,
"close - Close connection",

"quit", Ftp_quit, 0,
"quit - Exit from uftp",


"exit", Ftp_quit, 0,
"exit - Exit from uftp",


"set", Ftp_set, 0,
"set - Set variables: (Without args print current settings)\n\
frame <number> - select another session(frame)\n\
timeout <secs> - Set network timeout\n\
nooptimeout <secs>- Set network timeout with clearing timeout\n\
noop <secs> - Set time interval for sending NOOP operator\n\
to server for erased delay\n\
sleep <secs> - Set pause beetween transfer attempt\n\
debug <y|n> - Set debuging ftp's protocol (Default no)\n\
try <y|n> - Set retransfer mode with broken network (Default yes)\n\
hash <y|n> - Set hashing transfer (Default no)\n\
restore <y|n> - Set retransfer mode (reget/reput) (Default yes!!!!)\n\
bin <y|n> - Set automatic turn on binary mode (Default no) \n\
prompt <string> - Set prompt (See help prompt)\n\
port <number> - Set ftpd's port for next sessions\n\
user <name> - Set default user name (default you name)",

"setenv", Ftp_env, 0,
"setenv - Set enviroment variable",

"unsetenv", Ftp_env, 0,
"unsetenv - Unset enviroment variable",

"env", Ftp_env, 0,
"env - Print enviroment variables",


"prompt", NULL, 0,
"\
prompt is a string, which may be contains %<char>
or ^<char> combitanion, which have next interprets:

%H, %h - full and short remote host names
%M, %m - full and short local host names
%u - remote user's name
%d - remote current directory
%D - local current directory
%f - number of current frame
%p - the ftp's port number
%t - timeout
%T - current time
%P - uftp process id
%% - character %
^<char>- control character
%^ - character ^
",

"list", Ftp_list, 0,
"list - List session's information",

"user", Ftp_user, 1,
"user <user> - send user's name",

"pass", Ftp_pass, 1,
"pass <pass> - send user's password",

"bin", Ftp_bin, 1,
"bin - Set binary mode for current frame",

"ascii", Ftp_ascii, 1,
"ascii - Set ASCII mode for current frame",

"cd", Ftp_cd, 1,
"cd <directory> - change current remote directory ",

"acd", Ftp_acd, 0,
"acd <file_or_directory> - search pointed directory using archie, and setup connection to it",

"lcd", Ftp_lcd, 0,
"lcd <directory> - Change local directory",

"abort", Ftp_abort, 1,
"abort - abort last operation",

"mkdir", Ftp_mkdir, 1,
"mkdir <dirname> - create new directory",

"rm", Ftp_rm, 1,
"rm <filename_spec> - remove file(s)",

"mv", Ftp_move, 1,
"mv <old> <new> - rename file",

"dir", Ftp_get, 1,
"dir <argslist> ... - print list of files",

"ls", Ftp_get, 1,
"ls <arglist> ... - print short list of files",

"get", Ftp_get, 1,
"get <remote_file> [<local_file>] - receive file from server",

"pget", Ftp_proxyget, 0,
"pget <http_spec> [<local_file>] - receive file from server thru HTTP proxy server",

"mget", Ftp_mget, 1,
"mget <remote_file(s)> - recursive receive file(s) from server",

"aget", Ftp_acd, 0,
"aget <file> - search pointed file using archie, and retrive it",

"aaget", Ftp_aaget, 0,
"aaget <file> - search pointed file using archie, and retrive it from anywhere",

"put", Ftp_get, 1,
"put <local_file> [<remote_file>] - send server to file",

"mput", Ftp_mput, 1,
"mput <local_file(s)> - recursive send file(s) to server",

"copy", Ftp_copy, 1,
"copy [<frame>!]file [<frame>!]file - copy file via client cache",

"ccopy", Ftp_ccopy, 1,
"ccopy [<frame>!]file [<frame>!]file - copy file directly beetween servers",

"cat", Ftp_type, 1,
"cat <file> - print body of remote file to screen",

"page", Ftp_page, 1,
"page <file> - print body of remote file to screen via pager",

"bg", Ftp_bg, 0,
"bg <any_command> - run command(s) backgroundly (output redirect to file),\n\
You can also add &-char to back of line without \"bg\"",

"archie", Ftp_acd, 0,
"archie - Find file using archie service and display to screen",

"dup", Ftp_dup, 1,
"dup - Make new analogous frame",

"quote", Ftp_quote, 1,
"quote <some_string> - send command directly to server",

"help", Ftp_help, 0,
"help <command> - print list of commands or command description",

"alias", Ftp_alias, 0,
"\
alias aliasname <list> .... - make new alias, use $X for taking \n\
X's argument from command string, and $* for taking\n\
all arguments. If $<anything> on alias not present,\n\
the arguments appending to end of command string",

"unalias", Ftp_unalias, 0,
"unalias <aliasname> - remove alias",

"mkalias", Ftp_mkalias, 0,
"mkalias <Alias_name> - make alias for create this frame, use save for saving it to file",

"savealiases", Ftp_save_aliases, 0,
"savealiases - Save aliases to file",

"savesets", Ftp_save_sets, 0,
"savesets - Save sets to file",

"etc", NULL, 0,
"\
1. In any command you may use constructions <file and >file for\n\
redirect input output.\n\
\n\
2. All local files files interprets as libftp file(s), \n\
this support next specification:\n\
\n\
|string - interprets string as shell command, which must be\n\
execute and input or output take from/to it.\n\
\n\
\n\
*STDIN*, *STDOUT*, *STDERR* - opened streams.\n\
\n\
anything - local file name.\n\
\n\
3. Command started with '!' passed to shell.\n
\n\
4. If string beetween two \" or \', its interprets as one word.\n\
\n\
5. Any string may be devide to few commands using ';'.",

NULL

};

\End\Of\Shar\
else
echo "will not over write ./utils/uftpcmd.c"
fi


if `test ! -d ./doc`
then
mkdir ./doc
echo "mkdir ./doc"
fi

if `test ! -s ./doc/example.c`
then
echo "writing ./doc/example.c"
cat > ./doc/example.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: example.c,v 5.0 1995/12/10 10:37:11 orel Exp $";

/*
$Log: example.c,v $
* Revision 5.0 1995/12/10 10:37:11 orel
* LIBFTP Version 5.0 (Distributed revision)
*

*/

/* Include standard libftp's header */

#include <FtpLibrary.h>

main(int argc, char *argv[])
{

FILE *input,*output;
int c;

if (argc<3)
exit(fprintf(stderr,"Usage: %s input-file output-file\n",argv[0]));

FtplibDebug(yes);

if ((input=Ftpfopen(argv[1],"r"))==NULL)
{
perror(argv[1]);
exit(1);
}

if ((output=Ftpfopen(argv[2],"w"))==NULL)
{
perror(argv[2]);
exit(1);
}

while ( (c=getc(input)) != EOF && (putc(c,output)!=EOF) );

if (ferror(input))
{
perror(argv[1]);
exit(1);
}

if (ferror(output))
{
perror(argv[1]);
exit(1);
}

Ftpfclose(input);
Ftpfclose(output);

exit(0);

}
\End\Of\Shar\
else
echo "will not over write ./doc/example.c"
fi
echo "Finished archive 3 of 8"
exit


Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 66
Archive-Name: libftp-5.0/part05

#!/bin/sh
# to extract, remove the header and type "sh filename"

if `test ! -d ./utils`
then
mkdir ./utils
echo "mkdir ./utils"

fi
if `test ! -s ./utils/getline.h`
then
echo "writing ./utils/getline.h"
cat > ./utils/getline.h << '\End\Of\Shar\'
#ifndef GETLINE_H
#define GETLINE_H

/* unix systems can #define POSIX to use termios, otherwise
* the bsd or sysv interface will be used
*/

char *getline(); /* read a line of input */
void gl_setwidth(); /* specify width of screen */
void gl_histadd(); /* adds entries to hist */
void gl_strwidth(); /* to bind gl_strlen */

extern int (*gl_in_hook)();
extern int (*gl_out_hook)();
extern int (*gl_tab_hook)();

#endif /* GETLINE_H */
\End\Of\Shar\
else
echo "will not over write ./utils/getline.h"
fi
if `test ! -s ./utils/glob.c`
then
echo "writing ./utils/glob.c"
cat > ./utils/glob.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: glob.c,v 5.0 1995/12/10 10:34:21 orel Exp $";

/*
$Log: glob.c,v $


* Revision 5.0 1995/12/10 10:34:21 orel
* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.2 1995/09/09 09:51:49 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.2 1995/09/09 09:51:49 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/08/19 18:42:25 orel


* *** empty log message ***
*

* Revision 4.1 1995/08/19 18:42:25 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 14:51:08 orel
* Libftp version 4.0
*
* Revision 4.0 1995/07/11 14:51:08 orel
* Libftp version 4.0
*

* Revision 3.1 1995/06/21 09:28:34 orel


* Porting to AIX and some modification..........
*

* Revision 3.1 1995/06/21 09:28:34 orel


* Porting to AIX and some modification..........
*

* Revision 3.0 1995/03/20 05:26:29 orel
* *** empty log message ***
*
* Revision 3.0 1995/03/20 05:26:29 orel
* *** empty log message ***
*

* Revision 2.7 1995/03/20 05:17:47 orel


* *** empty log message ***
*

* Revision 2.7 1995/03/20 05:17:47 orel


* *** empty log message ***
*

* Revision 2.6 1995/03/16 09:38:04 orel


* *** empty log message ***
*

* Revision 2.6 1995/03/16 09:38:04 orel


* *** empty log message ***
*

* Revision 2.5 1995/03/05 15:02:08 orel


* *** empty log message ***
*

* Revision 2.5 1995/03/05 15:02:08 orel


* *** empty log message ***
*

* Revision 2.4 1995/02/26 12:44:02 orel


* *** empty log message ***
*

* Revision 2.4 1995/02/26 12:44:02 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/13 16:05:45 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/13 16:05:45 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/08 17:31:53 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/08 17:31:53 orel


* *** empty log message ***
*

* Revision 2.1 1995/02/04 09:12:51 orel
* rcs id
*
* Revision 2.1 1995/02/04 09:12:51 orel
* rcs id
*

*/
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93";
#endif /* LIBC_SCCS and not lint */

/*
* glob(3) -- a superset of the one defined in POSIX 1003.2.
*
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
*
* Optional extra services, controlled by flags not defined by POSIX:
*
* GLOB_QUOTE:
* Escaping convention: \ inhibits any special meaning the following
* character might have (except \ at end of string is retained).
* GLOB_MAGCHAR:
* Set in gl_flags if pattern contained a globbing character.
* GLOB_NOMAGIC:
* Same as GLOB_NOCHECK, but it will only append pattern if it did
* not contain any magic characters. [Used in csh style globbing]
* GLOB_ALTDIRFUNC:
* Use alternately specified directory access functions.
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/

#include <sys/param.h>
#include <sys/stat.h>

#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <glob.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define DOLLAR '$'
#define DOT '.'
#define EOS '\0'
#define LBRACKET '['
#define NOT '!'
#define QUESTION '?'
#define QUOTE '\\'
#define RANGE '-'
#define RBRACKET ']'
#define SEP '/'
#define STAR '*'
#define TILDE '~'
#define UNDERSCORE '_'
#define LBRACE '{'
#define RBRACE '}'
#define SLASH '/'
#define COMMA ','

#ifndef DEBUG

#define M_QUOTE 0x8000
#define M_PROTECT 0x4000
#define M_MASK 0xffff
#define M_ASCII 0x00ff

typedef u_short Char;

#else

#define M_QUOTE 0x80
#define M_PROTECT 0x40
#define M_MASK 0xff
#define M_ASCII 0x7f

typedef char Char;

#endif


#define CHAR(c) ((Char)((c)&M_ASCII))
#define META(c) ((Char)((c)|M_QUOTE))
#define M_ALL META('*')
#define M_END META(']')
#define M_NOT META('!')
#define M_ONE META('?')
#define M_RNG META('-')
#define M_SET META('[')
#define ismeta(c) (((c)&M_QUOTE) != 0)


static int compare __P((const void *, const void *));
static void g_Ctoc __P((const Char *, char *));
static int g_lstat __P((Char *, struct stat *, glob_t *));
static DIR *g_opendir __P((Char *, glob_t *));
static Char *g_strchr __P((Char *, int));
#ifdef notdef
static Char *g_strcat __P((Char *, const Char *));
#endif
static int g_stat __P((Char *, struct stat *, glob_t *));
static int glob0 __P((const Char *, glob_t *));
static int glob1 __P((Char *, glob_t *));
static int glob2 __P((Char *, Char *, Char *, glob_t *));
static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *));
static int globextend __P((const Char *, glob_t *));
static const Char * globtilde __P((const Char *, Char *, glob_t *));
static int globexp1 __P((const Char *, glob_t *));
static int globexp2 __P((const Char *, const Char *, glob_t *, int *));
static int match __P((Char *, Char *, Char *));
#ifdef DEBUG
static void qprintf __P((const char *, Char *));
#endif

int
glob(pattern, flags, errfunc, pglob)
const char *pattern;
int flags, (*errfunc) __P((const char *, int));
glob_t *pglob;
{
const u_char *patnext;
int c;
Char *bufnext, *bufend, patbuf[MAXPATHLEN+1];

patnext = (u_char *) pattern;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;

bufnext = patbuf;
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_QUOTE) {
/* Protect the quoted characters. */
while (bufnext < bufend && (c = *patnext++) != EOS)
if (c == QUOTE) {
if ((c = *patnext++) == EOS) {
c = QUOTE;
--patnext;
}
*bufnext++ = c | M_PROTECT;
}
else
*bufnext++ = c;
}
else
while (bufnext < bufend && (c = *patnext++) != EOS)
*bufnext++ = c;
*bufnext = EOS;

if (flags & GLOB_BRACE)
return globexp1(patbuf, pglob);
else
return glob0(patbuf, pglob);
}

/*
* Expand recursively a glob {} pattern. When there is no more expansion
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
static int globexp1(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char* ptr = pattern;
int rv;

/* Protect a single {}, for find(1), like csh */
if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS)
return glob0(pattern, pglob);

while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL)
if (!globexp2(ptr, pattern, pglob, &rv))
return rv;

return glob0(pattern, pglob);
}


/*
* Recursive brace globbing helper. Tries to expand a single brace.
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
static int globexp2(ptr, pattern, pglob, rv)
const Char *ptr, *pattern;
glob_t *pglob;
int *rv;
{
int i;
Char *lm, *ls;
const Char *pe, *pm, *pl;
Char patbuf[MAXPATHLEN + 1];

/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
continue;
ls = lm;

/* Find the balanced brace */
for (i = 0, pe = ++ptr; *pe; pe++)
if (*pe == LBRACKET) {
/* Ignore everything between [] */
for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++)
continue;
if (*pe == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pe = pm;
}
}
else if (*pe == LBRACE)
i++;
else if (*pe == RBRACE) {
if (i == 0)
break;
i--;
}

/* Non matching braces; just glob the pattern */
if (i != 0 || *pe == EOS) {
*rv = glob0(patbuf, pglob);
return 0;
}

for (i = 0, pl = pm = ptr; pm <= pe; pm++)
switch (*pm) {
case LBRACKET:
/* Ignore everything between [] */
for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++)
continue;
if (*pm == EOS) {
/*
* We could not find a matching RBRACKET.
* Ignore and just look for RBRACE
*/
pm = pl;
}
break;

case LBRACE:
i++;
break;

case RBRACE:
if (i) {
i--;
break;
}
/* FALLTHROUGH */
case COMMA:
if (i && *pm == COMMA)
break;
else {
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
/*
* Append the rest of the pattern after the
* closing brace
*/
for (pl = pe + 1; (*lm++ = *pl++) != EOS;)
continue;

/* Expand the current pattern */
#ifdef DEBUG
qfprintf(stderr,"globexp2:", patbuf);
#endif
*rv = globexp1(patbuf, pglob);

/* move after the comma, to the next string */
pl = pm + 1;
}
break;

default:
break;
}
*rv = 0;
return 0;
}

/*
* expand tilde from the passwd file.
*/
static const Char *
globtilde(pattern, patbuf, pglob)
const Char *pattern;
Char *patbuf;
glob_t *pglob;
{
struct passwd *pwd;
char *h;
const Char *p;
Char *b;

if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;

/* Copy up to the end of the string or / */
for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH;
*h++ = *p++)
continue;

*h = EOS;

if (((char *) patbuf)[0] == EOS) {
/*
* handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
if ((h = getenv("HOME")) == NULL) {
if ((pwd = getpwuid(getuid())) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
}
else {
/*
* Expand a ~user
*/
if ((pwd = getpwnam((char*) patbuf)) == NULL)
return pattern;
else
h = pwd->pw_dir;
}

/* Copy the home directory */
for (b = patbuf; *h; *b++ = *h++)
continue;

/* Append the rest of the pattern */
while ((*b++ = *p++) != EOS)
continue;

return patbuf;
}

/*
* The main glob() routine: compiles the pattern (optionally processing
* quotes), calls glob1() to do the real pattern matching, and finally
* sorts the list (unless unsorted operation is requested). Returns 0
* if things went well, nonzero if errors occurred. It is not an error
* to find no matches.
*/
static int
glob0(pattern, pglob)
const Char *pattern;
glob_t *pglob;
{
const Char *qpatnext;
int c, err, oldpathc;
Char *bufnext, patbuf[MAXPATHLEN+1];

qpatnext = globtilde(pattern, patbuf, pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;

/* We don't need to check for buffer overflow any more. */
while ((c = *qpatnext++) != EOS) {
switch (c) {
case LBRACKET:
c = *qpatnext;
if (c == NOT)
++qpatnext;
if (*qpatnext == EOS ||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
*bufnext++ = LBRACKET;
if (c == NOT)
--qpatnext;
break;
}
*bufnext++ = M_SET;
if (c == NOT)
*bufnext++ = M_NOT;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
if (*qpatnext == RANGE &&
(c = qpatnext[1]) != RBRACKET) {
*bufnext++ = M_RNG;
*bufnext++ = CHAR(c);
qpatnext += 2;
}
} while ((c = *qpatnext++) != RBRACKET);
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_END;
break;
case QUESTION:
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_ONE;
break;
case STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
/* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
*bufnext++ = M_ALL;
break;
default:
*bufnext++ = CHAR(c);
break;
}
}
*bufnext = EOS;
#ifdef DEBUG
qfprintf(stderr,"glob0:", patbuf);
#endif

if ((err = glob1(patbuf, pglob)) != 0)
return(err);

/*
* If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
if (pglob->gl_pathc == oldpathc &&
((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
return(globextend(pattern, pglob));
else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
}

static int
compare(p, q)
const void *p, *q;
{
return(strcmp(*(char **)p, *(char **)q));
}

static int
glob1(pattern, pglob)
Char *pattern;
glob_t *pglob;
{
Char pathbuf[MAXPATHLEN+1];

/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == EOS)
return(0);
return(glob2(pathbuf, pathbuf, pattern, pglob));
}

/*
* The functions glob2 and glob3 are mutually recursive; there is one level
* of recursion for each segment in the pattern that contains one or more
* meta characters.
*/
static int
glob2(pathbuf, pathend, pattern, pglob)
Char *pathbuf, *pathend, *pattern;
glob_t *pglob;
{
struct stat sb;
Char *p, *q;
int anymeta;

/*
* Loop over pattern segments until end of pattern or until
* segment with meta character found.
*/
for (anymeta = 0;;) {
if (*pattern == EOS) { /* End of pattern? */
*pathend = EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);

if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != SEP) && (S_ISDIR(sb.st_mode)
#ifdef S_ISLNK
|| (S_ISLNK(sb.st_mode) &&
#else
|| ( (sb.st_mode&S_IFLNK) &&
#endif
(g_stat(pathbuf, &sb, pglob) == 0) &&
S_ISDIR(sb.st_mode)))) {
*pathend++ = SEP;
*pathend = EOS;
}
++pglob->gl_matchc;
return(globextend(pathbuf, pglob));
}

/* Find end of next segment, copy tentatively to pathend. */
q = pathend;
p = pattern;
while (*p != EOS && *p != SEP) {
if (ismeta(*p))
anymeta = 1;
*q++ = *p++;
}

if (!anymeta) { /* No expansion, do next segment. */
pathend = q;
pattern = p;
while (*pattern == SEP)
*pathend++ = *pattern++;
} else /* Need expansion, recurse. */
return(glob3(pathbuf, pathend, pattern, p, pglob));
}
/* NOTREACHED */
}

static int
glob3(pathbuf, pathend, pattern, restpattern, pglob)
Char *pathbuf, *pathend, *pattern, *restpattern;
glob_t *pglob;
{
register struct dirent *dp;
DIR *dirp;
int err;
char buf[MAXPATHLEN];

/*
* The readdirfunc declaration can't be prototyped, because it is
* assigned, below, to two functions which are prototyped in glob.h
* and dirent.h as taking pointers to differently typed opaque
* structures.
*/
struct dirent *(*readdirfunc)();

*pathend = EOS;
errno = 0;

if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
g_Ctoc(pathbuf, buf);
if (pglob->gl_errfunc(buf, errno) ||
pglob->gl_flags & GLOB_ERR)
return (GLOB_ABEND);
}
return(0);
}

err = 0;

/* Search directory for matching names. */
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
readdirfunc = pglob->gl_readdir;
else
readdirfunc = readdir;
while ((dp = (*readdirfunc)(dirp))) {
register u_char *sc;
register Char *dc;

/* Initial DOT must be matched literally. */
if (dp->d_name[0] == DOT && *pattern != DOT)
continue;
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
*pathend = EOS;
continue;
}
err = glob2(pathbuf, --dc, restpattern, pglob);
if (err)
break;
}

if (pglob->gl_flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir)(dirp);
else
closedir(dirp);
return(err);
}


/*
* Extend the gl_pathv member of a glob_t structure to accomodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
* crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
* behavior.
*
* Return 0 if new item added, error code if memory couldn't be allocated.
*
* Invariant of the glob_t structure:
* Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
*/
static int
globextend(path, pglob)
const Char *path;
glob_t *pglob;
{
register char **pathv;
register int i;
u_int newsize;
char *copy;
const Char *p;

newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ?
realloc((char *)pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL)
return(GLOB_NOSPACE);

if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
/* first time around -- clear initial gl_offs items */
pathv += pglob->gl_offs;
for (i = pglob->gl_offs; --i >= 0; )
*--pathv = NULL;
}
pglob->gl_pathv = pathv;

for (p = path; *p++;)
continue;
if ((copy = malloc(p - path)) != NULL) {
g_Ctoc(path, copy);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
}
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
return(copy == NULL ? GLOB_NOSPACE : 0);
}


/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
*/
static int
match(name, pat, patend)
register Char *name, *pat, *patend;
{
int ok, negate_range;
Char c, k;

while (pat < patend) {
c = *pat++;
switch (c & M_MASK) {
case M_ALL:
if (pat == patend)
return(1);
do
if (match(name, pat, patend))
return(1);
while (*name++ != EOS);
return(0);
case M_ONE:
if (*name++ == EOS)
return(0);
break;
case M_SET:
ok = 0;
if ((k = *name++) == EOS)
return(0);
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
if (c <= k && k <= pat[1])
ok = 1;
pat += 2;
} else if (c == k)
ok = 1;
if (ok == negate_range)
return(0);
break;
default:
if (*name++ != c)
return(0);
break;
}
}
return(*name == EOS);
}

/* Free allocated data belonging to a glob_t structure. */
void
globfree(pglob)
glob_t *pglob;
{
register int i;
register char **pp;

if (pglob->gl_pathv != NULL) {
pp = pglob->gl_pathv + pglob->gl_offs;
for (i = pglob->gl_pathc; i--; ++pp)
if (*pp)
free(*pp);
free(pglob->gl_pathv);
}
}

static DIR *
g_opendir(str, pglob)
register Char *str;
glob_t *pglob;
{
char buf[MAXPATHLEN];

if (!*str)
strcpy(buf, ".");
else
g_Ctoc(str, buf);

if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_opendir)(buf));

return(opendir(buf));
}

static int
g_lstat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];

g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_lstat)(buf, sb));
return(lstat(buf, sb));
}

static int
g_stat(fn, sb, pglob)
register Char *fn;
struct stat *sb;
glob_t *pglob;
{
char buf[MAXPATHLEN];

g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_stat)(buf, sb));
return(stat(buf, sb));
}

static Char *
g_strchr(str, ch)
Char *str;
int ch;
{
do {
if (*str == ch)
return (str);
} while (*str++);
return (NULL);
}

#ifdef notdef
static Char *
g_strcat(dst, src)
Char *dst;
const Char* src;
{
Char *sdst = dst;

while (*dst++)
continue;
--dst;
while((*dst++ = *src++) != EOS)
continue;

return (sdst);
}
#endif

static void
g_Ctoc(str, buf)
register const Char *str;
char *buf;
{
register char *dc;

for (dc = buf; (*dc++ = *str++) != EOS;)
continue;
}

#ifdef DEBUG
static void
qprintf(str, s)
const char *str;
register Char *s;
{
register Char *p;

(void)fprintf(stderr,"%s:\n", str);
for (p = s; *p; p++)
(void)fprintf(stderr,"%c", CHAR(*p));
(void)fprintf(stderr,"\n");
for (p = s; *p; p++)
(void)fprintf(stderr,"%c", *p & M_PROTECT ? '"' : ' ');
(void)fprintf(stderr,"\n");
for (p = s; *p; p++)
(void)fprintf(stderr,"%c", ismeta(*p) ? '_' : ' ');
(void)fprintf(stderr,"\n");
}
#endif
\End\Of\Shar\
else
echo "will not over write ./utils/glob.c"
fi
echo "Finished archive 5 of 8"
exit


Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 68
Archive-Name: libftp-5.0/part07

#!/bin/sh
# to extract, remove the header and type "sh filename"

if `test ! -s ./FtpIO.c`
then
echo "writing ./FtpIO.c"
cat > ./FtpIO.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpIO.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpIO.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.6 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.5 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.5 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.4 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.4 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.3 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.3 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/* Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the exist
ing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

int FtpRead(FTP *con)
{
int c;

if ( con -> mode == 'I' )
return FtpGetc(con,FTPDATA(con));

if ( con->ch != EOF )
{
c=con->ch;
con->ch=EOF;
return c;
}

c=FtpGetc(con,FTPDATA(con));

if ( c == Ctrl('M') )
{
c = FtpGetc(con,FTPDATA(con));

if ( c == Ctrl('J') )
return '\n';
con->ch = c;
return Ctrl('M');
}
return c;
}

int FtpWrite(FTP *ftp,char c)
{

if ( ftp -> mode == 'I' || c != '\n' )
return FtpPutc(ftp,FTPDATA(ftp),c);

FtpPutc(ftp,FTPDATA(ftp),Ctrl('M'));
return FtpPutc(ftp,FTPDATA(ftp),Ctrl('J'));
}


int FtpGetc(FTP *ftp,FILE *fp)
{
fd_set fds;
char c;

FD_ZERO(&fds);
FD_SET(fileno(fp),&fds);

if (select(getdtablesize(), &fds, 0, 0, &(ftp->timeout))<1)
return EXIT(ftp,QUIT);

if (read(fileno(fp),&c,1)<1)
return EOF;

if (ftp->hash!=NULL) (*ftp->hash)(ftp,1);

return (int)c;
}


STATUS FtpPutc(FTP *ftp,FILE *fp,char c)
{
fd_set fds;

FD_ZERO(&fds);
FD_SET(fileno(fp),&fds);

if (select(getdtablesize(), 0, &fds, 0, &(ftp->timeout))<1)
return EXIT(ftp,QUIT);

if (write(fileno(fp),&c,1)!=1)
return EXIT(ftp,QUIT);

if (ftp->hash!=NULL) (*ftp->hash)(ftp,1);
}


STATUS FtpReadBlock(FTP *ftp, char *buffer, int size)
{
fd_set fds;
register int rsize,status;

FD_ZERO(&fds);
FD_SET(fileno(FTPDATA(ftp)),&fds);

if (select(getdtablesize(), &fds,0, 0, &(ftp->timeout))<1)
return EXIT(ftp,QUIT);


if ((rsize=read(fileno(FTPDATA(ftp)),buffer,size))<0)
return EXIT(ftp,QUIT);

if (ftp->hash!=NULL && rsize!=0) (*ftp->hash)(ftp,rsize);

if (ftp->mode == 'A')
{
char buffer2[size];
register int i,ii;

for (i=0,ii=0;i<rsize;i++,ii++)
if (buffer[i]==Ctrl('M')&&buffer[i+1]==Ctrl('J'))
buffer2[ii]='\n',i++;
else
buffer2[ii]=buffer[i];

rsize=ii;
bcopy(buffer2,buffer,rsize);
}
return rsize;
}


STATUS FtpWriteBlock(FTP *ftp, char *buffer, int size)
{
fd_set fds;
register int wsize;
char buffer2[size*2];

FD_ZERO(&fds);
FD_SET(fileno(FTPDATA(ftp)),&fds);

if (select(getdtablesize(), 0, &fds, 0, &(ftp->timeout))<1)
return EXIT(ftp,QUIT);


if (ftp->mode=='A')
{
register int i,ii;

for(i=0,ii=0;i<size;i++,ii++)
if (buffer[i]=='\n')
buffer2[ii++]=Ctrl('M'),buffer2[ii]=Ctrl('J');
else
buffer2[ii]=buffer[i];
buffer=buffer2;
size=ii;
}

if ((wsize=write(fileno(FTPDATA(ftp)),buffer,size))!=size)
return EXIT(ftp,QUIT);

if ( ftp->hash!=NULL && wsize!=0 ) (*ftp->hash)(ftp,wsize);

return wsize;
}


\End\Of\Shar\
else
echo "will not over write ./FtpIO.c"
fi
if `test ! -s ./FtpInit.c`
then
echo "writing ./FtpInit.c"
cat > ./FtpInit.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpInit.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpInit.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.4 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

FTP FtpInit = {
NULL, /*sock*/
NULL, /*data*/
'A', /*mode*/
0, /*errno*/
0, /*ch*/
NULL,NULL,NULL, NULL, /*funcs*/
0, /*seek*/
FTP_HANDLERS, /*flags*/
{120,0}, /*timeout 2 min*/
21, /*Port*/
0, /*Counter*/
};

FTP *FtpCreateObject()
{
FTP *new = (FTP *) malloc (sizeof(FTP));

bcopy(&FtpInit,new,sizeof(FTP));

return new;
}


\End\Of\Shar\
else
echo "will not over write ./FtpInit.c"
fi
if `test ! -s ./FtpLibrary.h`
then
echo "writing ./FtpLibrary.h"
cat > ./FtpLibrary.h << '\End\Of\Shar\'
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.


*/


#ifndef __FTPLIBRARY_H
#define __FTPLIBRARY_H


#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <sys/socket.h>
#include <errno.h>

#ifdef _AIX
#include <sys/select.h>
#endif

#include <arpa/ftp.h>
#include <netinet/in.h>
#include <netdb.h>
#include <varargs.h>
#include <arpa/telnet.h>
#include <sys/stat.h>
#include <strings.h>

extern char *sys_errlist[];
extern int errno;


/* Standard Macros & Definitions */

enum {FTP_REST=1,FTP_NOEXIT=2,FTP_HANDLERS=4};


#define EXIT(con,e) \
( con -> errno = e, \
((con->flags&FTP_HANDLERS)&&(e==QUIT||e==LQUIT)&&(con->IO != NULL))?\
(*(con->IO))(con,e,sys_errlist[errno]):0,\
((con->flags&FTP_HANDLERS)&&(con->error != NULL) && (e < 0) )? \
(*(con->error))(con,e,FtpMessage(e)):0,\
e)


#define MAX_ANSWERS 10 /* Number of known goodest answers for reqest */
#define FTP_NFDS 64
#define FTPBUFSIZ BUFSIZ
#define LQUIT (-6)
#define QUIT (-5) /* Few time ago QUIT character been
equivalence to zero, changed for clear
conflicts with reading functions */
#define OK (0) /* Synonym for neitral good answer */
#define Ctrl(x) ((x) - '@')
#define FREE(x) memset ( &(x) , '\0' , sizeof (x) )
#define CUT(x) ((x)&0xff)
#define FtpStatus(ftp,what) \
( ((ftp)->flags&=~FTP_HANDLERS),(what),((ftp)->flags|=FTP_HANDLERS),\
((ftp)->errno) )
#define FtpError(what) ( (what)<0 )
#define FtpAssert(ftp,what) if (FtpError(what)) return EXIT((ftp),(ftp)->errno);

typedef int STATUS;
typedef char FtpString[256];

#ifdef __GNUC__
#define INLINE inline
#else
#define INLINE
#endif

/* Common Information Structure */

typedef struct/* All structure initialize from edited struct FtpInit */
{
FILE *sock; /* Command stream to server */

#define FTPDATA(x) ((x)->data)
#define FTPCMD(x) ((x)->sock)


FILE *data; /* Data stream to server */
char mode; /* Binary, Ascii, ......... */
int errno; /* Last error code */
int ch; /* Help character for ascii streams */

STATUS (*error)();
STATUS (*debug)();
STATUS (*IO)();
STATUS (*hash)(); /* Call with reading/writing next "int" characters
from stream */
int seek; /*
Warning! If server not supported REST-command,
then seek variable automaticaly turn to zero
*/
int flags; /* FTP_REST,
FTP_NOEXIT,
FTP_HANDLERS */
struct timeval timeout;
/* How long must be waiting next character
from server */
int port;
FtpString title; /* Using for FtpLog, FtpConnect lets hostname */
unsigned long counter;
/* Using by FtpHash */
} FTP;

typedef struct
{
struct tm createtime;
unsigned long size;
FtpString host;
FtpString file;
} ARCHIE;


typedef struct __ftp_stat__
{
char type; /* Type of file dir, regular, ..... */
int mode; /* Protections */
int inodes;
FtpString user;
FtpString group;
unsigned long size;
int month;
int day;
FtpString time;
FtpString name;
FtpString link;
struct __ftp_stat__ *next;
} FTP_STAT;


enum {no,yes};
enum {off,on};
enum {false,true};

extern FTP FtpInit;

/* Options defines */

#define FtpSetFlag(ftp,flag) ((ftp)->flags|=(flag))
#define FtpClearFlag(ftp,flag) ((ftp)->flags &= (~(flag)) )
#define FtpTestFlag(ftp,flag) ((ftp)->flags&(flag)==flag)
#define FtpSetTimeout(ftp,tim) \
((ftp)->timeout.tv_sec=tim,(ftp)->timeout.tv_usec=0)
#define FtpSetPort(ftp,prt) ((ftp)->port=(prt))

/* Connect & disconnect */

STATUS FtpConnect(FTP **con,char *hostname);
#define FtpUser(ftp,user) FtpCommand(ftp,"USER %s",user,230,331,332,EOF)
#define FtpPassword(ftp,pas) FtpCommand(ftp,"PASS %s",pas,230,332,EOF)
#define FtpAccount(ftp,acc) FtpCommand(ftp,"ACCT %s",acc,230,EOF)
STATUS FtpLogin(FTP **con,char *host ,char *user,char *pass,char *acct);
STATUS FtpBye (FTP * con);
STATUS FtpQuickBye (FTP * con);
STATUS FtpAbort(FTP *ftp);

/* Set type of transfer */

STATUS FtpType(FTP *ftp,char type);
#define FtpAscii(ftp) FtpType(ftp,'A')
#define FtpBinary(ftp) FtpType(ftp,'I')


/* Send/Receive and handling Procedure(s) */

STATUS FtpCopy(FTP *ftp1, FTP *ftp2, char *in, char *out);
STATUS FtpPassiveTransfer(FTP *ftp1, FTP *ftp2, char *in, char *out);

STATUS FtpRetr(FTP *con, char *command,char *inp,char *out);
#define FtpGet(ftp,in,out) FtpRetr(ftp,"RETR %s",in,out)
#define FtpDirectory(ftp,pat,out) FtpRetr(ftp,"LIST %s",pat,out)
#define FtpDir(ftp,out) FtpRetr(ftp,"LIST","",out)

STATUS FtpStor(FTP *con ,char*command ,char *inp,char *out);
#define FtpPut(ftp,in,out) FtpStor(ftp,"STOR %s",in,out)

STATUS FtpData( FTP * con , char * command , char * param , char *mode);
STATUS FtpPort ( FTP *con ,int ,int ,int ,int ,int ,int );
#define FtpOpenRead(ftp,file) FtpData(ftp,"RETR %s",file,"r")
#define FtpOpenWrite(ftp,file) FtpData(ftp,"STOR %s",file,"w")
#define FtpOpenAppend(ftp,file) FtpData(ftp,"APPE %s",file,"r")
STATUS FtpOpenDir( FTP * con , char * files );
STATUS FtpClose ( FTP *);

/* Command for hand transfer */

STATUS FtpRead ( FTP * con);
STATUS FtpWrite ( FTP * con , char c);
int FtpGetc ( FTP * ftp, FILE *fp );
STATUS FtpPutc (FTP *ftp, FILE *fp, char c);

/* Manipulation commands for remote server */

STATUS FtpCommand ();
#define FtpChdir(ftp,dir) FtpCommand(ftp,"CWD %s",dir,200,250,EOF)
#define FtpMkdir(ftp,dir) FtpCommand(ftp,"MKD %s",dir,200,257,EOF)
#define FtpRm(ftp,dir) FtpCommand(ftp,"DELE %s",dir,200,250,EOF)
STATUS FtpChmod(FTP *,char*file,int mode);
char *FtpPwd(FTP *con);
char *FtpSyst(FTP *con);
int FtpSize(FTP *con,char *filename);
STATUS FtpMove ( FTP *con,char * old,char *new);
STATUS FtpStat( FTP *con, char *pat, FTP_STAT **);
STATUS FtpStatFree(FTP_STAT *);

/* Procedures for dialog with remote server */

STATUS FtpInitMessageList();
STATUS FtpSendMessage( FTP * con , char * Message );
int FtpGetMessage( FTP * con , char * Message);
char *FtpMessage(int Number);
int FtpNumber ( char * Message );


/* Debug */

#define FtpSetErrorHandler(con,f) (con)->error = f
#define FtpSetDebugHandler(con,f) (con)->debug = f
#define FtpSetIOHandler(con,f) (con)->IO =f
#define FtpSetHashHandler(con,f) (con)->hash =f
#define FtplibDebug(t) FtpDebug(&FtpInit)

STATUS FtpDebugDebug ( FTP *con, int errno, char * Message);
STATUS FtpDebugError ( FTP *con, int errno, char * Message);
STATUS FtpDebugIO ( FTP *con, int errno, char * Message);
STATUS FtpLog(char *progtitle, char *msg);
STATUS FtpHash ( FTP *con, unsigned long number_of_bytes );
void FtpDebug ( FTP * con );
STATUS FtpBadReply550 (char *message);


/* Other Procedures */

FTP *FtpCreateObject();
FILE *FtpFullOpen(char * file,char * mode );
STATUS FtpFullSyntax(FtpString,FtpString,FtpString,FtpString,FtpString);
FILE *Ftpfopen(char *filename,char *mode);
STATUS Ftpfclose(FILE *);
STATUS FtpFullClose(FILE *);
STATUS FtpGood ();
STATUS FtpGood1 (int, int *);
struct hostent *FtpGetHost(char *host);
STATUS FtpFilenameChecher(char *input, char *output);
STATUS FtpLink(FTP *,FTP *);
int FtpArchie(char *what, ARCHIE *, int number);
char *word(char *s,int n);
STATUS FtpHttpGet(char *server,int port,char *spec, char *newfile);

#ifdef __cplusplus
}
#endif

/* Additional definitions */

#ifdef _AIX1
int accept (int, struct sockaddr_in*, int*);
char *bcopy (char*, char*, size_t);
int bind (int, const void*, int);
int connect (int, struct sockaddr_in*, int);
int gethostname (char*, size_t);
int getsockname (int, struct sockaddr_in*, int*);
int getpeername (int, struct sockaddr_in*, int*);
int getsockopt (int, int, int, void*, int*);
int listen(int, int);
int setsockopt (int, int, int, void*, int);
int socket (int, int, int);
void free (void*);
void *malloc (size_t);
#endif


#endif /* __FTPLIBRARYH_ */

\End\Of\Shar\
else
echo "will not over write ./FtpLibrary.h"
fi
if `test ! -s ./FtpLogin.c`
then
echo "writing ./FtpLogin.c"
cat > ./FtpLogin.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpLogin.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpLogin.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.4 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpLogin ( FTP ** con, char * host , char * user ,
char * password , char * account)
{

FtpAssert((*con),FtpConnect(con,host));
FtpAssert((*con),FtpUser((*con),user));
if (((*con)->errno)==230 )
return ((*con)->errno);
if (((*con)->errno)==332)
{
if ( account == NULL )
return EXIT(((*con)),(*con)->errno);
FtpAssert((*con),FtpAccount( (*con) , account ));
if ( ((*con)->errno)==230 )
return (*con)->errno;
}
return FtpPassword((*con),password);
}
\End\Of\Shar\
else
echo "will not over write ./FtpLogin.c"
fi
if `test ! -s ./FtpMessage.c`
then
echo "writing ./FtpMessage.c"
cat > ./FtpMessage.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpMessage.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpMessage.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.4 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"


static char * FtpMessageList[1000];

INLINE static char *___gets(char *s, int maxchars, FTP *ftp)
{
char *p=s;
int c;

while (1)
{
if ((c = FtpGetc(ftp,FTPCMD(ftp))) == EOF)
return NULL;

if ( c == '\n' && *(p-1) == '\r' )
{
p--;
*p='\0';
return s;
}

if ( (p-s) > maxchars ) return NULL;

*p++=(char)c;
}
}



int FtpGetMessage(FTP *con , char * Message )
{
int i=0,n;
char tmp[1024];

while(1)
{
if (___gets(tmp,sizeof tmp,con)==NULL)
return EXIT(con,QUIT);
if (isdigit(tmp[0]) &&
isdigit(tmp[1]) &&
isdigit(tmp[2]) &&
tmp[3]!='-') break;
if ( con -> debug != NULL )
(*con->debug)(con,0,tmp);
}

strcpy(Message,tmp);
FtpInitMessageList();
FtpMessageList[n=FtpNumber(Message)] =
( char * ) malloc ( strlen(Message) + 1);
strcpy(FtpMessageList[n] , Message );
if ( con -> debug != NULL )
(*con->debug)(con,n,Message);

return n;
}

STATUS FtpSendMessage(FTP *ftp,char * Message )
{
char *msg=Message;

while (*Message)
FtpAssert(ftp,FtpPutc(ftp,FTPCMD(ftp),*Message++));

FtpAssert(ftp,FtpPutc(ftp,FTPCMD(ftp),'\015'));
FtpAssert(ftp,FtpPutc(ftp,FTPCMD(ftp),'\012'));

if ( ftp -> debug != NULL )
(*ftp->debug)(ftp,0,msg);
return 1;
}

char *FtpMessage(int number)
{
extern int sys_nerr,errno;
extern char *sys_errlist[];

FtpInitMessageList();
if ( number == 0 )
return sys_errlist[errno];
return (FtpMessageList[abs(number)]==NULL)?
"":FtpMessageList[abs(number)];
}


STATUS FtpInitMessageList()
{
int i;
static u = 0;

if ( u )
return 1;

u = 1;

for (i=0;i<1000;i++)
FtpMessageList[i]=NULL;

return 1;
}

int FtpNumber(char *Message)
{
return (Message[0] - '0') * 100 +
(Message[1] - '0') * 10 +
(Message[2] - '0') ;
}

\End\Of\Shar\
else
echo "will not over write ./FtpMessage.c"
fi
if `test ! -s ./FtpMove.c`
then
echo "writing ./FtpMove.c"
cat > ./FtpMove.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpMove.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpMove.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 1.5 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpMove(FTP *con,char * oldname , char * newname )
{
STATUS i;

if ((i=FtpCommand(con,"RNFR %s",oldname,200,350,EOF)) > 1 )
return FtpCommand(con,"RNTO %s",newname,200,250,EOF);
else
return i;
}
\End\Of\Shar\
else
echo "will not over write ./FtpMove.c"
fi
if `test ! -s ./FtpOpenDir.c`
then
echo "writing ./FtpOpenDir.c"
cat > ./FtpOpenDir.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpOpenDir.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpOpenDir.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 1.5 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpOpenDir(FTP * con,char * file)
{
FtpString command;

if ( file == NULL || *file == '\0' )
strcpy(command,"NLST");
else
sprintf(command,"NLST %s",file);

return FtpCommand(con,command,"",120,150,200,EOF);
}
\End\Of\Shar\
else
echo "will not over write ./FtpOpenDir.c"
fi
if `test ! -s ./FtpPasv.c`
then
echo "writing ./FtpPasv.c"
cat > ./FtpPasv.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpPasv.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpPasv.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.1 1995/06/20 15:53:50 orel
* Porting to AIX
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.4 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/* Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the exist
ing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"


char * FtpPasv (FTP *ftp)
{
char *msg;
static FtpString PORT;
char *p=PORT;

if FtpError(FtpCommand(ftp,"PASV","",227,EOF))
return "";

msg = FtpMessage (227);

msg+=3;

while (!isdigit(*msg++));
msg--;

while (isdigit(*msg)||*msg==',') *p++=*msg++;
*p=0;

return PORT;
}


STATUS FtpLink(FTP *ftp1, FTP *ftp2)
{

FtpString PORT;

strcpy(PORT,FtpPasv(ftp1));

FtpCommand(ftp2,"PORT %s",PORT,200,EOF);
}

STATUS FtpPassiveTransfer(FTP *ftp1, FTP *ftp2, char *f1, char *f2)
{
FtpString tmp;
fd_set fds;

FtpAssert(ftp1,FtpLink(ftp1,ftp2));


if (!*f2) f2=f1;

FtpAssert(ftp2,FtpCommand(ftp2,"STOR %s",f2, 200, 120 , 150 , 125 , 250 , EOF ));
FtpAssert(ftp1,FtpCommand(ftp1,"RETR %s",f1, 200, 120 , 150 , 125 , 250 , EOF ));

FD_ZERO(&fds);

FD_SET(fileno(FTPCMD(ftp1)),&fds);
FD_SET(fileno(FTPCMD(ftp2)),&fds);

if (select(getdtablesize(),&fds,0,0,0)<0)
{
if (ftp1->error!=NULL)
return (*(ftp1->error))(ftp1,QUIT,sys_errlist[errno]);
if (ftp2->error!=NULL)
return (*(ftp2->error))(ftp1,QUIT,sys_errlist[errno]);
return QUIT;
}

if (FD_ISSET(fileno(FTPCMD(ftp1)),&fds))
{
FtpGetMessage(ftp1,tmp);
FtpLog(ftp1->title,tmp);
FtpGetMessage(ftp2,tmp);
FtpLog(ftp2->title,tmp);
}
else
{
FtpGetMessage(ftp2,tmp);
FtpLog(ftp2->title,tmp);
FtpGetMessage(ftp1,tmp);
FtpLog(ftp1->title,tmp);
}
}

\End\Of\Shar\
else
echo "will not over write ./FtpPasv.c"
fi
if `test ! -s ./FtpPort.c`
then
echo "writing ./FtpPort.c"
cat > ./FtpPort.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpPort.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpPort.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 1.5 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpPort(FTP *con,int a,int b,int c,int d,int e,int f)
{
FtpString cmd;
int i;

sprintf(cmd,"PORT %d,%d,%d,%d,%d,%d",a,b,c,d,e,f);
if ( FtpSendMessage(con,cmd) == QUIT)
return QUIT;
if ( (i=FtpGetMessage(con,cmd)) == QUIT)
return QUIT;

if ( ! FtpGood ( i , 200 , EOF ))
return EXIT(con,-i);

return EXIT(con,i);
}
\End\Of\Shar\
else
echo "will not over write ./FtpPort.c"
fi
if `test ! -s ./FtpPwd.c`
then
echo "writing ./FtpPwd.c"
cat > ./FtpPwd.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpPwd.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpPwd.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 1.5 1995/03/05 15:02:26 orel
* /
*
* Revision 1.5 1995/03/05 15:02:26 orel
* /
*
* Revision 1.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.3 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 1.2 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

char * FtpPwd(FTP * con)
{
FtpString tmp,tmp1;
int i;

if ( FtpSendMessage(con,"PWD") == QUIT )
return (char *) EXIT(con,QUIT);
if ( (i=FtpGetMessage(con,tmp)) == QUIT )
return (char *) EXIT(con,QUIT);

if ( i != 257 )
return (char *) EXIT(con,-i);

strcpy(tmp1,word(tmp,2));
if (*tmp1=='"')
{
strcpy(tmp,tmp1+1);
strncpy(tmp1,tmp,strlen(tmp)-1);
}
con -> errno = i;
return tmp1;
}
\End\Of\Shar\
else
echo "will not over write ./FtpPwd.c"
fi
if `test ! -s ./FtpRetr.c`
then
echo "writing ./FtpRetr.c"
cat > ./FtpRetr.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpRetr.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpRetr.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.4 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpRetr (FTP * con , char * command ,
char *in , char * out)
{
FILE *o;
int c;
struct stat st;
char buffer[FTPBUFSIZ],buffer2[FTPBUFSIZ];
register int size;

FtpFilenameChecker(&in,&out);

if ( FtpTestFlag(con,FTP_REST) && stat(out,&st)==0)
{
con -> seek = st.st_size;
if ((o=Ftpfopen(out,"a+"))==NULL)
return EXIT(con,LQUIT);
}
else
{
con -> seek = 0;
if ((o=Ftpfopen(out,"w+"))==NULL)
return EXIT(con,LQUIT);
}

if ( FtpError(FtpData(con,command,in,"r")))
{

if (con->seek==0) return EXIT(con,con->errno);

con -> seek = 0;
fclose(o);

if ( FtpError(FtpData(con,command,in,"r")) )
{
return EXIT(con,con->errno);
}

if ((o=Ftpfopen(out,"w+"))==NULL)
return EXIT(con,LQUIT);
}


fseek(o,con->seek,0);

while((size=FtpReadBlock(con,buffer,FTPBUFSIZ))>0)
{
if (write(fileno(o),buffer,size)!=size)
{
Ftpfclose(o);
return EXIT(con,LQUIT);
}
}

Ftpfclose(o);
return FtpClose(con);
}


\End\Of\Shar\
else
echo "will not over write ./FtpRetr.c"
fi
if `test ! -s ./FtpSize.c`
then
echo "writing ./FtpSize.c"
cat > ./FtpSize.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpSize.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpSize.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 2.4 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.2 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

int FtpSize(FTP * con, char *filename)
{
FtpString tmp;
int i,size;

strcpy(tmp,"SIZE ");
strcat(tmp,filename);

if ( FtpSendMessage(con,tmp) == QUIT )
return EXIT(con,QUIT);
if ( (i=FtpGetMessage(con,tmp)) == QUIT )
return EXIT(con,QUIT);

if ( i != 213 )
return con -> errno = (-i);

sscanf(tmp,"%*d %d",&size);
return size;
}
\End\Of\Shar\
else
echo "will not over write ./FtpSize.c"
fi
if `test ! -s ./FtpStat.c`
then
echo "writing ./FtpStat.c"
cat > ./FtpStat.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpStat.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpStat.c,v $
* Revision 5.0 1995/12/10 10:28:38 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/09/09 09:49:42 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.1 1995/06/20 15:53:50 orel
* Porting to AIX
*
* Revision 3.0 1995/03/20 05:26:07 orel


* *** empty log message ***
*

* Revision 1.5 1995/03/14 10:47:44 orel
* add UNKNOWN system type
*
* Revision 1.5 1995/03/14 10:47:44 orel
* add UNKNOWN system type
*
* Revision 1.4 1995/03/05 15:02:26 orel
* /
*
* Revision 1.3 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 1.2 1995/02/18 15:45:05 orel


* *** empty log message ***
*

* Revision 1.1 1995/02/18 15:42:53 orel
* Initial revision

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

static char * months[] = { "Jan", "Feb" , "Mar", "Apr", "May", "Jun", "Jul",
"Aug", "Sep", "Oct", "Nov", "Dec"};

#include "FtpLibrary.h"
#include <sys/stat.h>
#include <pwd.h>

static unix_parse(char *,FTP_STAT*);
static vms_parse(char *,FTP_STAT*, FILE*);
static vms_axp_parse(char *,FTP_STAT*);
static msdos_parse(char *,FTP_STAT*);

STATUS FtpStat(FTP *ftp, char *patern, FTP_STAT **first)
{
FtpString tmp,syst;
register FILE *in;
register FTP_STAT *stat=NULL, *prev=NULL;
register int status,sys_unix,sys_vms,sys_msdos;

*first = NULL;
strcpy(syst,FtpSyst(ftp));

sys_unix = !strcmp(syst,"UNIX") || !strcmp(syst,"UNKNOWN");
sys_vms = !strcmp(syst,"VMS");
sys_msdos = !strcmp(syst,"MSDOS");

sprintf(tmp,"/tmp/%s.XXXXXX",getpwuid(getuid())->pw_name);
mktemp(tmp);

if (*patern==0)
FtpRetr(ftp,"LIST","",tmp);
else
FtpRetr(ftp,sys_unix?"LIST -d %s":"LIST %s",patern,tmp);

if ( (in=fopen(tmp,"r")) == NULL)
return EXIT(ftp,LQUIT);


while(1)
{

if (fgets(tmp,sizeof tmp,in)==NULL)
break;

if ( stat == NULL )
{
*first = stat = (FTP_STAT *) malloc(sizeof(FTP_STAT));
bzero(stat,sizeof(FTP_STAT));
}

if ( ( sys_unix && unix_parse(tmp,stat))
||( sys_vms && (vms_parse(tmp,stat,in)||vms_axp_parse(tmp,stat)))
||( sys_msdos && msdos_parse(tmp,stat)))
{
stat -> next = (FTP_STAT *) malloc(sizeof(FTP_STAT));
prev = stat;
stat = stat -> next;
}
}

if (prev!=NULL)
free(prev->next),
prev->next=NULL;

fclose(in);

return 0;
}

static unix_parse(char *str, FTP_STAT *stat )
{
FtpString tmp;
register int column=1;
register int i;

if (*word(str,8)=='\0') return 0; /* Isn't file description */

strcpy(tmp,word(str,column++));

if (strlen(tmp)!=10) return 0;

stat->type = tmp[0];

stat->mode =
(( tmp[1] == 'r' ) ? S_IRUSR : 0) |
(( tmp[2] == 'w' ) ? S_IWUSR : 0) |
(( tmp[3] == 'x' ) ? S_IXUSR : 0) |
(( tmp[4] == 'r' ) ? S_IRGRP : 0) |
(( tmp[5] == 'w' ) ? S_IWGRP : 0) |
(( tmp[6] == 'x' ) ? S_IXGRP : 0) |
(( tmp[7] == 'r' ) ? S_IROTH : 0) |
(( tmp[8] == 'w' ) ? S_IWOTH : 0) |
(( tmp[9] == 'x' ) ? S_IXOTH : 0);


stat -> inodes = atoi ( word(str,column++));

strcpy ( stat -> user , word ( str, column ++ ));

if (*word(str,9)=='\0')
stat -> group[0] = 0;
else
strcpy ( stat -> group , word ( str, column ++ ));

stat -> size = atoi ( word(str,column++));


strcpy(tmp,word(str,column++));

stat->month = -1;
for (i=0;i<12;i++)
if (!strncasecmp(months[i],tmp,3))
{
stat->month=i;
break;
}


stat -> day = atoi ( word(str,column++));

strcpy(stat->time,word(str,column++));

strcpy(stat->name,word(str,column++));

if ( stat->type == 'l' && !strcmp(word(str,column++),"->") )
strcpy(stat->link,word(str,column++));

}

static vms_parse(char *str, FTP_STAT *stat, FILE *in)
{
FtpString tmp;
register char *p;
register int i;

strcpy(tmp,word(str,1));

if (*word(str,2)==0 && ((char*)strchr(tmp,'.')!=NULL &&
((char*)strchr(tmp,';'))!=NULL)
&& fgets(tmp,sizeof tmp,in)!=NULL)
*(char *)strchr(str,10)=0,
strcat(str,tmp);


if (*word(str,5) != '[' && *word(str,6)!='(' ) return 0;

strcpy(stat -> name , word(str,1));
stat -> size = atoi(word(str,2));

strcpy(tmp,word(str,5));


if (strchr(tmp+1,',')==NULL)
{
strcpy(stat->user,tmp+1);
*(char *)strchr(stat->user,']')='\0';
stat->group[0]=0;
}
else
{
strcpy(stat->group,tmp+1);
*(char *)strchr(stat->group,',')='\0';
strcpy(stat->user,(char *)strchr(tmp,',')+1);
*(char *)strchr(stat->user,']')='\0';
}

for (p=stat->name;*p;p++) *p=tolower(*p);

if ( (char*)strstr(stat->name,".dir;") != NULL)
{
*(char *)strchr(stat->name,'.')=0;
stat->type='d';
}
else
{
*(char *)strchr(stat->name,';')=0;
stat->type = '-';
}

stat -> day = atoi(word(str,3));

strcpy(tmp,(char *)strchr(word(str,3),'-')+1);
tmp[3]=0;

stat->month = -1;

for (i=0;i<12;i++)
if (!strncasecmp(months[i],tmp,3))
{
stat->month=i;
break;
}

strcpy(stat->time,word(str,4));

strcpy(tmp,word(str,6));


for(p=tmp;*p!=',';p++);
p++;

stat->mode=0;

if (*p=='R') { stat -> mode |= S_IRUSR; p++;}
if (*p=='W') { stat -> mode |= S_IWUSR; p++;}
if (*p=='E') { stat -> mode |= S_IXUSR; p++;}
if (*p=='D') { p++;}
p++;

if (*p=='R') { stat -> mode |= S_IRGRP; p++;}
if (*p=='W') { stat -> mode |= S_IWGRP; p++;}
if (*p=='E') { stat -> mode |= S_IXGRP; p++;}
if (*p=='D') { p++;}
p++;

if (*p=='R') { stat -> mode |= S_IROTH; p++;}
if (*p=='W') { stat -> mode |= S_IWOTH; p++;}
if (*p=='E') { stat -> mode |= S_IXOTH; p++;}
if (*p=='D') { p++;}

return 1;
}


static vms_axp_parse(char *str, FTP_STAT *stat)
{
FtpString tmp;
register char *p;
register int i;

if (*word(str,4) != '[' && *word(str,5)!='(' ) return 0;

strcpy(stat -> name , word(str,1));
stat -> size = atoi(word(str,2))*512;

strcpy(tmp,word(str,4));

strcpy(stat->group,tmp+1);
*(char *)strchr(stat->group,',')='\0';
strcpy(stat->user,(char *)strchr(tmp,',')+1);
*(char *)strchr(stat->user,']')='\0';

for (p=stat->name;*p;p++) *p=tolower(*p);

if ( (char*)strstr(stat->name,".dir;") != NULL)
{
*(char *)strchr(stat->name,'.')=0;
stat->type='d';
}
else
{
*(char *)strchr(stat->name,';')='.';
stat->type = '-';
}

stat -> day = atoi(word(str,3));

strcpy(tmp,(char *)strchr(word(str,3),'-')+1);
tmp[3]=0;

stat->month = -1;

for (i=0;i<12;i++)
if (!strncasecmp(months[i],tmp,3))
{
stat->month=i;
break;
}

strcpy(tmp,word(str,5));
for(p=tmp;*p!=',';p++);
p++;

stat->mode=0;

if (*p=='R') { stat -> mode |= S_IRUSR; p++;}
if (*p=='W') { stat -> mode |= S_IWUSR; p++;}
if (*p=='E') { stat -> mode |= S_IXUSR; p++;}
if (*p=='D') { p++;}
p++;

if (*p=='R') { stat -> mode |= S_IRGRP; p++;}
if (*p=='W') { stat -> mode |= S_IWGRP; p++;}
if (*p=='E') { stat -> mode |= S_IXGRP; p++;}
if (*p=='D') { p++;}
p++;

if (*p=='R') { stat -> mode |= S_IROTH; p++;}
if (*p=='W') { stat -> mode |= S_IWOTH; p++;}
if (*p=='E') { stat -> mode |= S_IXOTH; p++;}
if (*p=='D') { p++;}

return 1;
}

static msdos_parse(char *str, FTP_STAT *stat)
{
FtpString tmp;
register char *p;

if (*word(str,5) != 0) return 0;

strcpy(stat -> name , word(str,1));

for (p=stat->name;*p;*p++) *p=tolower(*p);

stat ->mode = 0644;

if (!strcmp(stat->name,".")||!strcmp(stat->name,"..")) return 0;

strcpy(tmp,word(str,2));

if (!strcasecmp(tmp,"<dir>"))
{
stat ->type = 'd';
stat ->mode |= S_IXUSR;
}
else
{
stat -> size = atoi(tmp);
stat -> type = '-';
}

strcpy(tmp,word(str,3));
stat -> month = atoi(tmp);
stat -> day = atoi((char*)strchr(tmp,'-')+1);

strcpy(stat->time,word(str,4));
return 1;
}




STATUS FtpStatFree(FTP_STAT *stat)
{
FTP_STAT *next;

while ( stat != NULL )
{
next = stat -> next;
free(stat);
stat = next;
}
}








\End\Of\Shar\
else
echo "will not over write ./FtpStat.c"
fi
echo "Finished archive 7 of 8"
exit


Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 69
Archive-Name: libftp-5.0/part08

#!/bin/sh
# to extract, remove the header and type "sh filename"

if `test ! -s ./FtpAbort.c`
then
echo "writing ./FtpAbort.c"
cat > ./FtpAbort.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpAbort.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpAbort.c,v $


* Revision 5.0 1995/12/10 10:28:38 orel
* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.2 1995/09/09 10:10:01 orel
* Clean problems with aborting already broken connection.
*
* Revision 4.2 1995/09/09 10:10:01 orel
* Clean problems with aborting already broken connection.

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"


FtpAbort(FTP *ftp)
{
fd_set fds;
char msgc=IAC;
FtpString msg;

if (FTPCMD(ftp)!=NULL) /* To avoid segmentation fault
for abort nonexisting connections */
{
FD_ZERO(&fds);
FD_SET(fileno(FTPCMD(ftp)),&fds);

FtpPutc(ftp, FTPCMD(ftp), IAC);
FtpPutc(ftp, FTPCMD(ftp), IP);

if ( send ( fileno(FTPCMD(ftp)), &msgc , 1 ,MSG_OOB) != 1 )
return EXIT(ftp,QUIT);

FtpPutc(ftp, FTPCMD(ftp), DM);

FtpSendMessage(ftp,"ABOR");

while (select ( getdtablesize(), &fds, 0,0, &(ftp->timeout) )>0)
{
register int i;

FtpGetMessage(ftp,msg);
if (FtpGood(FtpNumber(msg),225,226,EOF)) break;
}
}
}


\End\Of\Shar\
else
echo "will not over write ./FtpAbort.c"
fi
if `test ! -s ./FtpArchie.c`
then
echo "writing ./FtpArchie.c"
cat > ./FtpArchie.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpArchie.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpArchie.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

#define C2I(n) ((int)((n)-'0'))

int FtpArchie ( char *what, ARCHIE *result, int len)
{
FILE *archie;
FtpString cmd,tmp;
int i;

bzero(result,sizeof(result[0])*len);

sprintf(cmd,"archie -t -l -m %d %s",len,what);

if ((archie = popen(cmd,"r"))==NULL)
return 0;

for(i=0;i<len;i++)
{
char *p, *pp;

if (fgets(tmp,sizeof (tmp), archie)==NULL)
break;


result[i].createtime.tm_year = C2I (tmp[2 ])*10 - 70 + C2I(tmp[3]);
result[i].createtime.tm_mday = C2I (tmp[4 ])*10 + C2I(tmp[5]);
result[i].createtime.tm_hour = C2I (tmp[6 ])*10 + C2I(tmp[7]);
result[i].createtime.tm_min = C2I (tmp[8 ])*10 + C2I(tmp[9]);
result[i].createtime.tm_sec = C2I (tmp[10])*10 + C2I(tmp[11]);

for(p=tmp; *p!=' '; p++);
for(; *p==' '; p++);

result[i].size = atoi(p);

for(; *p!=' '; p++);
for(; *p==' '; p++);

for (pp=result[i].host;*p!=' ';p++,pp++) *pp=*p;
*pp=0;
for(; *p==' '; p++);
for (pp=result[i].file;*p!='\n';p++,pp++) *pp=*p;
*pp=0;

}

return i;
}
\End\Of\Shar\
else
echo "will not over write ./FtpArchie.c"
fi
if `test ! -s ./FtpBye.c`
then
echo "writing ./FtpBye.c"
cat > ./FtpBye.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpBye.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpBye.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"
#include <signal.h>

STATUS FtpBye(FTP *ftp)
{
FtpString S1;
int i;

FtpAssert(ftp,FtpCommand(ftp,"QUIT",221,EOF));

fclose(FTPCMD(ftp));
free(ftp);
return 0;
}

STATUS FtpQuickBye(FTP *ftp)
{


if (ftp == NULL) return;

if (FTPDATA(ftp)!=NULL)
{
shutdown(fileno(FTPDATA(ftp)),2);
fclose(FTPDATA(ftp));
}

if (FTPCMD(ftp)!=NULL)
{
shutdown(fileno(FTPCMD(ftp)),2);
fclose(FTPCMD(ftp));
}

free(ftp);
}

\End\Of\Shar\
else
echo "will not over write ./FtpBye.c"
fi
if `test ! -s ./FtpChmod.c`
then
echo "writing ./FtpChmod.c"
cat > ./FtpChmod.c << '\End\Of\Shar\'
static char rcsid[] = "$Id";

/*
$Log: FtpChmod.c,v $


* Revision 5.0 1995/12/10 10:28:38 orel
* LIBFTP Version 5.0 (Distributed revision)
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel
* *** empty log message ***
*
* Revision 3.0 1995/03/20 05:26:07 orel
* *** empty log message ***
*

* Revision 1.2 1995/03/05 15:02:26 orel
* /
*
* Revision 1.2 1995/03/05 15:02:26 orel
* /
*
* Revision 1.1 1995/02/19 15:47:05 orel
* Initial revision
*
* Revision 1.1 1995/02/19 15:47:05 orel
* Initial revision


*
*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpChmod(FTP *ftp,char *file,int mode)
{
FtpString msg;

sprintf(msg,"SITE CHMOD %03o %s",mode,file);
return FtpCommand(ftp,msg,"",200,EOF);

}
\End\Of\Shar\
else
echo "will not over write ./FtpChmod.c"
fi
if `test ! -s ./FtpClose.c`
then
echo "writing ./FtpClose.c"
cat > ./FtpClose.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpClose.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpClose.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/* Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.
*/

#include "FtpLibrary.h"

STATUS FtpClose(FTP *ftp)
{
int i;
FtpString S1;

fflush(FTPDATA(ftp));
shutdown(fileno(FTPDATA(ftp)),2);
fclose(FTPDATA(ftp));

FtpAssert(ftp,i=FtpGetMessage(ftp,S1));
if ( i != 226 )
return EXIT(ftp,-i);
return EXIT(ftp,i);
}
\End\Of\Shar\
else
echo "will not over write ./FtpClose.c"
fi
if `test ! -s ./FtpCommand.c`
then
echo "writing ./FtpCommand.c"
cat > ./FtpCommand.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpCommand.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpCommand.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpCommand(va_alist)
va_dcl
{
FTP *con;
char *command, *param;
int Answer[MAX_ANSWERS];
va_list args;
FtpString S1;
int i,counter=0;

va_start(args);

con = va_arg(args,FTP *);
command = va_arg(args,char *);
param = va_arg(args, char *);

while ( 1 )
{
if (counter == MAX_ANSWERS)
return EXIT(con,QUIT);
Answer[counter] = va_arg(args,int);
if (Answer[counter] == EOF ) break;
counter++;
}

va_end(args);


sprintf(S1,command,param);

if ( FtpSendMessage(con,S1) == QUIT )
return EXIT(con,QUIT);

if ( (i=FtpGetMessage(con,S1)) == QUIT )
return EXIT(con,QUIT);

if ( ! FtpGood1 ( i , Answer ))
return EXIT(con,-i);

return EXIT(con,i);
}



\End\Of\Shar\
else
echo "will not over write ./FtpCommand.c"
fi
if `test ! -s ./FtpConnect.c`
then
echo "writing ./FtpConnect.c"
cat > ./FtpConnect.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpConnect.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpConnect.c,v $


* Revision 5.0 1995/12/10 10:28:38 orel
* LIBFTP Version 5.0 (Distributed revision)
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.1 1995/06/20 15:53:50 orel

* *** empty log message ***
*
* Revision 3.0 1995/03/20 05:26:07 orel
* *** empty log message ***
*

* Revision 2.5 1995/03/05 15:02:26 orel
* /
*
* Revision 2.5 1995/03/05 15:02:26 orel
* /
*
* Revision 2.4 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.3 1995/02/18 15:42:53 orel


* modify for recurive mget
*

* Revision 2.3 1995/02/18 15:42:53 orel


* modify for recurive mget
*

* Revision 2.2 1995/02/04 10:00:21 orel


* *** empty log message ***
*

* Revision 2.2 1995/02/04 10:00:21 orel


* *** empty log message ***
*

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpConnect(FTP **con,char * hostname)
{
struct sockaddr_in unit;
register struct hostent *host;
register int new_socket;
FtpString S1;
STATUS x;

*con = FtpCreateObject();

if ((host=FtpGetHost(hostname))==NULL)
return EXIT((*con),QUIT);

strcpy((*con) -> title,host -> h_name); /* Default title for FtpLog */

unit.sin_family = host -> h_addrtype; /* AF_INET */

bcopy(host-> h_addr_list[0],(char *)&unit.sin_addr,host->h_length);
if ( ( new_socket = socket ( unit.sin_family , SOCK_STREAM , 0)) < 0)
return EXIT((*con),QUIT);

unit.sin_port = htons((*con)->port);

while ( connect ( new_socket , (struct sockaddr*) &unit , sizeof unit ) < 0 )
{
host -> h_addr_list ++;
if (host -> h_addr_list[0]==NULL) {
close(new_socket);
return EXIT((*con),QUIT);
}
bcopy(host -> h_addr_list[0],(char *)&unit,host->h_length);
close(new_socket);
if ( ( new_socket = socket ( unit.sin_family , SOCK_STREAM , 0)) < 0)
{
close(new_socket);
return EXIT((*con),QUIT);
}
}

FTPCMD(*con) = fdopen(new_socket,"r+");

if ( (x=FtpGetMessage(*con,S1)) == QUIT )
return EXIT((*con),QUIT);
if ( ! FtpGood(x,120,220,EOF))
{
close(new_socket);
return EXIT((*con),-x);
}

if ( (*con)->mode != 'A' )
{
FtpString x;

sprintf (x,"TYPE %c",(*con)->mode);
FtpSendMessage(*con,x);
FtpGetMessage(*con,x);
}

return EXIT((*con),x);
}

\End\Of\Shar\
else
echo "will not over write ./FtpConnect.c"
fi
if `test ! -s ./FtpCopy.c`
then
echo "writing ./FtpCopy.c"
cat > ./FtpCopy.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpCopy.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpCopy.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpCopy (FTP * ftp1 , FTP * ftp2 ,char *in , char * out)
{
int size;
char buffer[FTPBUFSIZ];

if (!*out) out=in;

if ( FtpTestFlag(ftp1,FTP_REST) && FtpTestFlag(ftp2,FTP_REST)
&& (size=FtpSize(ftp1,in))>0
&& FtpCommand(ftp1,"REST 0",0,0,EOF)==350 && FtpCommand(ftp2,"REST 0",0,0,EOF)==350 )
ftp1->seek=ftp2->seek=size;
else
ftp1->seek=ftp2->seek=0;

FtpAssert(ftp1,FtpData(ftp1,"RETR %s",in,"r"));
FtpAssert(ftp2,FtpData(ftp2,"STOR %s",out,"w"));

while ((size=FtpReadBlock(ftp1,buffer,FTPBUFSIZ))>0)
{
if (FtpWriteBlock(ftp2,buffer,size)!=size)
return EXIT(ftp2,QUIT);
}

FtpAssert(ftp1,FtpClose(ftp1));
FtpAssert(ftp2,FtpClose(ftp2));
return 0;
}

\End\Of\Shar\
else
echo "will not over write ./FtpCopy.c"
fi
if `test ! -s ./FtpData.c`
then
echo "writing ./FtpData.c"
cat > ./FtpData.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpData.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpData.c,v $


* Revision 5.0 1995/12/10 10:28:38 orel
* LIBFTP Version 5.0 (Distributed revision)
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.1 1995/06/20 15:53:50 orel
* Porting to AIX
*
* Revision 3.0 1995/03/20 05:26:07 orel
* *** empty log message ***
*

* Revision 2.7 1995/03/20 05:18:13 orel


* *** empty log message ***
*

* Revision 2.6 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.6 1995/02/26 16:46:50 orel


* *** empty log message ***
*

* Revision 2.5 1995/02/18 15:42:53 orel


* modify for recurive mget
*

* Revision 2.5 1995/02/18 15:42:53 orel


* modify for recurive mget
*

* Revision 2.4 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.4 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpData(FTP * con,char * command , char * file ,char * mode)
{
struct sockaddr_in data,from;
register struct hostent *host;
FtpString hostname,cmd;
int NewSocket,Accepted_Socket,len=sizeof(data),one=1,fromlen=sizeof(from),i;
char *a,*b;

FREE(data);
FREE(from);

if ( gethostname( hostname , sizeof hostname ) == -1 )
return EXIT(con,QUIT);

if ((host=(struct hostent *)gethostbyname(hostname))==0)
return EXIT(con,QUIT);

data.sin_family = host -> h_addrtype;

bcopy(host-> h_addr_list[0],(char *)&data.sin_addr,host->h_length);

if ((NewSocket = socket ( AF_INET , SOCK_STREAM , 0 ))<0)
return EXIT(con,QUIT);

if ( setsockopt ( NewSocket , SOL_SOCKET , SO_REUSEADDR ,
(char *)&one , sizeof(one) ) < 0 )
{
close(NewSocket);
return EXIT ( con,QUIT );
}

data.sin_port = 0 ;

if ( bind ( NewSocket , (struct sockaddr*) &data , sizeof data ) < 0 )
return EXIT(con,QUIT);

if ( getsockname ( NewSocket , (struct sockaddr*) &data , &len ) < 0 )
return EXIT(con,QUIT);

if ( listen ( NewSocket , 1 ) < 0 )
return EXIT(con,QUIT);

a = ( char * ) & data.sin_addr;
b = ( char * ) & data.sin_port;

FtpAssert(con,FtpPort(con,CUT(a[0]),CUT(a[1]),CUT(a[2]),
CUT(a[3]),CUT(b[0]),CUT(b[1])));

if ( con -> seek != 0)
{
if ((i = FtpCommand ( con, "REST %d" , con -> seek , 0, EOF)) != 350 )
return -i;
}

FtpAssert(con, i=FtpCommand ( con , command , file ,

200, 120 , 150 , 125 , 250 , EOF ));

if (( Accepted_Socket = accept (NewSocket , (struct sockaddr *)&from , &fromlen )) < 0)
{
close(NewSocket);
return EXIT(con,QUIT);
}

close(NewSocket);

FTPDATA(con) = fdopen(Accepted_Socket, "r+");

return i;
}

\End\Of\Shar\
else
echo "will not over write ./FtpData.c"
fi
if `test ! -s ./FtpDebug.c`
then
echo "writing ./FtpDebug.c"
cat > ./FtpDebug.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpDebug.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpDebug.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

void FtpDebug(FTP *ftp)
{
STATUS FtpDebugDebug(),
FtpDebugError(),
FtpDebugIO();

FtpSetDebugHandler(ftp,FtpDebugDebug);
FtpSetErrorHandler(ftp,FtpDebugError);
FtpSetIOHandler(ftp,FtpDebugIO);
}

STATUS FtpDebugDebug(FTP *ftp,int n, char * Message)
{
FtpString tmp;


strcpy(tmp,Message);

if (strncmp(tmp,"PASS ",5)==0)
{
char *p=tmp+5;
while ( *p != '\0') *p++='*';
};

FtpLog(ftp->title,tmp);
return 1;
}

STATUS FtpDebugError(FTP *ftp,int n, char * Message)
{

FtpLog("FtpDebugError","");
FtpLog(ftp->title,Message);
if ( ! FtpTestFlag(ftp,FTP_NOEXIT))
exit(1);
}

STATUS FtpDebugIO(FTP *ftp,int n, char * Message)
{
FtpLog("FtpDebugIO","");
FtpLog(ftp->title,Message);
if ( ! FtpTestFlag(ftp,FTP_NOEXIT))
exit(1);
}

STATUS FtpLog(char *name,char *str)
{
time_t t=time((time_t *)0);
struct tm *lt=localtime(&t);
fprintf(stderr,"%02d:%02d:%02d %s %s\n",lt->tm_hour,
lt->tm_min,lt->tm_sec,name,str);
fflush(stderr);
}

FtpHash(FTP *ftp, unsigned long chars)
{

if (chars==0) return ftp->counter=0;
ftp->counter+=chars;
fprintf(stderr,"%10u bytes transfered\r",ftp->counter);
fflush(stderr);
return ftp->counter;
}


STATUS FtpBadReply550(char *s)
{
if(
((char *)strstr(s,"unreachable")!=NULL) ||
((char *)strstr(s,"Broken pipe")!=NULL)
)
return 0;
return 1;
}

\End\Of\Shar\
else
echo "will not over write ./FtpDebug.c"
fi
if `test ! -s ./FtpFilenameChecker.c`
then
echo "writing ./FtpFilenameChecker.c"
cat > ./FtpFilenameChecker.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpFilenameChecker.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpFilenameChecker.c,v $

* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*
* Revision 2.1 1995/02/04 09:01:40 orel
* add rcsid
*

*/
/* Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.
*/

#include "FtpLibrary.h"

static char * simplename(char *s)
{
char *p;

if ( (p=(char *)strrchr(s,'/')) == NULL )
return s;
return p+1;
}

STATUS FtpFilenameChecker(char ** in, char ** out)
{
struct stat st;

if ( (stat(*out,&st) == 0) && S_ISDIR(st.st_mode))
{
char * sfn = simplename(*in);
char * new = (char *) malloc ( strlen(*out)+ strlen(sfn) + 2 );

strcpy(new,*out);
strcat(new,"/");
strcat(new,sfn);
*out=new;
return;
};

}


\End\Of\Shar\
else
echo "will not over write ./FtpFilenameChecker.c"
fi
if `test ! -s ./FtpFull.c`
then
echo "writing ./FtpFull.c"
cat > ./FtpFull.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpFull.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpFull.c,v $


* Revision 5.0 1995/12/10 10:28:38 orel
* LIBFTP Version 5.0 (Distributed revision)
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.1 1995/09/09 09:49:42 orel
* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*
* Revision 4.0 1995/07/11 07:00:26 orel
* Libftp Version 4.0
*
* Revision 3.0 1995/03/20 05:26:07 orel
* *** empty log message ***
*
* Revision 3.0 1995/03/20 05:26:07 orel
* *** empty log message ***
*

* Revision 2.6 1995/03/20 05:18:13 orel
* *** empty log message ***
*
* Revision 2.5 1995/02/26 16:46:50 orel
* *** empty log message ***
*
* Revision 2.5 1995/02/26 16:46:50 orel
* *** empty log message ***
*
* Revision 2.4 1995/02/18 15:42:53 orel
* modify for recurive mget
*
* Revision 2.4 1995/02/18 15:42:53 orel
* modify for recurive mget
*

* Revision 2.2 1995/02/04 09:02:53 orel
* add rcsid
*

*/
/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"
#include <pwd.h>

static FTP *ftp_table[256];
static STATUS syntax();

FILE * FtpFullOpen(char * file , char * mode )
{
FTP *ftp;
FILE *tmp;
FtpString Host,User,Passwd,RemoteFile;
STATUS i;

if ( ! FtpFullSyntax (file,Host,User,Passwd,RemoteFile))
{
tmp=fopen(file,mode);
if (tmp==NULL) return tmp;
ftp_table[(int)fileno(tmp)] = NULL;
return tmp;
}
if ( FtpLogin(&ftp,Host,User,Passwd,NULL) < 0 )
return NULL;

if (mode[1]=='b') FtpBinary(ftp);

switch(mode[0])
{
case 'r':
if (FtpError(FtpOpenRead(ftp,RemoteFile)))
return NULL;
ftp_table[fileno(FTPDATA(ftp))] = ftp;
return FTPDATA(ftp);
case 'w':
if (FtpError(FtpOpenWrite(ftp,RemoteFile)))
return NULL;
ftp_table[fileno(FTPDATA(ftp))] = ftp;
return FTPDATA(ftp);
case 'a':
if (FtpError(FtpOpenAppend(ftp,RemoteFile)))
return NULL;
ftp_table[fileno(FTPDATA(ftp))] = ftp;
return FTPDATA(ftp);
}
/* Error Mode */
return NULL;
}

STATUS FtpFullClose(FILE *f)
{
FTP *ftp=ftp_table[(int)fileno(f)];
if (ftp == NULL)
return fclose(f);
FtpClose(ftp);
return FtpQuickBye(ftp);
}


/* Format of ftp's file [user[/passord]@]hostname:filename_with_path */

STATUS FtpFullSyntax ( FtpString source ,
FtpString host ,
FtpString user ,
FtpString passwd ,
FtpString file)

{
char *in,*out;
FtpString tmp;

host[0] = user[0] = passwd[0] = file[0] = '\0';

for ( in=source, out = user;
*in !='\0' && *in != '/' && *in!='@' && *in!=':' ;
*out++ = *in++);
*out = '\0';

if ( *in == '\0' ) return 0;

if ( *in == ':' )
{
strcpy(host,user);
strcpy(user,"anonymous");
gethostname(tmp, sizeof tmp);
sprintf(passwd,"%s@%s",
getpwuid(getuid())->pw_name,gethostbyname(tmp)->h_name);
goto file;
}

if ( *in == '/' )
{
for ( in++, out = passwd;
*in !='\0' && *in!='@' ;
*out++ = *in++);
*out = '\0';
if ( *in == '\0' ) return 0;
}
else
{
gethostname(tmp, sizeof tmp);
sprintf(passwd,"%s@%s",
getpwuid(getuid())->pw_name,gethostbyname(tmp)->h_name);
}


for ( in++, out = host;
*in !='\0' && *in!=':' ;
*out++ = *in++);
*out = '\0';

if ( *in == '\0' ) return 0;

file:

for ( in++, out = file;
*in !='\0';
*out++ = *in++);
*out = '\0';

return 1;
}

\End\Of\Shar\
else
echo "will not over write ./FtpFull.c"
fi
if `test ! -s ./FtpGetHost.c`
then
echo "writing ./FtpGetHost.c"
cat > ./FtpGetHost.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpGetHost.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpGetHost.c,v $

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

struct hostent *FtpGetHost(char *host)
{

static struct in_addr addr;
static struct hostent _host;
static char *point[2];
static char *alias[1];

bzero(&_host,sizeof _host);
if ( (addr.s_addr=inet_addr(host)) != -1 )
{
_host.h_addr_list = point;
_host.h_addr_list[0] = (char *) &addr;
_host.h_addr_list[1] = (char *) 0;
alias[0]=NULL;
_host.h_aliases=alias;
_host.h_name=host;
_host.h_length=sizeof(unsigned long);
_host.h_addrtype=AF_INET;
return &_host;
}

return gethostbyname(host);
}


\End\Of\Shar\
else
echo "will not over write ./FtpGetHost.c"
fi
if `test ! -s ./FtpGood.c`
then
echo "writing ./FtpGood.c"
cat > ./FtpGood.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpGood.c,v 5.0 1995/12/10 10:28:38 orel Exp $";

/*
$Log: FtpGood.c,v $

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"

STATUS FtpGood(va_alist)
va_dcl
{
va_list args;
int Number;
int Answer[MAX_ANSWERS];
int counter=0;

va_start(args);

Number = va_arg(args,int);

while ( 1 )
{
if (counter == MAX_ANSWERS)
return 0;
Answer[counter] = va_arg(args,int);
if (Answer[counter] == EOF ) break;
counter++;
}

va_end(args);

return FtpGood1(Number,Answer);
}


STATUS FtpGood1(int Number , int *Answer)
{
while (1)
{
if ( *Answer == Number) return 1;
if ( *Answer == 0) return 1;
if ( *Answer == EOF ) return 0;
Answer++;
}
}

\End\Of\Shar\
else
echo "will not over write ./FtpGood.c"
fi
if `test ! -s ./FtpHTTP.c`
then
echo "writing ./FtpHTTP.c"
cat > ./FtpHTTP.c << '\End\Of\Shar\'
static char rcsid[] = "$Id:";

/*
$Log: FtpHTTP.c,v $


* Revision 5.0 1995/12/10 10:28:38 orel
* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 1.2 1995/12/02 11:23:07 orel


* *** empty log message ***
*

* Revision 1.1 1995/11/21 21:44:20 orel
* Initial revision
*
*/

/*
Library for ftpd clients.(libftp)
Copyright by Oleg Orel
All rights reserved.

This library is desined for free, non-commercial software creation.

It is changeable and can be improved. The author would greatly appreciate
any advises, new components and patches of the existing programs.

Commercial usage is also possible with participation of it's author.

*/

#include "FtpLibrary.h"
#include <sys/file.h>

static char ContextLenght[]="Content-Length: ";


STATUS FtpHttpGet(char* server,int port,char *spec, char *newfile)

{
struct sockaddr_in unit;
register struct hostent *host;
register int new_socket;
char buf[16*1024];
register int n;
FILE *fp, *sock;
register char *p;
register int counter;
int ContextLenghtLenght=strlen(ContextLenght);
int LenghtOfFile=-1;

if ((host=FtpGetHost(server))==NULL)
return QUIT;

unit.sin_family = host -> h_addrtype; /* AF_INET */

bcopy(host-> h_addr_list[0],(char *)&unit.sin_addr,host->h_length);
if ( ( new_socket = socket ( unit.sin_family , SOCK_STREAM , 0)) < 0)
return QUIT;

unit.sin_port = htons(port);

while ( connect ( new_socket , (struct sockaddr*) &unit , sizeof unit ) < 0 )
{
host -> h_addr_list ++;
if (host -> h_addr_list[0]==NULL) {
close(new_socket);
return QUIT;
}
bcopy(host -> h_addr_list[0],(char *)&unit,host->h_length);
close(new_socket);
if ( ( new_socket = socket ( unit.sin_family , SOCK_STREAM , 0)) < 0)
{
close(new_socket);
return QUIT;
}
}

sock=fdopen(new_socket,"r+");

if (fprintf(sock,
"GET %s HTTP/1.0\r\nAccept: */*\r\nUserAgent: LIBFTP\r\n\r\n",
spec)!=0)
{

shutdown(new_socket,2);
fclose(sock);
return QUIT;
}

fflush(sock);

p=strrchr(spec,'/');
if ( ((newfile==NULL) || !*newfile) && p!=NULL)
strcpy(newfile,++p);

if ((fp=fopen(newfile,"w+"))==NULL)
{
shutdown(new_socket,2);
close(new_socket);
return LQUIT;
}

while ( (fgets(buf,sizeof buf,sock))!=NULL )
{
if (FtpInit.debug!=NULL)
printf("%s",buf);

if (strstr(buf,"Internal error")!=NULL)
return ENOENT;

if (!strncmp(ContextLenght,buf,ContextLenghtLenght))
{
sscanf (buf,"Context-Lenght: %d",&LenghtOfFile);
}

if (buf[0]==Ctrl('M') && buf[1]=='\n' && buf[2]==0)
break;
}


for (counter=0; (n=getc(sock))!=EOF ; counter++)
if (putc(n,fp)==EOF)
{
fclose(fp);
shutdown(new_socket,2);
fclose(sock);
return LQUIT;
}
fclose(fp);
shutdown(new_socket,2);
fclose(sock);

if (counter==LenghtOfFile || LenghtOfFile == -1 )
return OK;

return QUIT;

}

\End\Of\Shar\
else
echo "will not over write ./FtpHTTP.c"
fi
echo "Finished archive 8 of 8"
exit


Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 63
Archive-Name: libftp-5.0/part02

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./doc`
then
mkdir ./doc
echo "mkdir ./doc"
fi

if `test ! -s ./doc/libftp.ps`
then
echo "writing ./doc/libftp.ps"
cat > ./doc/libftp.ps << '\End\Of\Shar\'
%!PS-Adobe-2.0
%%Creator: dvips 5.47 Copyright 1986-91 Radical Eye Software
%%Title: libftp.dvi
%%Pages: 18 1
%%BoundingBox: 0 0 612 792
%%EndComments
%%BeginProcSet: tex.pro

/TeXDict 200 dict def % define a working dictionary
TeXDict begin % start using it.
/N /def load def
/B { bind def } N
/S /exch load def
/X { S N } B
/TR /translate load N

/isls false N
/vsize 10 N

/@rigin % -xps -yps @rigin - establishes dvips conventions
{ isls { [ 0 1 -1 0 0 0 ] concat } if
72 Resolution div 72 VResolution div neg scale
Resolution VResolution vsize neg mul TR
matrix currentmatrix
dup dup 4 get round 4 exch put
dup dup 5 get round 5 exch put
setmatrix } N


/@letter { /vsize 10 N } B

/@landscape { /isls true N /vsize -1 N } B

/@a4 { /vsize 10.6929133858 N } B

/@a3 { /vsize 15.5531 N } B

/@ledger { /vsize 16 N } B

/@legal { /vsize 13 N } B

/@manualfeed
{ statusdict /manualfeed true put
} B

% n @copies - set number of copies
/@copies
{ /#copies X
} B


/FMat [1 0 0 -1 0 0] N
/FBB [0 0 0 0] N

/nn 0 N /IE 0 N /ctr 0 N
/df-tail % id numcc maxcc df-tail -- initialize a new font dictionary
{
/nn 8 dict N % allocate new font dictionary
nn begin
/FontType 3 N
/FontMatrix fntrx N
/FontBBox FBB N
string /base X
array /BitMaps X
/BuildChar {CharBuilder} N
/Encoding IE N
end
dup { /foo setfont } % dummy macro to be filled in
2 array copy cvx N % have to allocate a new one
load % now we change it
0 nn put
/ctr 0 N % go, count, and etc.
[ % start next char definition
} B
/df {
/sf 1 N
/fntrx FMat N
df-tail
} B
/dfs { div /sf X
/fntrx [ sf 0 0 sf neg 0 0 ] N
df-tail
} B

/E { pop nn dup definefont setfont } B


/ch-width {ch-data dup length 5 sub get} B % the number of pixels across
/ch-height {ch-data dup length 4 sub get} B % the number of pixels tall
/ch-xoff {128 ch-data dup length 3 sub get sub} B % num pixels right of origin
/ch-yoff {ch-data dup length 2 sub get 127 sub} B % number of pixels below origin
/ch-dx {ch-data dup length 1 sub get} B % number of pixels to next character
/ch-image {ch-data dup type /stringtype ne
{ ctr get /ctr ctr 1 add N } if
} B % the hex string image, or array of same
/id 0 N /rw 0 N /rc 0 N /gp 0 N /cp 0 N /G 0 N /sf 0 N

/CharBuilder % fontdict ch Charbuilder - -- image one character
{save 3 1 roll S dup /base get 2 index get S /BitMaps get S get
/ch-data X pop
/ctr 0 N
ch-dx 0 ch-xoff ch-yoff ch-height sub
ch-xoff ch-width add ch-yoff
setcachedevice
ch-width ch-height true
[1 0 0 -1 -.1 ch-xoff sub ch-yoff .1 add]
{ch-image} imagemask
restore
} B

% in the following, the font-cacheing mechanism requires that
% a name unique in the particular font be generated

/D % char-data ch D - -- define character bitmap in current font
{ /cc X
dup type /stringtype ne {]} if
nn /base get cc ctr put
nn /BitMaps get S ctr S
sf 1 ne {
dup dup length 1 sub dup 2 index S get sf div put
} if
put
/ctr ctr 1 add N
} B

/I % a faster D for when the next char follows immediately
{ cc 1 add D } B

/bop % bop - -- begin a brand new page
{
userdict /bop-hook known { bop-hook } if
/SI save N
@rigin
0 0 moveto
} N

/eop % - eop - -- end a page
{ % eop-aux % -- to observe VM usage
clear SI restore
showpage
userdict /eop-hook known { eop-hook } if
} N

/@start % - @start - -- start everything
{
userdict /start-hook known { start-hook } if
/VResolution X
/Resolution X
1000 div /DVImag X
/IE 256 array N
0 1 255 {IE S 1 string dup 0 3 index put cvn put} for
} N

/p /show load N % the main character setting routine

/RMat [ 1 0 0 -1 0 0 ] N % things we need for rules
/BDot 260 string N
/rulex 0 N /ruley 0 N
/v { % can't use ...fill; it makes rules too big
/ruley X /rulex X
V
} B
/V
statusdict begin /product where
{ pop product dup length 7 ge
{ 0 7 getinterval (Display) eq } { pop false } ifelse }
{ false } ifelse end
{ {
gsave
TR -.1 -.1 TR 1 1 scale rulex ruley
false RMat { BDot } imagemask
grestore
} }
{ {
gsave
TR -.1 -.1 TR rulex ruley scale 1 1
false RMat { BDot } imagemask
grestore
} } ifelse B
/a { moveto } B % absolute positioning
/delta 0 N % we need a variable to hold space moves
/tail { dup /delta X 0 rmoveto } B
/M { S p delta add tail } B
/b { S p tail } B % show and tail!
/c { -4 M } B
/d { -3 M } B
/e { -2 M } B
/f { -1 M } B
/g { 0 M } B
/h { 1 M } B
/i { 2 M } B
/j { 3 M } B
/k { 4 M } B
/w { 0 rmoveto } B
/l { p -4 w } B
/m { p -3 w } B
/n { p -2 w } B
/o { p -1 w } B
/q { p 1 w } B
/r { p 2 w } B
/s { p 3 w } B
/t { p 4 w } B
/x { 0 S rmoveto } B
/y { 3 2 roll p a } B
/bos { /SS save N } B
/eos { clear SS restore } B

end % revert to previous dictionary
%%EndProcSet
TeXDict begin 1000 300 300 @start /Fa 3 63 df<60F0F06004047C830C>58
D<0000038000000F0000003C000000F0000003C000000F0000003C000000F0000003C000000F00
00003C000000F0000000F00000003C0000000F00000003C0000000F00000003C0000000F000000
03C0000000F00000003C0000000F000000038019187D9520>60 D<E0000000780000001E000000
0780000001E0000000780000001E0000000780000001E0000000780000001E0000000780000007
8000001E00000078000001E00000078000001E00000078000001E00000078000001E0000007800
0000E000000019187D9520>62 D E /Fb 28 122 df<E038F078F078F078F078F078F078F078E0
38E03860300D0B7C9816>34 D<0387000387000387000387000387000387007FFFC0FFFFE0FFFF
E0070E00070E00070E000E1C000E1C000E1C000E1C00FFFFE0FFFFE07FFFC01C38001C38001C38
001C38001C38001C380013197F9816>I<3801807C0380FE0380FE0700EE0700EE0E00EE0E00EE
0E00FE1C00FE1C007C380038380000700000700000700000E00000E00001C00001C00001C00003
80000383800707C0070FE00E0EE00E0EE00E0EE01C0EE01C0EE0380FE03807C018038013207F9C
16>37 D<FFFF80FFFF80FFFF8011037E8D16>45 D<70F8F8F8700505788416>I<70F8F8F87000
0000000000000070F8F8F8700512789116>58 D<FFFFE0FFFFE0FFFFE01C00E01C00E01C00E01C
00E01C00001C00001C1C001C1C001FFC001FFC001FFC001C1C001C1C001C00001C00001C00001C
00001C00001C0000FF8000FFC000FF800013197F9816>70 D<FFC000FFC000FFC0001C00001C00
001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00
401C00E01C00E01C00E01C00E0FFFFE0FFFFE0FFFFE013197F9816>76 D<7F07F0FF8FF87F07F0
1C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C01C0
1C01C01C01C01C01C00E03800E038007070007FF0003FE0000F8001519809816>85
D<1FE0007FF8007FFC00783C00301E00000E00000E0003FE001FFE007E0E00F00E00E00E00E00E
00F01E00F83E007FFFE03FE7E00F83E013127E9116>97 D<7E0000FE00007E00000E00000E0000
0E00000E00000E3E000EFF800FFFC00F83E00F01E00E00F00E00F00E00700E00700E00700E0070
0E00F00F00E00F01E00F83C00FFFC00EFF00063C001419809816>I<03F80FFE1FFE3C1E780C70
00F000E000E000E000E000F000700778073E0F1FFE0FFC03F010127D9116>I<003F00007F0000
3F0000070000070000070000070003C7000FF7003FFF003C1F00780F00F00700F00700E00700E0
0700E00700E00700F00700F00F00781F007C3F003FFFE01FF7F007C7E014197F9816>I<03E00F
F81FFC3C1E780E7007E007FFFFFFFFFFFFE000E000700778073C0F1FFE0FFC03F010127D9116>
I<001F00007F8000FF8001E78001C30001C00001C0007FFF00FFFF00FFFF0001C00001C00001C0
0001C00001C00001C00001C00001C00001C00001C00001C00001C0003FFE007FFF003FFE001119
7F9816>I<03E3C00FFFE01FFFE01E3CC03C1E00380E00380E00380E003C1E001E3C001FFC001F
F8003BE0003800003800001FFC001FFF003FFFC07803C0F001E0E000E0E000E0E000E0F001E07C
07C03FFF800FFE0003F800131C7F9116>I<7E0000FE00007E00000E00000E00000E00000E0000
0E3C000EFF000FFF800F87800F03800F03800E03800E03800E03800E03800E03800E03800E0380
0E03800E03807FC7F0FFE7F87FC7F01519809816>I<018003C003C0018000000000000000007F
C07FC07FC001C001C001C001C001C001C001C001C001C001C001C001C07FFFFFFF7FFF101A7D99
16>I<FFC000FFC000FFC00001C00001C00001C00001C00001C00001C00001C00001C00001C000
01C00001C00001C00001C00001C00001C00001C00001C00001C00001C000FFFF80FFFF80FFFF80
11197E9816>108 D<7E3C00FEFF007FFF800F87800F03800F03800E03800E03800E03800E0380
0E03800E03800E03800E03800E03807FC7F0FFE7F87FC7F01512809116>110
D<03E0000FF8001FFC003C1E00780F00700700E00380E00380E00380E00380E00380F007807007
00780F003C1E001FFC000FF80003E00011127E9116>I<7E3E00FEFF807FFFC00F83E00F01E00E
00F00E00F00E00700E00700E00700E00700E00F00F00E00F01E00F83C00FFFC00EFF000E3C000E
00000E00000E00000E00000E00000E00007FC000FFE0007FC000141B809116>I<FF0FC0FF3FE0
FF7FE007F04007E00007C000078000078000070000070000070000070000070000070000070000
FFFC00FFFC00FFFC0013127F9116>114 D<0FEC3FFC7FFCF03CE01CE01CF0007F801FF007FC00
3EE00EE00EF00EF81EFFFCFFF8C7E00F127D9116>I<0300000700000700000700000700007FFF
00FFFF00FFFF000700000700000700000700000700000700000700000701000703800703800707
8007878003FF0003FE0000F80011177F9616>I<7E1F80FE3F807E1F800E03800E03800E03800E
03800E03800E03800E03800E03800E03800E03800E07800F0F800FFFF007FFF803E3F015128091
16>I<FF1FE0FFBFE0FF1FE038038038038038038038038038E38019F30019F30019B3001DB700
1DB7001DB7001DB7000F1E000F1E000F1E0013127F9116>119 D<7F1FC0FF9FE07F1FC01C0700
0E07000E0E000E0E00070E00071C00071C00039C00039C0003980001B80001B80000F00000F000
00F00000E00000E00000E00001C00079C0007BC0007F80003F00003C0000131B7F9116>121
D E /Fc 18 118 df<183C3C3C0404080810204080060C779C0D>39 D<00000300000700000E00
000C00001C0000180000380000300000700000E00000C00001C000018000038000030000070000
0600000E00001C0000180000380000300000700000600000E00000C00001C00003800003000007
00000600000E00000C00001C0000180000380000700000600000E00000C00000C0000018297F9E
15>47 D<01FFC0003C0000380000380000380000380000700000700000700000700000E00000E0
0000E00000E00001C00001C00001C00001C0000380000380000380000380000700000700000700
000700000F0000FFE000121C7E9B10>73 D<03CC063C0C3C181C3838303870387038E070E070E0
70E070E0E2C0E2C0E261E462643C380F127B9115>97 D<3F00070007000E000E000E000E001C00
1C001C001C0039C03E60383038307038703870387038E070E070E070E060E0E0C0C0C1C0618063
003C000D1D7B9C13>I<01F007080C08181C3838300070007000E000E000E000E000E000E008E0
10602030C01F000E127B9113>I<001F80000380000380000700000700000700000700000E0000
0E00000E00000E0003DC00063C000C3C00181C00383800303800703800703800E07000E07000E0
7000E07000E0E200C0E200C0E20061E4006264003C3800111D7B9C15>I<01E007100C10180838
10701070607F80E000E000E000E000E000E0086010602030C01F000D127B9113>I<0003C00006
70000C70001C60001C00001C0000380000380000380000380000380003FF800070000070000070
0000700000700000E00000E00000E00000E00000E00001C00001C00001C00001C00001C0000380
00038000038000030000030000070000C60000E60000CC00007800001425819C0D>I<0FC00001
C00001C0000380000380000380000380000700000700000700000700000E78000E8C000F0E000E
0E001C0E001C0E001C0E001C0E00381C00381C00381C00383800703880703880707080707100E0
3200601C00111D7D9C15>104 D<01800380010000000000000000000000000000001C00260047
0047008E008E000E001C001C001C0038003800710071007100720072003C00091C7C9B0D>I<1F
800380038007000700070007000E000E000E000E001C001C001C001C0038003800380038007000
700070007000E400E400E400E40068003800091D7C9C0B>108 D<3C3C00264600468700470700
8E07008E07000E07000E07001C0E001C0E001C0E001C1C00381C40381C40383840383880701900
300E0012127C9117>110 D<07870004D98008E0C008E0C011C0E011C0E001C0E001C0E00381C0
0381C00381C00381800703800703000707000706000E8C000E70000E00000E00001C00001C0000
1C00001C00003C0000FF8000131A7F9115>112 D<3C3C26C2468747078E068E000E000E001C00
1C001C001C0038003800380038007000300010127C9112>114 D<01F006080C080C1C18181C00
1F001FC00FF007F0007800386030E030C030806060C01F000E127D9111>I<00C001C001C001C0
0380038003800380FFE00700070007000E000E000E000E001C001C001C001C0038403840384038
8019000E000B1A7D990E>I<1E0300270700470700470700870E00870E000E0E000E0E001C1C00
1C1C001C1C001C1C003838803838801838801839001C5900078E0011127C9116>I
E /Fd 28 121 df<7070F8F8FCFCFCFC74740404040408081010202040400E0B7F9615>34
D<70F8F8F87005057D840B>46 D<07C01C703838701C701CF01EF01EF01EF01EF01EF01EF01EF0
1EF01EF01EF01E701C701C38381C7007C00F157E9414>48 D<01800780FF80FF80078007800780
078007800780078007800780078007800780078007800780FFF8FFF80D157D9414>I<0FC03FF8
70FCF83CF83EF81E701E003E003C0038007000E001C0038006060C06180E3FFC7FFCFFFCFFFC0F
157E9414>I<00180000380000780000F80001F8000378000278000678000C7800187800307800
607800C07800FFFF80FFFF8000780000780000780000780007FF8007FF8011157F9414>52
D<01F00FF81E1C3C3C383C70187000F000F3E0F438F81CF01CF01EF01EF01E701E701E781C3C38
1FF007E00F157E9414>54 D<07E01FF03838701C701C781C7E1C7FB83FF01FF00FF83BFC70FEE0
3EE01EE00EE00EF00C78183FF00FE00F157E9414>56 D<0FC01FF03838703CF01CF01CF01EF01E
F01E701E703E385E0F9E001E001C301C783C783870F03FE01F800F157E9414>I<FFF800FFF800
0F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F8060
0F80600F80600F80E00F80C00F81C00F83C0FFFFC0FFFFC013177E9618>76
D<FF807FE0FFC07FE00FE006000FF006000DF006000CF806000C7C06000C7E06000C3E06000C1F
06000C0F86000C0FC6000C07E6000C03E6000C01F6000C00FE000C00FE000C007E000C003E000C
001E000C001E00FFC00E00FFC006001B177E9620>78 D<FFF8FFC0FFF8FFC00F800C000F800C00
0F800C000F800C000F800C000F800C000F800C000F800C000F800C000F800C000F800C000F800C
000F800C000F800C000F800C000F800C000780180007C0180003E0700000FFE000003F80001A17
7E961F>85 D<080810102020404080808080B8B8FCFCFCFC7C7C38380E0B7B9615>92
D<07F01C1C383C783C7018F000F000F000F000F0007000780038061C0C07F80F0F7F8E12>99
D<001F80001F8000078000078000078000078000078000078003F7801E1F803807807807807007
80F00780F00780F00780F00780F00780700780780780380F801C1FE007E7E013177F9617>I<07
F01C18380C78067007F007F007FFFFF000F0007000780038031E0603FC100F7F8E13>I<01F003
9C073C0F3C0F180F000F000F00FFC0FFC00F000F000F000F000F000F000F000F000F000F000F00
3FE03FE00E1780960C>I<FC0000FC00003C00003C00003C00003C00003C00003C00003C7C003D
8E003E0F003E0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F00FF3FC0FF
3FC012177E9617>104 D<387C7C7C3800000000FCFC3C3C3C3C3C3C3C3C3C3C3CFFFF08187F97
0B>I<FC0000FC00003C00003C00003C00003C00003C00003C00003C7F003C7F003C38003C7000
3CE0003DC0003FC0003FE0003CF0003C70003C38003C3C003C1E00FF3F80FF3F8011177E9615>
107 D<FCFC3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3C3CFFFF08177F960B>I<FC7C00FD8E00
3E0F003E0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F00FF3FC0FF3FC0
120F7E8E17>110 D<07F0001C1C00380E00700700700700F00780F00780F00780F00780F00780
700700700700380E001C1C0007F000110F7F8E14>I<F8E0F9383A783A783C303C003C003C003C
003C003C003C003C00FF80FF800D0F7E8E11>114 D<1FF060704030C030E000FF007FE03FF00F
F80078C018C018E010F020CFC00D0F7F8E10>I<0600060006000E000E001E003FE0FFE01E001E
001E001E001E001E001E001E301E301E301E300E2007C00C157F9410>I<FC3F00FC3F003C0F00
3C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C0F003C1F001C2FC00FCFC0120F7E
8E17>I<FE1FC0FE1FC01E0C000F180007B80007F00003E00001E00003F000037800063C000E3C
001C1E00FC1FC0FC1FC0120F7F8E15>120 D E /Fe 6 111 df<01800180018001804182F18F39
9C0FF003C003C00FF0399CF18F4182018001800180018010127E9215>3
D<0000600000600000E00000C00001C0000180000380000300000700000600000600000E00000C
00001C0000180000380000300000700000600000E00000C00000C00001C0000180000380000300
000700000600000E00000C00000C00001C0000180000380000300000700000600000E00000C000
00C0000013287A9D00>54 D<003C00E001C0018003800380038003800380038003800380038003
80038003800380030007001C00F0001C0007000300038003800380038003800380038003800380
0380038003800380018001C000E0003C0E297D9E15>102 D<F0001C0007000300038003800380
0380038003800380038003800380038003800380018001C000E0003C00E001C001800380038003
800380038003800380038003800380038003800380030007001C00F0000E297D9E15>I<C0C0C0
C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C002
297B9E0C>106 D<C000C000E00060006000700030003800180018001C000C000C000E00060006
000700030003000380018001C000C000C000E000600060007000300030003800180018001C000C
000E0006000600070003000310297E9E15>110 D E /Ff 48 122 df<000FF000007FFC0001F8
0E0003E01F0007C03F000F803F000F803F000F801E000F800C000F8000000F8000000F8000000F
800000FFFFFF00FFFFFF000F801F000F801F000F801F000F801F000F801F000F801F000F801F00
0F801F000F801F000F801F000F801F000F801F000F801F000F801F000F801F000F801F000F801F
000F801F007FF0FFE07FF0FFE01B237FA21F>12 D<387CFEFFFF7F3B03030706060C1C18702008
117CA210>39 D<00180030006000C001C00380070007000E001E001C003C003C003C0078007800
78007800F800F000F000F000F000F000F000F000F000F000F000F000F80078007800780078003C
003C003C001C001E000E0007000700038001C000C00060003000180D317BA416>I<C000600030
0018001C000E0007000700038003C001C001E001E001E000F000F000F000F000F8007800780078
0078007800780078007800780078007800F800F000F000F000F001E001E001E001C003C0038007
0007000E001C00180030006000C0000D317DA416>I<FFFCFFFCFFFCFFFC0E047F8C13>45
D<387CFEFEFE7C3807077C8610>I<0000180000380000380000700000700000E00000E00000E0
0001C00001C0000380000380000380000700000700000700000E00000E00001C00001C00001C00
00380000380000700000700000700000E00000E00001C00001C00001C000038000038000070000
0700000700000E00000E00000E00001C00001C0000380000380000380000700000700000E00000
E00000C0000015317DA41C>I<00180000780001F800FFF800FFF80001F80001F80001F80001F8
0001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F80001F8
0001F80001F80001F80001F80001F80001F80001F80001F8007FFFE07FFFE013207C9F1C>49
D<03FC000FFF003C1FC07007E07C07F0FE03F0FE03F8FE03F8FE01F87C01F83803F80003F80003
F00003F00007E00007C0000F80001F00003E0000380000700000E01801C0180380180700180E00
380FFFF01FFFF03FFFF07FFFF0FFFFF0FFFFF015207D9F1C>I<00FE0007FFC00F07E01E03F03F
03F03F81F83F81F83F81F81F03F81F03F00003F00003E00007C0001F8001FE0001FF000007C000
01F00001F80000FC0000FC3C00FE7E00FEFF00FEFF00FEFF00FEFF00FC7E01FC7801F81E07F00F
FFC001FE0017207E9F1C>I<0000E00001E00003E00003E00007E0000FE0001FE0001FE00037E0
0077E000E7E001C7E00187E00307E00707E00E07E00C07E01807E03807E07007E0E007E0FFFFFE
FFFFFE0007E00007E00007E00007E00007E00007E00007E000FFFE00FFFE17207E9F1C>I<1000
201E01E01FFFC01FFF801FFF001FFE001FF8001BC00018000018000018000018000019FC001FFF
001E0FC01807E01803E00003F00003F00003F80003F83803F87C03F8FE03F8FE03F8FC03F0FC03
F07007E03007C01C1F800FFF0003F80015207D9F1C>I<001F8000FFE003F07007C0F00F01F81F
01F83E01F83E01F87E00F07C00007C0000FC0800FC7FC0FCFFE0FD80F0FF00F8FE007CFE007CFC
007EFC007EFC007EFC007E7C007E7C007E7C007E3C007C3E007C1E00F80F00F00783E003FFC000
FF0017207E9F1C>I<6000007800007FFFFE7FFFFE7FFFFC7FFFF87FFFF87FFFF0E00060E000C0
C00180C00300C00300000600000C00001C0000180000380000780000780000F00000F00000F000
01F00001F00001F00003F00003F00003F00003F00003F00003F00003F00001E00017227DA11C>
I<000070000000007000000000F800000000F800000000F800000001FC00000001FC00000003FE
00000003FE00000003FE00000006FF000000067F0000000E7F8000000C3F8000000C3F80000018
3FC00000181FC00000381FE00000300FE00000300FE00000600FF000006007F00000E007F80000
FFFFF80000FFFFF800018001FC00018001FC00038001FE00030000FE00030000FE000600007F00
0600007F00FFE00FFFF8FFE00FFFF825227EA12A>65 D<0003FE0080001FFF818000FF01E38001
F8003F8003E0001F8007C0000F800F800007801F800007803F000003803F000003807F00000180
7E000001807E00000180FE00000000FE00000000FE00000000FE00000000FE00000000FE000000
00FE00000000FE000000007E000000007E000001807F000001803F000001803F000003801F8000
03000F8000030007C000060003F0000C0001F800380000FF00F000001FFFC0000003FE00002122
7DA128>67 D<FFFFFF8000FFFFFFF00007F003FC0007F0007E0007F0003F0007F0001F8007F000
0FC007F00007E007F00007E007F00007F007F00003F007F00003F007F00003F007F00003F807F0
0003F807F00003F807F00003F807F00003F807F00003F807F00003F807F00003F807F00003F807
F00003F007F00003F007F00003F007F00007E007F00007E007F0000FC007F0001F8007F0003F00
07F0007E0007F003FC00FFFFFFF000FFFFFF800025227EA12B>I<FFFFFFFCFFFFFFFC07F000FC
07F0003C07F0001C07F0000C07F0000E07F0000E07F0000607F0180607F0180607F0180607F018
0007F0380007F0780007FFF80007FFF80007F0780007F0380007F0180007F0180007F0180307F0
180307F0000307F0000607F0000607F0000607F0000E07F0000E07F0001E07F0003E07F001FCFF
FFFFFCFFFFFFFC20227EA125>I<FFFFFFF8FFFFFFF807F001F807F0007807F0003807F0001807
F0001C07F0001C07F0000C07F0000C07F0180C07F0180C07F0180007F0180007F0380007F07800
07FFF80007FFF80007F0780007F0380007F0180007F0180007F0180007F0180007F0000007F000
0007F0000007F0000007F0000007F0000007F0000007F00000FFFFE000FFFFE0001E227EA123>
I<FFFF83FFFEFFFF83FFFE07F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F000
1FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007FF
FFFFC007FFFFFFC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007
F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC007F0001FC0
07F0001FC0FFFF83FFFEFFFF83FFFE27227EA12C>72 D<FFFFE0FFFFE003F80003F80003F80003
F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003
F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003F80003
F800FFFFE0FFFFE013227FA115>I<FFFFE000FFFFE00007F0000007F0000007F0000007F00000
07F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F000
0007F0000007F0000007F0000007F0000007F0000007F0001807F0001807F0001807F0001807F0
003807F0003807F0007007F0007007F000F007F001F007F007F0FFFFFFF0FFFFFFF01D227EA122
>76 D<0007FC0000003FFF800000FC07E00003F001F80007E000FC000FC0007E001F80003F001F
80003F003F00001F803F00001F807F00001FC07E00000FC07E00000FC0FE00000FE0FE00000FE0
FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE0FE00000FE07E00000F
C07F00001FC07F00001FC03F00001F803F80003F801F80003F000FC0007E0007E000FC0003F001
F80000FC07E000003FFF80000007FC000023227DA12A>79 D<FFFFFF00FFFFFFE007F007F007F0
01FC07F000FC07F0007E07F0007E07F0007F07F0007F07F0007F07F0007F07F0007F07F0007E07
F0007E07F000FC07F001FC07F007F007FFFFE007FFFF0007F0000007F0000007F0000007F00000
07F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F00000FFFF80
00FFFF800020227EA126>I<FFFFFE0000FFFFFFC00007F007F00007F001F80007F000FC0007F0
007E0007F0007F0007F0007F0007F0007F0007F0007F0007F0007F0007F0007F0007F0007E0007
F000FC0007F001F80007F007F00007FFFFC00007FFFF800007F00FE00007F007F00007F003F800
07F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC0007F001FC
0007F001FC0607F000FE0607F000FF0CFFFF803FF8FFFF800FF027227EA12A>82
D<01FC0407FF8C1F03FC3C007C7C003C78001C78001CF8000CF8000CFC000CFC0000FF0000FFE0
007FFF007FFFC03FFFF01FFFF80FFFFC03FFFE003FFE0003FF00007F00003F00003FC0001FC000
1FC0001FE0001EE0001EF0003CFC003CFF00F8C7FFE080FF8018227DA11F>I<7FFFFFFF807FFF
FFFF807E03F80F807803F807807003F803806003F80180E003F801C0E003F801C0C003F800C0C0
03F800C0C003F800C0C003F800C00003F800000003F800000003F800000003F800000003F80000
0003F800000003F800000003F800000003F800000003F800000003F800000003F800000003F800
000003F800000003F800000003F800000003F800000003F800000003F800000003F8000003FFFF
F80003FFFFF80022227EA127>I<07FC001FFF803F07C03F03E03F01E03F01F01E01F00001F000
01F0003FF003FDF01FC1F03F01F07E01F0FC01F0FC01F0FC01F0FC01F07E02F07E0CF81FF87F07
E03F18167E951B>97 D<FF000000FF0000001F0000001F0000001F0000001F0000001F0000001F
0000001F0000001F0000001F0000001F0000001F0000001F0FE0001F3FF8001FF07C001F801E00
1F001F001F000F801F000F801F000FC01F000FC01F000FC01F000FC01F000FC01F000FC01F000F
C01F000FC01F000F801F001F801F801F001FC03E001EE07C001C3FF800180FC0001A237EA21F>
I<00FF8007FFE00F83F01F03F03E03F07E03F07C01E07C0000FC0000FC0000FC0000FC0000FC00
00FC00007C00007E00007E00003E00301F00600FC0E007FF8000FE0014167E9519>I<0001FE00
0001FE0000003E0000003E0000003E0000003E0000003E0000003E0000003E0000003E0000003E
0000003E0000003E0001FC3E0007FFBE000F81FE001F007E003E003E007E003E007C003E00FC00
3E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E00FC003E007C003E007C003E003E
007E001E00FE000F83BE0007FF3FC001FC3FC01A237EA21F>I<00FE0007FF800F87C01E01E03E
01F07C00F07C00F8FC00F8FC00F8FFFFF8FFFFF8FC0000FC0000FC00007C00007C00007E00003E
00181F00300FC07003FFC000FF0015167E951A>I<003F8000FFC001E3E003C7E007C7E00F87E0
0F83C00F80000F80000F80000F80000F80000F8000FFFC00FFFC000F80000F80000F80000F8000
0F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F8000
0F80007FF8007FF80013237FA211>I<03FC1E0FFF7F1F0F8F3E07CF3C03C07C03E07C03E07C03
E07C03E07C03E03C03C03E07C01F0F801FFF0013FC003000003000003800003FFF801FFFF00FFF
F81FFFFC3800FC70003EF0001EF0001EF0001EF0001E78003C7C007C3F01F80FFFE001FF001821
7E951C>I<FF000000FF0000001F0000001F0000001F0000001F0000001F0000001F0000001F00
00001F0000001F0000001F0000001F0000001F07E0001F1FF8001F307C001F403C001F803E001F
803E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E00
1F003E001F003E001F003E001F003E001F003E00FFE1FFC0FFE1FFC01A237EA21F>I<1C003F00
7F007F007F003F001C000000000000000000000000000000FF00FF001F001F001F001F001F001F
001F001F001F001F001F001F001F001F001F001F001F001F00FFE0FFE00B247EA310>I<FF00FF
001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00
1F001F001F001F001F001F001F001F001F001F001F001F00FFE0FFE00B237EA210>108
D<FF07F007F000FF1FFC1FFC001F303E303E001F403E403E001F801F801F001F801F801F001F00
1F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F
001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F001F00
1F001F00FFE0FFE0FFE0FFE0FFE0FFE02B167E9530>I<FF07E000FF1FF8001F307C001F403C00
1F803E001F803E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E
001F003E001F003E001F003E001F003E001F003E001F003E00FFE1FFC0FFE1FFC01A167E951F>
I<00FE0007FFC00F83E01E00F03E00F87C007C7C007C7C007CFC007EFC007EFC007EFC007EFC00
7EFC007EFC007E7C007C7C007C3E00F81F01F00F83E007FFC000FE0017167E951C>I<FF0FE000
FF3FF8001FF07C001F803E001F001F001F001F801F001F801F000FC01F000FC01F000FC01F000F
C01F000FC01F000FC01F000FC01F000FC01F001F801F001F801F803F001FC03E001FE0FC001F3F
F8001F0FC0001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F000000FF
E00000FFE000001A207E951F>I<FE1F00FE3FC01E67E01EC7E01E87E01E87E01F83C01F00001F
00001F00001F00001F00001F00001F00001F00001F00001F00001F00001F00001F0000FFF000FF
F00013167E9517>114 D<0FF3003FFF00781F00600700E00300E00300F00300FC00007FE0007F
F8003FFE000FFF0001FF00000F80C00780C00380E00380E00380F00700FC0E00EFFC00C7F00011
167E9516>I<0180000180000180000180000380000380000780000780000F80003F8000FFFF00
FFFF000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F8180
0F81800F81800F81800F81800F830007C30003FE0000F80011207F9F16>I<FF01FE00FF01FE00
1F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E001F003E
001F003E001F003E001F003E001F003E001F003E001F007E001F00FE000F81BE0007FF3FC001FC
3FC01A167E951F>I<FFE01FE0FFE01FE00F8006000F8006000FC00E0007C00C0007E01C0003E0
180003E0180001F0300001F0300000F8600000F86000007CC000007CC000007FC000003F800000
3F8000001F0000001F0000000E0000000E00001B167F951E>I<FFE7FF07F8FFE7FF07F81F0078
00C00F807801800F807C01800F807C018007C07E030007C0DE030007E0DE070003E0DF060003E1
8F060001F18F0C0001F38F8C0001FB079C0000FB07D80000FE03D800007E03F000007E03F00000
7C01F000003C01E000003800E000001800C00025167F9528>I<FFE01FE0FFE01FE00F8006000F
8006000FC00E0007C00C0007E01C0003E0180003E0180001F0300001F0300000F8600000F86000
007CC000007CC000007FC000003F8000003F8000001F0000001F0000000E0000000E0000000C00
00000C00000018000078180000FC380000FC300000FC60000069C000007F8000001F0000001B20
7F951E>121 D E /Fg 51 122 df<00FCF807839C0E079C1C07081C07001C07001C07001C0700
1C0700FFFFE01C07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C0700
1C0700FF1FE01617809615>11 D<00FC000782000E07001C07001C02001C00001C00001C00001C
0000FFFF001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C
0700FF1FE01317809614>I<60C0F1E0F1E070E01020102020402040408040800B0A7F9612>34
D<0102040C1818303070606060E0E0E0E0E0E0E0E0E0E060606070303018180C04020108227D98
0E>40 D<8040203018180C0C0E060606070707070707070707070606060E0C0C18183020408008
227E980E>I<60F0F070101020204040040A7D830A>44 D<FF80FF80090280870C>I<60F0F06004
047D830A>I<0018001800380030003000700060006000E000C001C00180018003800300030007
00060006000E000C000C001C001800380030003000700060006000E000C000C0000D217E9812>
I<07C018303018701C600C600CE00EE00EE00EE00EE00EE00EE00EE00EE00E600C600C701C3018
1C7007C00F157F9412>I<03000700FF0007000700070007000700070007000700070007000700
0700070007000700070007007FF00C157E9412>I<0F8030E040708030C038E038403800380070
0070006000C00180030006000C08080810183FF07FF0FFF00D157E9412>I<40007FFE7FFC7FF8
C008801080200040008000800100010003000200060006000E000E000E000E000E0004000F167E
9512>55 D<07E018302018600C600C700C78183E101F600FC00FF018F8607C601EC00EC006C006
C004600C38300FE00F157F9412>I<07C0183030186018E00CE00CE00EE00EE00E601E301E186E
0F8E000E000C001C70187018603020C01F800F157F9412>I<001000003800003800003800005C
00005C00005C00008E00008E00008E0001070001070003078002038002038007FFC00401C00401
C00800E00800E01800E03800F0FE03FE17177F961A>65 D<FFFE001C03801C00E01C00601C0070
1C00701C00701C00701C00E01C01C01FFF801FFFC01C00E01C00701C00301C00381C00381C0038
1C00381C00701C00E01C01C0FFFF0015177F9619>I<FFFFE01C00E01C00601C00201C00101C00
101C00101C04001C04001C04001C0C001FFC001C0C001C04001C04081C04081C00081C00181C00
101C00101C00301C00F0FFFFF015177F9618>69 D<FFFFE01C00E01C00601C00201C00101C0010
1C00101C04001C04001C04001C0C001FFC001C0C001C04001C04001C04001C00001C00001C0000
1C00001C00001C0000FFC00014177F9617>I<007E080381980600580C00381800183000187000
08700008E00008E00000E00000E00000E00000E003FEE000387000387000383000381800380C00
380600380380D8007F0817177E961C>I<FF83FE1C00701C00701C00701C00701C00701C00701C
00701C00701C00701C00701FFFF01C00701C00701C00701C00701C00701C00701C00701C00701C
00701C0070FF83FE17177F961A>I<FFE00E000E000E000E000E000E000E000E000E000E000E00
0E000E000E000E000E000E000E000E000E000E00FFE00B177F960D>I<00FC000303000E01C01C
00E0380070300030700038600018E0001CE0001CE0001CE0001CE0001CE0001CE0001C70003870
00383000303800701C00E00E01C003030000FC0016177E961B>79 D<FFFE001C03801C00C01C00
601C00701C00701C00701C00701C00601C00C01C03801FFE001C00001C00001C00001C00001C00
001C00001C00001C00001C00001C0000FF800014177F9618>I<FFFC001C03801C00C01C00E01C
00701C00701C00701C00701C00E01C00C01C03801FFE001C07801C01C01C00E01C00E01C00E01C
00E01C00E01C00E11C00E11C0072FF803C18177F961A>82 D<7FFFF86038184038084038088038
048038048038040038000038000038000038000038000038000038000038000038000038000038
0000380000380000380000380007FFC016177F9619>84 D<FFC03F801E001C000F000800070010
00078030000380200001C0400001E0400000E0800000F1800000710000003A0000003E0000001C
0000001C0000001C0000001C0000001C0000001C0000001C0000001C0000001C000000FF800019
1780961A>89 D<204020404080408081008100E1C0F1E0F1E060C00B0A7B9612>92
D<1FC0386038301038003803F81E3830387038E039E039E07970FF1F1E100E7F8D12>97
D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001CF8001F06001C03001C03
801C01801C01C01C01C01C01C01C01C01C01801C03801C03001B0E0010F8001217809614>I<07
F01838303870106000E000E000E000E000600070083008183007C00D0E7F8D10>I<007E00000E
00000E00000E00000E00000E00000E00000E00000E0007CE001C3E00300E00700E00600E00E00E
00E00E00E00E00E00E00600E00700E00301E00182E0007CFC012177F9614>I<0FC01860303070
38E018FFF8E000E000E000600070083010183007C00D0E7F8D10>I<03E006700E701C201C001C
001C001C001C00FF801C001C001C001C001C001C001C001C001C001C001C001C00FF800C178096
0B>I<0F9E18E33060707070707070306018C02F80200060003FE03FF83FFC600EC006C006C006
600C38380FE010157F8D12>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00
001C7C001D8E001E07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07
00FF9FE01317809614>I<183C3C1800000000007C1C1C1C1C1C1C1C1C1C1C1C1CFF081780960A>
I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C3F801C1C001C18001C20
001C40001CC0001FE0001CF0001C70001C78001C3C001C1E001C1E00FF3FC01217809613>107
D<FC001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00
1C001C001C00FF80091780960A>I<FC7C1F001D8E63801E0781C01C0701C01C0701C01C0701C0
1C0701C01C0701C01C0701C01C0701C01C0701C01C0701C01C0701C0FF9FE7F81D0E808D1E>I<
FC7C001D8E001E07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C0700
FF9FE0130E808D14>I<07C018303018600C600CE00EE00EE00EE00EE00E701C3018183007C00F
0E7F8D12>I<FCF8001F0E001C03001C03801C01801C01C01C01C01C01C01C01C01C01801C0380
1C07001F0E001CF8001C00001C00001C00001C00001C0000FF80001214808D14>I<FCF01D381E
381C101C001C001C001C001C001C001C001C001C00FF800D0E808D0E>114
D<1F4060C0C040C040E000FF007F801FC001E080608060C060E0C09F000B0E7F8D0E>I<080008
000800180018003800FF80380038003800380038003800380038403840384038401C800F000A14
7F930E>I<FC3F001C07001C07001C07001C07001C07001C07001C07001C07001C07001C07001C
0F000E170003E7E0130E808D14>I<FE1F3C0E3C0C1C081C080E100E100720072003C003C003C0
01800180100E7F8D13>I<FCFE7C3838383838101C3C201C3C201C4C200E4E400E4E400E864007
8780078780070380030300030300160E7F8D19>I<FE3F3C181C100E20074007C0038001C002E0
04F008701838383CFC7F100E7F8D13>I<FE1F3C0E3C0C1C081C080E100E100720072003C003C0
03C00180018001000100E200E200A400780010147F8D13>I E /Fh 10 58
df<1F00318060C04040C060C060C060C060C060C060C060C060404060C031801F000B107F8F0F>
48 D<0C003C00CC000C000C000C000C000C000C000C000C000C000C000C000C00FF8009107E8F
0F>I<1F00618040C08060C0600060006000C00180030006000C00102020207FC0FFC00B107F8F
0F>I<1F00218060C060C000C0008001800F00008000400060C060C060804060801F000B107F8F
0F>I<0300030007000F000B001300330023004300C300FFE003000300030003001FE00B107F8F
0F>I<20803F002C002000200020002F0030802040006000600060C06080C061801F000B107F8F
0F>I<0780184030C060C06000C000CF00F080E040C060C060C060406060C030801F000B107F8F
0F>I<40007FE07FC08080808001000200040004000C0008000800180018001800180018000B11
7E900F>I<1F00208040404040404070803F000F00338061C0C060C060C060404060801F000B10
7F8F0F>I<1F00318060C0C040C060C060C06040E021E01E600060004060C0608043003E000B10
7F8F0F>I E /Fi 68 125 df<003FC00001F0300003C0380007C07C000F807C000F807C000F80
38000F8000000F8000000F8000000F800000FFFFFC00FFFFFC000F807C000F807C000F807C000F
807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C00
0F807C007FE1FF807FE1FF80191D809C1B>12 D<003FFC0001F07C0003C07C0007C07C000F807C
000F807C000F807C000F807C000F807C000F807C000F807C00FFFFFC00FFFFFC000F807C000F80
7C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F807C000F
807C000F807C000F807C007FF3FF807FF3FF80191D809C1B>I<781E00FC3F00FC3F00FE3F80FE
3F807A1E80020080020080040100040100080200080200300C00401000110E7E9C19>34
D<78FCFCFEFE7A0202040408083040070E7D9C0D>39 D<0020004001800380030006000E001C00
1C003C0038003800780078007800F800F000F000F000F000F000F000F000F000F000F800780078
007800380038003C001C001C000E000600030003800180004000200B297C9E13>I<8000400030
00380018000C000E000700070007800380038003C003C003C003E001E001E001E001E001E001E0
01E001E001E003E003C003C003C0038003800780070007000E000C00180038003000400080000B
297D9E13>I<01C00003E00001C00041C100F1C780F9CF80FDDF803EBE0007F00007F0003EBE00
FDDF80F9CF80F1C78041C10001C00003E00001C00011127D9E18>I<0003800000038000000380
000003800000038000000380000003800000038000000380000003800000038000000380000003
800000038000FFFFFFFCFFFFFFFCFFFFFFFC000380000003800000038000000380000003800000
03800000038000000380000003800000038000000380000003800000038000000380001E1F7D99
25>I<78FCFCFEFE7A0202040408083040070E7D850D>I<FFE0FFE0FFE0FFE00B047F8A10>I<78
FCFCFCFC7806067D850D>I<000180000380000380000700000700000700000E00000E00001C00
001C00001C0000380000380000380000700000700000E00000E00000E00001C00001C00001C000
0380000380000380000700000700000E00000E00000E00001C00001C00001C0000380000380000
700000700000700000E00000E00000C0000011297D9E18>I<00600001E0000FE000FFE000F3E0
0003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E00003E0
0003E00003E00003E00003E00003E00003E00003E0007FFF807FFF80111B7D9A18>49
D<07F8001FFE00383F80780FC0FC07C0FC07E0FC03E0FC03E07803E00007E00007C00007C0000F
80001F00001E0000380000700000E0000180600300600600600800E01FFFC03FFFC07FFFC0FFFF
C0FFFFC0131B7E9A18>I<03F8001FFE003C1F003C0F807C07C07E07C07C07C03807C0000F8000
0F80001E00003C0003F800001E00000F800007C00007C00007E03007E07807E0FC07E0FC07E0FC
07C0780F80781F001FFE0007F800131B7E9A18>I<000180000380000780000F80001F80003F80
006F8000CF80008F80018F80030F80060F800C0F80180F80300F80600F80C00F80FFFFF8FFFFF8
000F80000F80000F80000F80000F80000F8001FFF801FFF8151B7F9A18>I<1801801FFF001FFE
001FFC001FF8001FC00018000018000018000018000019F8001E0E00180F801007800007C00007
E00007E00007E07807E0F807E0F807E0F807C0F007C0600F80381F001FFE0007F000131B7E9A18
>I<007E0003FF000781800F03C01E07C03C07C03C0380780000780000F80000F8F800FB0E00FA
0780FC0380FC03C0F803E0F803E0F803E0F803E07803E07803E07803C03C03C03C07801E0F0007
FE0003F800131B7E9A18>I<78FCFCFCFC7800000000000078FCFCFCFC7806127D910D>58
D<00038000000380000007C0000007C0000007C000000FE000000FE000001FF000001BF000001B
F0000031F8000031F8000061FC000060FC0000E0FE0000C07E0000C07E0001803F0001FFFF0003
FFFF8003001F8003001F8006000FC006000FC00E000FE00C0007E0FFC07FFEFFC07FFE1F1C7E9B
24>65 D<FFFFF800FFFFFF000FC01F800FC00FC00FC007C00FC007E00FC007E00FC007E00FC007
E00FC007E00FC007C00FC00F800FC03F000FFFFE000FC00F800FC007C00FC007E00FC003E00FC0
03F00FC003F00FC003F00FC003F00FC003F00FC007E00FC007E00FC01FC0FFFFFF00FFFFFC001C
1C7E9B22>I<001FE02000FFF8E003F80FE007C003E00F8001E01F0000E03E0000E03E0000607E
0000607C000060FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000
7C0000607E0000603E0000603E0000C01F0000C00F80018007C0030003F80E0000FFFC00001FE0
001B1C7D9B22>I<FFFFF800FFFFFF000FC01FC00FC007E00FC001F00FC001F80FC000F80FC000
FC0FC0007C0FC0007C0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0007E0FC0
007E0FC0007C0FC0007C0FC0007C0FC000F80FC000F80FC001F00FC007E00FC01FC0FFFFFF00FF
FFF8001F1C7E9B25>I<FFFFFF00FFFFFF000FC01F000FC007000FC003000FC003800FC003800F
C181800FC181800FC181800FC180000FC380000FFF80000FFF80000FC380000FC180000FC18000
0FC180600FC180600FC000E00FC000C00FC000C00FC001C00FC001C00FC003C00FC00F80FFFFFF
80FFFFFF801B1C7E9B1F>I<FFFFFF00FFFFFF000FC01F000FC007000FC003000FC003800FC003
800FC001800FC181800FC181800FC180000FC180000FC380000FFF80000FFF80000FC380000FC1
80000FC180000FC180000FC180000FC000000FC000000FC000000FC000000FC000000FC00000FF
FF0000FFFF0000191C7E9B1E>I<000FF008007FFE3801FC07F807E001F80F8000781F0000783F
0000383E0000387E0000187C000018FC000000FC000000FC000000FC000000FC000000FC000000
FC007FFFFC007FFF7C0001F87E0001F83E0001F83F0001F81F0001F80F8001F807E001F801FC07
F8007FFE78000FF818201C7D9B26>I<FFFC3FFFFFFC3FFF0FC003F00FC003F00FC003F00FC003
F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FFFFFF00FFFFFF00FC003F00FC0
03F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00FC003F00F
C003F0FFFC3FFFFFFC3FFF201C7E9B25>I<FFFFFFFF07E007E007E007E007E007E007E007E007
E007E007E007E007E007E007E007E007E007E007E007E007E007E007E007E0FFFFFFFF101C7F9B
12>I<FFFF00FFFF000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC0000FC000
0FC0000FC0000FC0000FC0000FC0000FC0030FC0030FC0030FC0070FC0070FC0060FC00E0FC01E
0FC07EFFFFFEFFFFFE181C7E9B1D>76 D<FFC00003FFFFE00007FF0FE00007F00DF0000DF00DF0
000DF00DF0000DF00CF80019F00CF80019F00C7C0031F00C7C0031F00C3E0061F00C3E0061F00C
1F00C1F00C1F00C1F00C1F00C1F00C0F8181F00C0F8181F00C07C301F00C07C301F00C03E601F0
0C03E601F00C01FC01F00C01FC01F00C01FC01F00C00F801F00C00F801F0FFC0701FFFFFC0701F
FF281C7E9B2D>I<FFE003FFFFE003FF0FF000300FF800300DFC00300CFE00300C7E00300C3F00
300C1F80300C1FC0300C0FE0300C07F0300C03F0300C01F8300C01FC300C00FE300C007F300C00
3F300C001FB00C001FF00C000FF00C0007F00C0003F00C0001F00C0000F00C0000F0FFC00070FF
C00030201C7E9B25>I<003FE00001F07C0003C01E000F800F801F0007C01E0003C03E0003E07E
0003F07C0001F07C0001F0FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8
FC0001F87C0001F07E0003F07E0003F03E0003E03F0007E01F0007C00F800F8003C01E0001F07C
00003FE0001D1C7D9B24>I<FFFFF800FFFFFE000FC03F800FC00F800FC007C00FC007E00FC007
E00FC007E00FC007E00FC007E00FC007C00FC007C00FC00F800FC03F000FFFFC000FC000000FC0
00000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC000000FC00000FF
FC0000FFFC00001B1C7E9B21>I<003FE00001F07C0003C01E000F800F801F0007C01F0007C03E
0003E07E0003F07C0001F07C0001F0FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8FC0001F8
FC0001F8FC0001F87C0001F07C0001F07E0003F03E0003E03E0703E01F08C7C00F906F8003D03E
0001F87C00003FF8080000180800001C1800001FF800001FF800000FF000000FF0000007E00000
03C01D247D9B24>I<FFFFF00000FFFFFE00000FC03F00000FC00F80000FC007C0000FC007E000
0FC007E0000FC007E0000FC007E0000FC007E0000FC007C0000FC00F80000FC03E00000FFFF000
000FC07C00000FC03E00000FC03F00000FC01F80000FC01F80000FC01F80000FC01F80000FC01F
80000FC01F80000FC01F81800FC01F81800FC00FC180FFFC07C300FFFC01FE00211C7E9B24>I<
07F8201FFEE03C07E07801E07000E0F000E0F00060F00060F80000FE0000FFE0007FFE003FFF00
3FFF800FFFC007FFE0007FE00003F00001F00000F0C000F0C000F0C000E0E000E0F001C0FC03C0
EFFF0083FC00141C7D9B1B>I<7FFFFFE07FFFFFE0781F81E0701F80E0601F8060E01F8070C01F
8030C01F8030C01F8030C01F8030001F8000001F8000001F8000001F8000001F8000001F800000
1F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000001F8000
07FFFE0007FFFE001C1C7E9B21>I<FFFC03FFFFFC03FF0FC000300FC000300FC000300FC00030
0FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000300FC000
300FC000300FC000300FC000300FC000300FC0003007C0003007C0006003E000E001F001C000FC
0780007FFE00000FF800201C7E9B25>I<FFFC01FF80FFFC01FF800FC000180007E000300007E0
00300007F000700003F000600003F800E00001F800C00001FC00C00000FC01800000FC01800000
7E030000007E030000007F070000003F060000003F8E0000001F8C0000001FCC0000000FD80000
000FD800000007F000000007F000000007F000000003E000000003E000000001C000000001C000
00211C7F9B24>I<FFFC7FFE0FFCFFFC7FFE0FFC0FC007E000C00FC007F000C00FE003F001C007
E003F0018007E007F8018003F007F8030003F007F8030003F80CFC070001F80CFC060001F81CFE
060001FC187E0E0000FC187E0C0000FC387F0C00007E303F1800007E303F1800007F601FB80000
3F601FB000003FE01FF000003FC00FF000001FC00FE000001FC00FE000000F8007C000000F8007
C000000F0003C0000007000380000007000380002E1C7F9B31>I<7FFE1FFE007FFE1FFE0007F0
01800003F803800001FC07000000FC06000000FE0C0000007F1C0000003F380000003FB0000000
1FE00000000FE00000000FE000000007F000000003F800000007F80000000FFC0000000CFE0000
00187E000000387F000000703F800000601F800000C01FC00001C00FE000018007F000030007F0
00FFF03FFF80FFF03FFF80211C7F9B24>I<7FFFFC7FFFFC7E01F87803F87003F0E007E0E007E0
C00FC0C01FC0C01F80003F00007F00007E0000FC0000FC0001F80003F80603F00607E0060FE006
0FC00E1F800E1F801C3F001C7F003C7E00FCFFFFFCFFFFFC171C7D9B1D>90
D<040100180600200800200800401000401000802000802000BC2F00FE3F80FE3F807E1F807E1F
803C0F00110E7B9C19>92 D<0FF8001C1E003E0F803E07803E07C01C07C00007C0007FC007E7C0
1F07C03C07C07C07C0F807C0F807C0F807C0780BC03E13F80FE1F815127F9117>97
D<FF0000FF00001F00001F00001F00001F00001F00001F00001F00001F00001F00001F3F801FE1
E01F80701F00781F003C1F003C1F003E1F003E1F003E1F003E1F003E1F003E1F003C1F003C1F00
781F80701EC1E01C3F00171D7F9C1B>I<03FC000E0E001C1F003C1F00781F00780E00F80000F8
0000F80000F80000F80000F800007800007801803C01801C03000E0E0003F80011127E9115>I<
000FF0000FF00001F00001F00001F00001F00001F00001F00001F00001F00001F001F9F00F07F0
1C03F03C01F07801F07801F0F801F0F801F0F801F0F801F0F801F0F801F07801F07801F03C01F0
1C03F00F0FFE03F9FE171D7E9C1B>I<01FC000F07001C03803C01C07801C07801E0F801E0F801
E0FFFFE0F80000F80000F800007800007C00603C00601E00C00F038001FC0013127F9116>I<00
7F0001E38003C7C00787C00F87C00F83800F80000F80000F80000F80000F8000FFF800FFF8000F
80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F80000F
80007FF8007FF800121D809C0F>I<03F8F00E0F381E0F381C07303C07803C07803C07803C0780
1C07001E0F000E0E001BF8001000001800001800001FFF001FFFC00FFFE01FFFF07801F8F00078
F00078F000787000707800F01E03C007FF00151B7F9118>I<FF0000FF00001F00001F00001F00
001F00001F00001F00001F00001F00001F00001F0FC01F31E01F40F01F80F81F80F81F00F81F00
F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F8FFE7FFFFE7FF181D7F9C1B
>I<1E003F003F003F003F001E00000000000000000000000000FF00FF001F001F001F001F001F
001F001F001F001F001F001F001F001F001F00FFE0FFE00B1E7F9D0E>I<FF0000FF00001F0000
1F00001F00001F00001F00001F00001F00001F00001F00001F0FF81F0FF81F03801F07001F0C00
1F18001F70001FF8001FFC001FBC001F3E001F1F001F0F001F0F801F07C01F03E0FFC7FCFFC7FC
161D7F9C19>107 D<FF00FF001F001F001F001F001F001F001F001F001F001F001F001F001F00
1F001F001F001F001F001F001F001F001F001F001F001F00FFE0FFE00B1D7F9C0E>I<FF0FC07E
00FF31E18F001F40F207801F80FC07C01F80FC07C01F00F807C01F00F807C01F00F807C01F00F8
07C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C01F00F807C0FFE7
FF3FF8FFE7FF3FF825127F9128>I<FF0FC0FF31E01F40F01F80F81F80F81F00F81F00F81F00F8
1F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F8FFE7FFFFE7FF18127F911B>I<01FC
000F07801C01C03C01E07800F07800F0F800F8F800F8F800F8F800F8F800F8F800F87800F07800
F03C01E01E03C00F078001FC0015127F9118>I<FF3F80FFE1E01F80F01F00781F007C1F003C1F
003E1F003E1F003E1F003E1F003E1F003E1F003C1F007C1F00781F80F01FC1E01F3F001F00001F
00001F00001F00001F00001F0000FFE000FFE000171A7F911B>I<FE3E00FE47001E8F801E8F80
1E8F801F07001F00001F00001F00001F00001F00001F00001F00001F00001F00001F0000FFF000
FFF00011127F9114>114 D<1FD830786018E018E018F000FF807FE07FF01FF807FC007CC01CC0
1CE01CE018F830CFC00E127E9113>I<0300030003000300070007000F000F003FFCFFFC1F001F
001F001F001F001F001F001F001F001F0C1F0C1F0C1F0C0F08079803F00E1A7F9913>I<FF07F8
FF07F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F81F00F8
1F01F80F01F80786FF01F8FF18127F911B>I<FFC1FCFFC1FC1F00601F80E00F80C00FC0C007C1
8007C18003E30003E30001F60001F60001FE0000FC0000FC0000780000780000300016127F9119
>I<FF8FF8FEFF8FF8FE1F03E0301F03E0301F83E0700F83F0600F86F06007C6F0C007CEF8C007
EC79C003EC7D8003F83D8001F83F0001F83F0001F01F0000F01E0000E00E0000E00E001F127F91
22>I<FFC7FCFFC7FC1F81800F838007C70003EE0001FC0001F80000F800007C0000FE0001DF00
039F00070F800607C00C03E0FF07FCFF07FC16127F9119>I<FFC1FCFFC1FC1F00601F80E00F80
C00FC0C007C18007C18003E30003E30001F70001F60000FE0000FC0000FC000078000078000030
00003000007000706000F86000F8C000F980007300003E0000161A7F9119>I<3FFF803C1F0030
3F00303E00607C0060FC0060F80001F00003F00007E00007C1800F81801F81801F03803E03007E
07007C0F00FFFF0011127F9115>I<FFFFFFFFFFFE2F01808B30>124 D E
/Fj 10 58 df<0F0030C0606060604020C030C030C030C030C030C030C030C030C03040206060
606030C00F000C137E9211>48 D<0C001C00EC000C000C000C000C000C000C000C000C000C000C
000C000C000C000C000C00FFC00A137D9211>I<1F0060C06060F070F030603000700070006000
C001C00180020004000810101020207FE0FFE00C137E9211>I<0FC03070703870387038003800
3000E00FC0007000380018001C601CF01CF018E03860701FC00E137F9211>I<006000E000E001
60026006600C600860106020606060C060FFFC0060006000600060006003FC0E137F9211>I<60
607FC07F8044004000400040004F0070C040E0006000700070E070E070E06040E021C01F000C13
7E9211>I<07C00C201070207060006000C000CF00D0C0E060C020C030C030C030403060202060
10C00F000C137E9211>I<40007FFC7FF840108010802000400080010001000300020006000600
0E000E000E000E000E0004000E147E9311>I<0FC0003000084008600870083C103F600F800FE0
31F06078C01CC00CC00CC00C601830300FC00E137F9211>I<0F00308060404060C020C030C030
C0304030607030B00F30003000200060E040E08041003E000C137E9211>I
E /Fk 83 125 df<007E1F0001C1B1800303E3C00703C3C00E03C1800E01C0000E01C0000E01C0
000E01C0000E01C0000E01C000FFFFFC000E01C0000E01C0000E01C0000E01C0000E01C0000E01
C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E01C0000E
01C0007F87FC001A1D809C18>11 D<007E0001C1800301800703C00E03C00E01800E00000E0000
0E00000E00000E0000FFFFC00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0
0E01C00E01C00E01C00E01C00E01C00E01C00E01C07F87F8151D809C17>I<007FC001C1C00303
C00703C00E01C00E01C00E01C00E01C00E01C00E01C00E01C0FFFFC00E01C00E01C00E01C00E01
C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C00E01C07FCF
F8151D809C17>I<003F07E00001C09C18000380F018000701F03C000E01E03C000E00E018000E
00E000000E00E000000E00E000000E00E000000E00E00000FFFFFFFC000E00E01C000E00E01C00
0E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C
000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C000E00E01C007FC7FCFF80211D80
9C23>I<6060F0F0F8F86868080808080808101010102020404080800D0C7F9C15>34
D<0F0000C0188001C030600380703807806027FF00E0100600E0100E00E0101C00E0101800E010
3800E0103000E01070006020E0007020C0003041C000188380000F0303C000070620000E0C1000
0C1C08001C18080038380400303804007038040060380400E0380401C038040180380403801808
07001C0806000C100E0006200C0003C01E217E9E23>37 D<00E000000190000003080000030800
00070800000708000007080000070800000710000007100000072000000740000003C03FE00380
0F00038006000380040005C0040009C0080010E0100030E010006070200060702000E0384000E0
3C4000E01C8000E00F0020E0070020700780403009C0401830E18007C03E001B1F7E9D20>I<60
F0F8680808081010204080050C7C9C0C>I<004000800100020006000C000C0018001800300030
007000600060006000E000E000E000E000E000E000E000E000E000E000E000E000600060006000
700030003000180018000C000C00060002000100008000400A2A7D9E10>I<8000400020001000
18000C000C000600060003000300038001800180018001C001C001C001C001C001C001C001C001
C001C001C001C0018001800180038003000300060006000C000C00180010002000400080000A2A
7E9E10>I<01800180018001804182F18F399C0FF003C003C00FF0399CF18F4182018001800180
018010127E9E15>I<60F0F0701010101020204080040C7C830C>44 D<FFE0FFE00B0280890E>I<
60F0F06004047C830C>I<00030003000700060006000E000C001C001800180038003000300070
0060006000E000C000C001C001800380030003000700060006000E000C000C001C001800180038
003000700060006000E000C000C00010297E9E15>I<03C00C301818300C300C700E60066006E0
07E007E007E007E007E007E007E007E007E007E007E007E00760066006700E300C300C18180C30
07E0101D7E9B15>I<030007003F00C70007000700070007000700070007000700070007000700
070007000700070007000700070007000700070007000F80FFF80D1C7C9B15>I<07C01830201C
400C400EF00FF80FF807F8077007000F000E000E001C001C00380070006000C00180030006010C
01180110023FFE7FFEFFFE101C7E9B15>I<07E01830201C201C781E780E781E381E001C001C00
180030006007E00030001C001C000E000F000F700FF80FF80FF80FF00E401C201C183007E0101D
7E9B15>I<000C00000C00001C00003C00003C00005C0000DC00009C00011C00031C00021C0004
1C000C1C00081C00101C00301C00201C00401C00C01C00FFFFC0001C00001C00001C00001C0000
1C00001C00001C0001FFC0121C7F9B15>I<300C3FF83FF03FC020002000200020002000200023
E024302818301C200E000E000F000F000F600FF00FF00FF00F800E401E401C2038187007C0101D
7E9B15>I<00F0030C06040C0E181E301E300C700070006000E3E0E430E818F00CF00EE006E007
E007E007E007E007600760077006300E300C18180C3003E0101D7E9B15>I<4000007FFF807FFF
007FFF0040020080040080040080080000100000100000200000600000400000C00000C00001C0
000180000180000380000380000380000380000780000780000780000780000780000780000300
00111D7E9B15>I<03E00C301008200C20066006600660067006780C3E083FB01FE007F007F818
FC307E601E600FC007C003C003C003C00360026004300C1C1007E0101D7E9B15>I<03C00C3018
18300C700C600EE006E006E007E007E007E007E0076007700F300F18170C2707C700060006000E
300C780C78187010203030C00F80101D7E9B15>I<60F0F0600000000000000000000060F0F060
04127C910C>I<60F0F0600000000000000000000060F0F0701010101020204080041A7C910C>I<
7FFFFFC0FFFFFFE000000000000000000000000000000000000000000000000000000000000000
00FFFFFFE07FFFFFC01B0C7E8F20>61 D<003F800000C060000300180004000400080002001000
0100201F00802070808040E0404040C0384041C038408180382083803820838038208380382083
803820838038208180382041C0382040C0384040E0784020709880201F0F001000000008000000
04000000030001E000C01F80003FF0001B1D7E9C20>64 D<000600000006000000060000000F00
00000F0000000F00000017800000178000001780000023C0000023C0000023C0000041E0000041
E0000041E0000080F0000080F0000180F8000100780001FFF80003007C0002003C0002003C0006
003E0004001E0004001E000C001F001E001F00FF80FFF01C1D7F9C1F>I<FFFFC00F00F00F0038
0F003C0F001C0F001E0F001E0F001E0F001E0F001C0F003C0F00780F01F00FFFE00F00780F003C
0F001E0F000E0F000F0F000F0F000F0F000F0F000F0F001E0F001E0F003C0F0078FFFFE0181C7E
9B1D>I<001F808000E0618001801980070007800E0003801C0003801C00018038000180780000
807800008070000080F0000000F0000000F0000000F0000000F0000000F0000000F0000000F000
0000700000807800008078000080380000801C0001001C0001000E000200070004000180080000
E03000001FC000191E7E9C1E>I<FFFFC0000F00F0000F003C000F000E000F0007000F0007000F
0003800F0003C00F0001C00F0001C00F0001E00F0001E00F0001E00F0001E00F0001E00F0001E0
0F0001E00F0001E00F0001C00F0001C00F0003C00F0003800F0007800F0007000F000E000F001C
000F007000FFFFC0001B1C7E9B20>I<FFFFFC0F003C0F000C0F00040F00040F00060F00020F00
020F02020F02000F02000F02000F06000FFE000F06000F02000F02000F02000F02010F00010F00
020F00020F00020F00060F00060F000C0F003CFFFFFC181C7E9B1C>I<FFFFF80F00780F00180F
00080F00080F000C0F00040F00040F02040F02000F02000F02000F06000FFE000F06000F02000F
02000F02000F02000F00000F00000F00000F00000F00000F00000F00000F8000FFF800161C7E9B
1B>I<001F808000E0618001801980070007800E0003801C0003801C0001803800018078000080
7800008070000080F0000000F0000000F0000000F0000000F0000000F0000000F000FFF0F0000F
80700007807800078078000780380007801C0007801C0007800E00078007000B800180118000E0
6080001F80001C1E7E9C21>I<FFF3FFC00F003C000F003C000F003C000F003C000F003C000F00
3C000F003C000F003C000F003C000F003C000F003C000F003C000FFFFC000F003C000F003C000F
003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C000F003C00
0F003C00FFF3FFC01A1C7E9B1F>I<FFF00F000F000F000F000F000F000F000F000F000F000F00
0F000F000F000F000F000F000F000F000F000F000F000F000F000F000F00FFF00C1C7F9B0F>I<
FFF03FE00F000F000F000C000F0008000F0010000F0020000F0040000F0080000F0100000F0200
000F0400000F0E00000F1F00000F2F00000F2780000F4780000F83C0000F01E0000F01E0000F00
F0000F00F8000F0078000F003C000F003C000F001E000F001F000F001F80FFF07FF01C1C7E9B20
>75 D<FFF8000F80000F00000F00000F00000F00000F00000F00000F00000F00000F00000F0000
0F00000F00000F00000F00000F00000F00000F00080F00080F00080F00180F00180F00100F0030
0F00700F01F0FFFFF0151C7E9B1A>I<FF8000FF800F8000F8000F8000F8000BC00178000BC001
78000BC001780009E002780009E002780008F004780008F004780008F004780008780878000878
0878000878087800083C107800083C107800083C107800081E207800081E207800081E20780008
0F407800080F40780008078078000807807800080780780008030078001C03007800FF8307FF80
211C7E9B26>I<FF007FC00F800E000F8004000BC0040009E0040009E0040008F0040008F80400
08780400083C0400083C0400081E0400080F0400080F0400080784000807C4000803C4000801E4
000801E4000800F40008007C0008007C0008003C0008003C0008001C0008000C001C000C00FF80
04001A1C7E9B1F>I<003F800000E0E0000380380007001C000E000E001C0007003C0007803800
0380780003C0780003C0700001C0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0F0
0001E0F00001E0700001C0780003C0780003C0380003803C0007801C0007000E000E0007001C00
0380380000E0E000003F80001B1E7E9C20>I<FFFF800F00E00F00780F003C0F001C0F001E0F00
1E0F001E0F001E0F001E0F001C0F003C0F00780F00E00FFF800F00000F00000F00000F00000F00
000F00000F00000F00000F00000F00000F00000F0000FFF000171C7E9B1C>I<003F800000E0E0
000380380007001C000E000E001C0007003C00078038000380780003C0780003C0700001C0F000
01E0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0F00001E0700001C0780003C078
0003C0380003803C0E07801C1107000E208E0007205C0003A0780000F0E020003FE02000006020
00003060000038E000003FC000003FC000001F8000000F001B257E9C20>I<FFFF00000F01E000
0F0078000F003C000F001C000F001E000F001E000F001E000F001E000F001C000F003C000F0078
000F01E0000FFF00000F03C0000F00E0000F00F0000F0078000F0078000F0078000F0078000F00
78000F0078000F0078100F0078100F0038100F003C20FFF01C20000007C01C1D7E9B1F>I<07E0
801C1980300580700380600180E00180E00080E00080E00080F00000F800007C00007FC0003FF8
001FFE0007FF0000FF80000F800007C00003C00001C08001C08001C08001C0C00180C00180E003
00D00200CC0C0083F800121E7E9C17>I<7FFFFFC0700F01C0600F00C0400F0040400F0040C00F
0020800F0020800F0020800F0020000F0000000F0000000F0000000F0000000F0000000F000000
0F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000000F0000
000F0000001F800003FFFC001B1C7F9B1E>I<FFF07FC00F000E000F0004000F0004000F000400
0F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004000F0004
000F0004000F0004000F0004000F0004000F0004000F0004000F00040007000800078008000380
10000180100000C020000070C000001F00001A1D7E9B1F>I<FFE00FF01F0003C00F0001800F00
01000F800300078002000780020003C0040003C0040003C0040001E0080001E0080001F0080000
F0100000F0100000F830000078200000782000003C4000003C4000003C4000001E8000001E8000
001F8000000F0000000F00000006000000060000000600001C1D7F9B1F>I<FFE0FFE0FF1F001F
003C1E001E00180F001F00100F001F00100F001F001007801F00200780278020078027802003C0
27804003C043C04003C043C04003E043C04001E081E08001E081E08001E081E08000F100F10000
F100F10000F100F100007900FA00007A007A00007A007A00003E007C00003C003C00003C003C00
003C003C00001800180000180018000018001800281D7F9B2B>I<7FF0FFC00FC03E0007801800
03C0180003E0100001E0200001F0600000F0400000788000007D8000003D0000001E0000001F00
00000F0000000F8000000F80000013C0000023E0000021E0000041F00000C0F800008078000100
7C0003003C0002001E0006001F001F003F80FFC0FFF01C1C7F9B1F>I<7FFFF07C01F07001E060
03C06003C0400780400F80400F00401E00001E00003C00007C0000780000F00000F00001E00003
E00003C0100780100780100F00101F00301E00203C00203C00607800E0F803E0FFFFE0141C7E9B
19>90 D<FEFEC0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0
C0C0C0C0FEFE07297C9E0C>I<08081010202040404040808080808080B0B0F8F8787830300D0C
7A9C15>I<FEFE0606060606060606060606060606060606060606060606060606060606060606
0606060606FEFE0729809E0C>I<1FC000307000783800781C00301C00001C00001C0001FC000F
1C00381C00701C00601C00E01C40E01C40E01C40603C40304E801F870012127E9115>97
D<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C7C001D86
001E03001C01801C01C01C00C01C00E01C00E01C00E01C00E01C00E01C00E01C00C01C01C01C01
801E030019060010F800131D7F9C17>I<07E00C301878307870306000E000E000E000E000E000
E00060007004300418080C3007C00E127E9112>I<003F00000700000700000700000700000700
00070000070000070000070000070003E7000C1700180F00300700700700600700E00700E00700
E00700E00700E00700E00700600700700700300700180F000C370007C7E0131D7E9C17>I<03E0
0C301818300C700E6006E006FFFEE000E000E000E00060007002300218040C1803E00F127F9112
>I<00F8018C071E061E0E0C0E000E000E000E000E000E00FFE00E000E000E000E000E000E000E
000E000E000E000E000E000E000E000E000E007FE00F1D809C0D>I<00038003C4C00C38C01C38
80181800381C00381C00381C00381C001818001C38000C300013C0001000003000001800001FF8
001FFF001FFF803003806001C0C000C0C000C0C000C06001803003001C0E0007F800121C7F9215
>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C7C001C
87001D03001E03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C
03801C03801C0380FF9FF0141D7F9C17>I<18003C003C00180000000000000000000000000000
00FC001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00FF80091D
7F9C0C>I<00C001E001E000C000000000000000000000000000000FE000E000E000E000E000E0
00E000E000E000E000E000E000E000E000E000E000E000E000E000E000E060E0F0C0F1C061803E
000B25839C0D>I<FC00001C00001C00001C00001C00001C00001C00001C00001C00001C00001C
00001C3FC01C0F001C0C001C08001C10001C20001C40001CE0001DE0001E70001C78001C38001C
3C001C1C001C0E001C0F001C0F80FF9FE0131D7F9C16>I<FC001C001C001C001C001C001C001C
001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C001C00
1C00FF80091D7F9C0C>I<FC7E07E0001C838838001D019018001E01E01C001C01C01C001C01C0
1C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01C01C001C01
C01C001C01C01C001C01C01C001C01C01C00FF8FF8FF8021127F9124>I<FC7C001C87001D0300
1E03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C0380
1C0380FF9FF014127F9117>I<03F0000E1C00180600300300700380600180E001C0E001C0E001
C0E001C0E001C0E001C06001807003803003001806000E1C0003F00012127F9115>I<FC7C001D
86001E03001C01801C01C01C00C01C00E01C00E01C00E01C00E01C00E01C00E01C01C01C01C01C
01801E03001D06001CF8001C00001C00001C00001C00001C00001C00001C0000FF8000131A7F91
17>I<03C1000C3300180B00300F00700700700700E00700E00700E00700E00700E00700E00700
600700700700300F00180F000C370007C700000700000700000700000700000700000700000700
003FE0131A7E9116>I<FCE01D301E781E781C301C001C001C001C001C001C001C001C001C001C
001C001C00FFC00D127F9110>I<1F9030704030C010C010E010F8007F803FE00FF000F8803880
18C018C018E010D0608FC00D127F9110>I<04000400040004000C000C001C003C00FFE01C001C
001C001C001C001C001C001C001C001C101C101C101C101C100C100E2003C00C1A7F9910>I<FC
1F801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C03801C
03801C07800C07800E1B8003E3F014127F9117>I<FF07E03C03801C01001C01000E02000E0200
07040007040007040003880003880003D80001D00001D00000E00000E00000E00000400013127F
9116>I<FF3FCFE03C0F03801C0701801C0701001C0B01000E0B82000E0B82000E1182000711C4
000711C4000720C40003A0E80003A0E80003C0680001C0700001C0700001803000008020001B12
7F911E>I<7F8FF00F03800F030007020003840001C80001D80000F00000700000780000F80000
9C00010E00020E000607000403801E07C0FF0FF81512809116>I<FF07E03C03801C01001C0100
0E02000E020007040007040007040003880003880003D80001D00001D00000E00000E00000E000
004000004000008000008000F08000F10000F300006600003C0000131A7F9116>I<7FFC703860
38407040F040E041C003C0038007000F040E041C043C0C380870087038FFF80E127F9112>I<FF
FFFFFFFF802901808B2A>124 D E /Fl 35 122 df<0001FF0000001FFFC000007F81E00000FC
01E00001F807F00003F807F00007F007F00007F007F00007F007F00007F007F00007F001C00007
F000000007F000000007F000000007F03FF800FFFFFFF800FFFFFFF800FFFFFFF80007F003F800
07F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F8
0007F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003F80007F003
F80007F003F80007F003F80007F003F80007F003F8007FFF3FFF807FFF3FFF807FFF3FFF80212A
7FA925>12 D<3C007F00FF80FF80FFC0FFC0FFC07FC03EC000C000C00180018001800300030006
000E001C00380030000A157BA913>39 D<000E00001E00007E0007FE00FFFE00FFFE00F8FE0000
FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000
FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000
FE0000FE0000FE007FFFFE7FFFFE7FFFFE17277BA622>49 D<00FF800007FFF0000FFFFC001E03
FE003800FF807C003F80FE003FC0FF001FC0FF001FE0FF000FE0FF000FE07E000FE03C001FE000
001FE000001FC000001FC000003F8000003F0000007E000000FC000000F8000001F0000003E000
00078000000F0000001E0000003C00E0007000E000E000E001C001C0038001C0060001C00FFFFF
C01FFFFFC03FFFFFC07FFFFFC0FFFFFF80FFFFFF80FFFFFF801B277DA622>I<007F800003FFF0
0007FFFC000F80FE001F007F003F807F003F803F803F803F803F803F801F803F801F003F800000
7F0000007F0000007E000000FC000001F8000007F00000FFC00000FFC0000001F80000007E0000
003F0000003F8000001FC000001FC000001FE000001FE03C001FE07E001FE0FF001FE0FF001FE0
FF001FC0FF003FC0FE003F807C007F003F00FE001FFFFC0007FFF00000FF80001B277DA622>I<
FFFFFFF800FFFFFFFF00FFFFFFFFC003F8001FE003F8000FF003F80007F803F80003F803F80003
FC03F80003FC03F80001FC03F80001FC03F80001FC03F80003FC03F80003F803F80003F803F800
07F003F8000FF003F8001FC003F800FF8003FFFFFE0003FFFFFFC003F8000FF003F80003F803F8
0001FC03F80001FE03F80000FE03F80000FE03F80000FF03F80000FF03F80000FF03F80000FF03
F80000FF03F80000FF03F80000FE03F80001FE03F80003FC03F80007FC03F8001FF8FFFFFFFFE0
FFFFFFFFC0FFFFFFFE0028297DA830>66 D<00007FE0030007FFFC07001FFFFF0F007FF00F9F00
FF0001FF01FC0000FF03F800007F07F000003F0FE000001F1FC000001F1FC000000F3F8000000F
3F800000077F800000077F800000077F00000000FF00000000FF00000000FF00000000FF000000
00FF00000000FF00000000FF00000000FF00000000FF000000007F000000007F800000007F8000
00073F800000073F800000071FC00000071FC000000E0FE000000E07F000001C03F800003C01FC
00007800FF0001F0007FF007C0001FFFFF800007FFFE0000007FF00028297CA831>I<FFFFFFFF
C0FFFFFFFFC0FFFFFFFFC003FC003FC003FC000FE003FC0003E003FC0001E003FC0001E003FC00
00E003FC0000E003FC0000E003FC0000F003FC01C07003FC01C07003FC01C07003FC01C00003FC
03C00003FC03C00003FC0FC00003FFFFC00003FFFFC00003FFFFC00003FC0FC00003FC03C00003
FC03C00003FC01C00003FC01C00003FC01C00003FC01C00003FC00000003FC00000003FC000000
03FC00000003FC00000003FC00000003FC00000003FC00000003FC000000FFFFFC0000FFFFFC00
00FFFFFC000024297EA82A>70 D<FFFFFCFFFFFCFFFFFC01FE0001FE0001FE0001FE0001FE0001
FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001
FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001FE0001
FE0001FE0001FE0001FE00FFFFFCFFFFFCFFFFFC16297FA819>73 D<FFFFFC0000FFFFFC0000FF
FFFC000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC000000
03FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0000
0003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0001C003FC00
01C003FC0001C003FC0001C003FC0003C003FC00038003FC00038003FC00078003FC00078003FC
000F8003FC000F8003FC001F8003FC007F8003FC01FF00FFFFFFFF00FFFFFFFF00FFFFFFFF0022
297EA828>76 D<FFFFFFF800FFFFFFFF00FFFFFFFFC003FC003FE003FC0007F003FC0003F803FC
0003FC03FC0001FC03FC0001FE03FC0001FE03FC0001FE03FC0001FE03FC0001FE03FC0001FE03
FC0001FE03FC0001FC03FC0003FC03FC0003F803FC0007F003FC003FE003FFFFFF8003FFFFFE00
03FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC0000
0003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00000003FC00
0000FFFFF00000FFFFF00000FFFFF0000027297EA82E>80 D<00FF00C003FFE1C00FFFF9C01F80
FFC03F003FC03E000FC07C0007C07C0007C0FC0003C0FC0003C0FC0001C0FE0001C0FE0001C0FF
000000FFC000007FFC00007FFFE0003FFFF8001FFFFE001FFFFF0007FFFF8003FFFFC000FFFFC0
000FFFE000007FE000001FF000000FF0000007F0E00003F0E00003F0E00003F0E00003F0F00003
E0F00003E0F80007E0FC0007C0FF000F80FFE01F80E3FFFF00E1FFFC00C01FF0001C297CA825>
83 D<7FFFFFFFFF807FFFFFFFFF807FFFFFFFFF807F807F807F807C007F800F8078007F800780
78007F80078070007F800380F0007F8003C0F0007F8003C0E0007F8001C0E0007F8001C0E0007F
8001C0E0007F8001C0E0007F8001C000007F80000000007F80000000007F80000000007F800000
00007F80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F
80000000007F80000000007F80000000007F80000000007F80000000007F80000000007F800000
00007F80000000007F80000000007F80000000007F80000000007F80000000FFFFFFC00000FFFF
FFC00000FFFFFFC0002A287EA72F>I<FFFFF0007FFFFFFFF0007FFFFFFFF0007FFF03FE000001
C001FE0000038001FE0000038000FF0000070000FF0000070000FF80000F00007F80000E00007F
C0000E00003FC0001C00003FE0001C00001FE0003800001FE0003800001FF0007800000FF00070
00000FF800F0000007F800E0000007FC00E0000003FC01C0000003FC01C0000003FE03C0000001
FE0380000001FF0780000000FF0700000000FF87000000007F8E000000007F8E000000007FDE00
0000003FDC000000003FFC000000001FF8000000001FF8000000000FF0000000000FF000000000
0FF00000000007E00000000007E00000000003C00000000003C0000030297FA833>86
D<03FF80000FFFF0001F01FC003F80FE003F807F003F803F003F803F801F003F8000003F800000
3F8000003F8000003F80003FFF8001FC3F800FE03F801F803F803F003F807E003F80FC003F80FC
003F80FC003F80FC003F80FC005F807E00DFC03F839FFC1FFE0FFC03F803FC1E1B7E9A21>97
D<FFE00000FFE00000FFE000000FE000000FE000000FE000000FE000000FE000000FE000000FE0
00000FE000000FE000000FE000000FE000000FE000000FE1FE000FE7FF800FFE07E00FF803F00F
F001F80FE000FC0FE000FC0FE0007E0FE0007E0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F
0FE0007F0FE0007F0FE0007F0FE0007E0FE0007E0FE0007E0FE000FC0FE000FC0FF001F80FF803
F00F9C0FE00F0FFF800E01FC00202A7EA925>I<003FF00001FFFC0003F03E000FC07F001F807F
003F007F003F007F007F003E007E0000007E000000FE000000FE000000FE000000FE000000FE00
0000FE000000FE0000007E0000007E0000007F0000003F0003803F8003801F8007000FE00E0003
F83C0001FFF800003FC000191B7E9A1E>I<00007FF000007FF000007FF0000007F0000007F000
0007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0000007F0
003F87F001FFF7F007F03FF00FC00FF01F8007F03F0007F03F0007F07E0007F07E0007F07E0007
F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F07E0007F07E00
07F03F0007F03F0007F01F800FF00FC01FF007E07FFF01FFE7FF007F87FF202A7EA925>I<003F
C00001FFF00007E07C000FC03E001F801F003F001F803F000F807F000F807E000FC0FE000FC0FE
0007C0FE0007C0FFFFFFC0FFFFFFC0FE000000FE000000FE000000FE0000007E0000007F000000
3F0001C03F8001C01F8003C00FC0078003F01F0000FFFC00003FE0001A1B7E9A1F>I<0007F800
3FFC007E3E01FC7F03F87F03F07F07F07F07F03E07F00007F00007F00007F00007F00007F00007
F000FFFFC0FFFFC0FFFFC007F00007F00007F00007F00007F00007F00007F00007F00007F00007
F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F0007FFF807F
FF807FFF80182A7EA915>I<007F80F001FFE3F807C0FE1C0F807C7C1F003E7C1F003E103F003F
003F003F003F003F003F003F003F003F003F003F001F003E001F003E000F807C0007C0F80005FF
E0000C7F8000180000001C0000001C0000001E0000001FFFF8001FFFFF000FFFFFC007FFFFE003
FFFFF00FFFFFF03E0007F07C0001F8F80000F8F80000F8F80000F8F80000F87C0001F07C0001F0
3F0007E00FC01F8007FFFF00007FF0001E287E9A22>I<FFE00000FFE00000FFE000000FE00000
0FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE000
000FE000000FE07E000FE1FF800FE30FC00FE40FE00FE807E00FF807F00FF007F00FF007F00FE0
07F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00F
E007F00FE007F00FE007F00FE007F00FE007F00FE007F0FFFE3FFFFFFE3FFFFFFE3FFF202A7DA9
25>I<07001FC01FE03FE03FE03FE01FE01FC007000000000000000000000000000000FFE0FFE0
FFE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00F
E00FE00FE0FFFEFFFEFFFE0F2B7EAA12>I<000700001FC0003FE0003FE0003FE0003FE0003FE0
001FC000070000000000000000000000000000000000000000000001FFE001FFE001FFE0000FE0
000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0
000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0
000FE07C0FE0FE0FE0FE1FC0FE1FC0FE1F807C3F003FFC000FF000133784AA15>I<FFE0FFE0FF
E00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0
0FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE00FE0FFFEFFFEFF
FE0F2A7EA912>108 D<FFC07F001FC000FFC1FFC07FF000FFC307E0C1F8000FC407F101FC000F
C803F200FC000FD803FE00FE000FD003FC00FE000FD003FC00FE000FE003F800FE000FE003F800
FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE0
03F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE000FE003F800FE
000FE003F800FE000FE003F800FE000FE003F800FE00FFFE3FFF8FFFE0FFFE3FFF8FFFE0FFFE3F
FF8FFFE0331B7D9A3A>I<FFC07E00FFC1FF80FFC30FC00FC40FE00FC807E00FD807F00FD007F0
0FD007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007
F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F0FFFE3FFFFFFE3FFFFFFE
3FFF201B7D9A25>I<003FE00001FFFC0003F07E000FC01F801F800FC03F0007E03F0007E07E00
03F07E0003F07E0003F0FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE0003F8FE
0003F87E0003F07E0003F03F0007E03F0007E01F800FC00FC01F8007F07F0001FFFC00003FE000
1D1B7E9A22>I<FFE1FE00FFE7FF80FFFE0FE00FF803F00FF001F80FE001FC0FE000FC0FE000FE
0FE000FE0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE0007F0FE000
7E0FE000FE0FE000FE0FE000FC0FE001FC0FF001F80FF803F00FFC0FE00FEFFF800FE1FC000FE0
00000FE000000FE000000FE000000FE000000FE000000FE000000FE000000FE00000FFFE0000FF
FE0000FFFE000020277E9A25>I<FFC3E0FFC7F8FFCC7C0FD8FE0FD0FE0FD0FE0FF0FE0FE07C0F
E0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000FE0000F
E0000FE0000FE000FFFF00FFFF00FFFF00171B7E9A1B>114 D<03FE300FFFF03E03F07800F070
00F0F00070F00070F80070FE0000FFE0007FFF007FFFC03FFFE01FFFF007FFF800FFF80007FC00
00FCE0007CE0003CF0003CF00038F80038FC0070FF01E0E7FFC0C1FF00161B7E9A1B>I<007000
00700000700000700000F00000F00000F00001F00003F00003F00007F0001FFFE0FFFFE0FFFFE0
07F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F00007F000
07F07007F07007F07007F07007F07007F07007F07003F0E001F8C000FFC0003F0014267FA51A>
I<FFE07FF0FFE07FF0FFE07FF00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE0
07F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00FE007F00F
E007F00FE007F00FE00FF00FE00FF007E017F003F067FF01FFC7FF007F87FF201B7D9A25>I<FF
FC1FFEFFFC1FFEFFFC1FFE07F0078003F8070001FC0F0001FE1E0000FE3C00007F7800003FF800
003FF000001FE000000FE0000007F0000007F800000FF800001FFC00003DFE000038FF0000787F
0000F03F8001E03FC003C01FE003800FE0FFF03FFFFFF03FFFFFF03FFF201B7F9A23>120
D<FFFE07FFFFFE07FFFFFE07FF07F000E007F000E007F801E003F801C003F801C001FC038001FC
038001FE078000FE070000FF0F00007F0E00007F0E00003F9C00003F9C00003FFC00001FF80000
1FF800000FF000000FF0000007F0000007E0000007E0000003C0000003C0000003800000038000
00078000380700007C070000FE0E0000FE0E0000FE1C0000FE3800007C7000003FE000000F8000
0020277F9A23>I E /Fm 24 118 df<70F8FCFC7404040404080810102040060F7C840E>44
D<70F8F8F87005057C840E>46 D<008003800F80F3800380038003800380038003800380038003
8003800380038003800380038003800380038003800380038003800380038003800380038007C0
FFFE0F217CA018>49 D<03F8000C1E001007002007804007C07807C07803C07807C03807C00007
80000780000700000F00000E0000380003F000001C00000F000007800007800003C00003C00003
E02003E07003E0F803E0F803E0F003C04003C0400780200780100F000C1C0003F00013227EA018
>51 D<1000801E07001FFF001FFE001FF80013E000100000100000100000100000100000100000
10F800130E001407001803801003800001C00001C00001E00001E00001E00001E07001E0F001E0
F001E0E001C08001C04003C04003802007001006000C1C0003F00013227EA018>53
D<01F000060C000C0600180700380380700380700380F001C0F001C0F001C0F001E0F001E0F001
E0F001E0F001E07001E07003E03803E01805E00C05E00619E003E1E00001C00001C00001C00003
80000380300300780700780600700C002018001030000FC00013227EA018>57
D<000FE00000701C0000800200030001800400004008000020080000201007C010201830082030
08084060040440C0078441C0038481C00382838003828380038283800382838003828380038283
8003828380038281C0038241C0038240C007824060078420300B84201831881007C0F008000000
08000000040000000300000E00800078007007C0000FFC001F237DA226>64
D<FFFFF0000F801E0007800700078003C0078001C0078000E0078000F007800078078000780780
007C0780003C0780003C0780003C0780003E0780003E0780003E0780003E0780003E0780003E07
80003E0780003E0780003E0780003C0780003C0780007C0780007807800078078000F0078000E0
078001E0078003C0078007000F801E00FFFFF8001F227EA125>68 D<000FE00000783C0000E00E
0003C00780078003C00F0001E00E0000E01E0000F03C0000783C0000787C00007C7C00007C7800
003C7800003CF800003EF800003EF800003EF800003EF800003EF800003EF800003EF800003EF8
00003E7800003C7C00007C7C00007C3C0000783E0000F81E0000F00F0001E00F0001E0078003C0
03C0078000E00E0000783C00000FE0001F247DA226>79 D<0FE0001838003C0C003C0E00180700
00070000070000070000FF0007C7001E07003C0700780700700700F00708F00708F00708F00F08
7817083C23900FC1E015157E9418>97 D<0E0000FE00001E00000E00000E00000E00000E00000E
00000E00000E00000E00000E00000E00000E00000E1F000E61C00E80600F00300E00380E003C0E
001C0E001E0E001E0E001E0E001E0E001E0E001E0E001E0E001C0E003C0E00380F00700C80600C
41C0083F0017237FA21B>I<01FE000703000C07801C0780380300780000700000F00000F00000
F00000F00000F00000F00000F000007000007800403800401C00800C010007060001F80012157E
9416>I<01FC000707000C03801C01C03801C07801E07000E0F000E0FFFFE0F00000F00000F000
00F00000F000007000007800203800201C00400E008007030000FC0013157F9416>101
D<00007001F198071E180E0E181C07001C07003C07803C07803C07803C07801C07001C07000E0E
000F1C0019F0001000001000001800001800001FFE000FFFC00FFFE03800F0600030400018C000
18C00018C000186000306000303800E00E038003FE0015217F9518>103
D<0E0000FE00001E00000E00000E00000E00000E00000E00000E00000E00000E00000E00000E00
000E00000E1F800E60C00E80E00F00700F00700E00700E00700E00700E00700E00700E00700E00
700E00700E00700E00700E00700E00700E00700E00700E0070FFE7FF18237FA21B>I<1C001E00
3E001E001C00000000000000000000000000000000000E00FE001E000E000E000E000E000E000E
000E000E000E000E000E000E000E000E000E000E000E00FFC00A227FA10E>I<0E00FE001E000E
000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E000E00
0E000E000E000E000E000E000E000E000E000E000E00FFE00B237FA20E>108
D<0E1FC07F00FE60E183801E807201C00F003C00E00F003C00E00E003800E00E003800E00E0038
00E00E003800E00E003800E00E003800E00E003800E00E003800E00E003800E00E003800E00E00
3800E00E003800E00E003800E00E003800E00E003800E0FFE3FF8FFE27157F942A>I<0E1F80FE
60C01E80E00F00700F00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E
00700E00700E00700E00700E00700E0070FFE7FF18157F941B>I<01FC000707000C01801800C0
3800E0700070700070F00078F00078F00078F00078F00078F00078F000787000707800F03800E0
1C01C00E038007070001FC0015157F9418>I<0E1F00FE61C00E80600F00700E00380E003C0E00
1C0E001E0E001E0E001E0E001E0E001E0E001E0E001E0E003C0E003C0E00380F00700E80E00E41
C00E3F000E00000E00000E00000E00000E00000E00000E00000E00000E0000FFE000171F7F941B
>I<0E3CFE461E8F0F0F0F060F000E000E000E000E000E000E000E000E000E000E000E000E000E
000F00FFF010157F9413>114 D<0F8830786018C018C008C008E008F0007F803FE00FF001F800
3C801C800C800CC00CC008E018D0308FC00E157E9413>I<0E0070FE07F01E00F00E00700E0070
0E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00700E00F00E00F0
06017003827800FC7F18157F941B>117 D E /Fn 10 116 df<78FCFCFCFC7806067A8512>46
D<003F800000E0E0000380380007001C000F001E000E000E001E000F001C0007003C0007803C00
07803C000780780003C0780003C0780003C0780003C0F80003E0F80003E0F80003E0F80003E0F8
0003E0F80003E0F80003E0F80003E0F80003E0F80003E0F80003E0F80003E0F80003E0F80003E0
F80003E0F80003E0F80003E0F80003E0780003C0780003C0780003C07C0007C03C0007803C0007
803C0007801C0007001E000F000E000E000F001E0007001C000380380000E0E000003F80001B30
7DAE21>48 D<0C0003000F801E000FFFFC000FFFF8000FFFF0000FFFC000087E00000800000008
000000080000000800000008000000080000000800000008000000080000000800000008000000
081FC00008607000098018000A001C000C000E00080007000000078000000780000003C0000003
C0000003C0000003E0000003E0000003E0000003E0780003E0F80003E0F80003E0F80003E0F000
03C0C00007C0400007804000078020000F0030000F0018001E000E003C000780F00001FFE00000
7F00001B307DAE21>53 D<FFFE000007FFFFFE000007FF07F0000001F803E0000000E003E00000
00C003F0000000C001F00000008001F00000008000F80000010000F80000010000FC0000010000
7C00000200007C00000200007E00000600003E00000400003E00000400001F00000800001F0000
0800001F80000800000F80001000000F800010000007C00020000007C00020000007E000200000
03E00040000003E00040000003F000C0000001F00080000001F00080000000F80100000000F801
00000000FC01000000007C02000000007C02000000003E04000000003E04000000003F04000000
001F08000000001F08000000001F98000000000F90000000000F900000000007E00000000007E0
0000000007E00000000003C00000000003C0000000000180000000000180000000000180000030
327FB032>86 D<003F800000E0E0000380380007003C000E001E001E001E001C000F003C000F00
7C000F0078000F8078000780F8000780F8000780FFFFFF80F8000000F8000000F8000000F80000
00F8000000F8000000780000007C0000003C0000003C0000801E0000800E0001000F0002000780
020001C00C0000F03000001FC000191F7E9E1D>101 D<07000F801F801F800F80070000000000
00000000000000000000000000000000000001801F80FF80FF800F800780078007800780078007
80078007800780078007800780078007800780078007800780078007800780078007800FC0FFF8
FFF80D307EAF12>105 D<0180FE00003F83078000FF8C03C000FF9001E0000FA001E00007A000
F00007C000F00007C000F000078000F000078000F000078000F000078000F000078000F0000780
00F000078000F000078000F000078000F000078000F000078000F000078000F000078000F00007
8000F000078000F000078000F000078000F000078000F000078000F000078000F0000FC001F800
FFFC1FFF80FFFC1FFF80211F7E9E25>110 D<001FC00000F0780001C01C00070007000F000780
1E0003C01C0001C03C0001E03C0001E0780000F0780000F0780000F0F80000F8F80000F8F80000
F8F80000F8F80000F8F80000F8F80000F8F80000F8780000F07C0001F03C0001E03C0001E01E00
03C01E0003C00F00078007800F0001C01C0000F07800001FC0001D1F7E9E21>I<0183E03F8C18
FF907CFF907C0FA07C07C03807C00007C00007C000078000078000078000078000078000078000
078000078000078000078000078000078000078000078000078000078000078000078000078000
0FC000FFFE00FFFE00161F7E9E19>114 D<01FC100E03301800F0300070600030E00030E00010
E00010E00010F00010F800007E00003FF0001FFF000FFFC003FFE0003FF00001F80000F880003C
80003C80001CC0001CC0001CE0001CE00018F00038F00030EC0060C301C080FE00161F7E9E1A>
I E /Fo 15 118 df<07000F801FC01FC01FC01F400E4000400080008000800100010002000400
0400080010002000400080000A1570B116>39 D<000FFFFFFC00000FFFFFFF8000007E000FC000
007C0003E000007C0001F000007C0001F800007C0000F80000F80000F80000F80000F80000F800
00FC0000F80000F80001F00000F80001F00001F80001F00001F80001F00001F00003E00003F000
03E00003E00003E00007C00003E0000FC00007C0001F000007C0003E000007C000FC000007C003
F000000FFFFFC000000F8001F000000F80007C00000F80003E00001F00003E00001F00001F0000
1F00001F00001F00001F00003E00001F80003E00001F80003E00001F80003E00001F80007C0000
1F00007C00003F00007C00003F00007C00003E0000F800007E0000F80000FC0000F80000FC0000
F80001F80001F00003F00001F00007E00001F0001FC00003F0007F0000FFFFFFFC0000FFFFFFF0
00002E317BB031>66 D<000FFFFFFFF8000FFFFFFFF800007E0003F800007C0000F800007C0000
7800007C00007800007C0000300000F80000300000F80000300000F80000300000F80000300001
F00000300001F00000300001F00000300001F00000600003E00180600003E00180000003E00180
000003E00180000007C00300000007C00300000007C00700000007C01F0000000FFFFE0000000F
FFFE0000000F801E0000000F800E0000001F000C0000001F000C0000001F000C0000001F000C00
00003E00180000003E00180000003E00000000003E00000000007C00000000007C00000000007C
00000000007C0000000000F80000000000F80000000000F80000000000F80000000001F0000000
0001F00000000001F00000000003F000000000FFFFE0000000FFFFE00000002D317BB02E>70
D<000FFFFE000FFFFE00003F0000003E0000003E0000003E0000003E0000007C0000007C000000
7C0000007C000000F8000000F8000000F8000000F8000001F0000001F0000001F0000001F00000
03E0000003E0000003E0000003E0000007C0000007C0000007C0000007C000000F8000000F8000
000F8000000F8000001F0000001F0000001F0000001F0000003E0000003E0000003E0000003E00
00007C0000007C0000007C0000007C000000F8000000F8000000F8000001F800007FFFE000FFFF
E0001F317CB01B>73 D<000FFFFE00000FFFFE0000007F000000007C000000007C000000007C00
0000007C00000000F800000000F800000000F800000000F800000001F000000001F000000001F0
00000001F000000003E000000003E000000003E000000003E000000007C000000007C000000007
C000000007C00000000F800000000F800000000F800000000F800000001F000000001F00000000
1F000000001F000000003E000018003E000018003E000018003E000030007C000030007C000070
007C000060007C0000E000F80000C000F80001C000F80001C000F800038001F000078001F0000F
8001F0003F0003F001FF00FFFFFFFE00FFFFFFFE0025317BB02C>76 D<000FFFFFFC00000FFFFF
FF0000007E001FC000007C0007E000007C0001F000007C0001F000007C0000F80000F80000F800
00F80000F80000F80000F80000F80000F80001F00001F80001F00001F80001F00001F80001F000
01F80003E00003F00003E00003F00003E00007E00003E00007C00007C0000F800007C0001F0000
07C0003E000007C0007C00000F8003F000000FFFFF8000000F80000000000F80000000001F0000
0000001F00000000001F00000000001F00000000003E00000000003E00000000003E0000000000
3E00000000007C00000000007C00000000007C00000000007C0000000000F80000000000F80000
000000F80000000000F80000000001F00000000001F00000000001F00000000003F000000000FF
FFC0000000FFFF800000002D317BB030>80 D<07FFFFFFFFF007FFFFFFFFF00FE007E007F00F80
07C001F00E0007C000E00C0007C000E01C0007C000E018000F8000E018000F8000E030000F8000
C030000F8000C030001F0000C060001F0000C060001F0000C060001F0000C0C0003E0001800000
3E00000000003E00000000003E00000000007C00000000007C00000000007C00000000007C0000
000000F80000000000F80000000000F80000000000F80000000001F00000000001F00000000001
F00000000001F00000000003E00000000003E00000000003E00000000003E00000000007C00000
000007C00000000007C00000000007C0000000000F80000000000F80000000000F80000000000F
80000000001F00000000001F00000000001F00000000003F000000007FFFFF0000007FFFFF0000
002C3174B032>84 D<1FFFF003FFF01FFFF003FFF000FC00007F0000F800001C0000F800001800
00F80000180000F80000180001F00000300001F00000300001F00000300001F00000300003E000
00600003E00000600003E00000600003E00000600007C00000C00007C00000C00007C00000C000
07C00000C0000F80000180000F80000180000F80000180000F80000180001F00000300001F0000
0300001F00000300001F00000300003E00000600003E00000600003E00000600003E0000060000
7C00000C00007C00000C00007C00000C00007C00000C0000780000180000780000180000F80000
300000780000300000780000600000780000600000780000C000007800018000003C0003000000
3C00060000001E000C0000000F003800000007C0F000000003FFC0000000007E000000002C3272
B034>I<0000007C00000FFC00000FFC0000007C00000078000000780000007800000078000000
F0000000F0000000F0000000F0000001E0000001E0000001E0000001E0000003C0000003C00000
03C00007C3C0001867800070378000E0178001C01F8003801F0007800F000F000F000F000F001F
001E001E001E003E001E003E001E007C003C007C003C007C003C007C003C00F8007800F8007800
F8007800F8007810F800F030F000F030F000F0307001F0307003F0607802E0603804E0C0180870
C00C30318007C01E001E3278B124>100 D<0007E000383000F01801C00C03800C07800C0F000C
1E000C1E00183E00187C00307C00E07C0780FFFC00F80000F80000F80000F00000F00000F00000
F00000F00000F00008F0000CF000187000307000603800C01803800C0E0003F000161F779E20>
I<00007C000001863000070378000E0178001C01F8003801F0007800F000F000F000F000F001F0
01E001E001E003E001E003E001E007C003C007C003C007C003C007C003C00F8007800F8007800F
8007800F8007800F800F000F000F000F000F0007001F0007003E0007803E0003805E0001809E00
00C33C00007C3C0000003C0000003C00000078000000780000007800000078000000F0000000F0
003801E0007801C000F8038000F8070000701C00003FF000001D2D7C9E20>103
D<000700000F80000F80000F000006000000000000000000000000000000000000000000000000
0000000000000000000000000003E000063000083800183800303C00303C00603C006078006078
00C07800C0F00000F00001E00001E00001E00003C00003C00003C0000780000780000781000F03
000F03001E03001E06001E06001E04001E0C000E180006300003C00011307AAF16>105
D<07C03F800C60C0E0187180E0107B01F0307E01F0307C01E0607C01C06078000060780000C0F0
0000C0F0000000F0000000F0000001E0000001E0000001E0000001E0000003C0000003C0000003
C0000003C00000078000000780000007800000078000000F0000000F0000000F0000000F000000
1E0000000C0000001C1F7A9E1E>114 D<000FC000383000601800C00C01C00C01801C03803C03
803C03801807800007C00003E00003FE0003FF8001FFC0007FE0000FF00001F00000F800007800
0078700070F80070F80070F00060E000E0C000C0400180600300181C0007F000161F7A9E1D>I<
01E00038063800780C180078181C0078101C0078303C00F0203C00F0603C00F0607800F0C07801
E0C07801E000F001E000F001E000F003C001E003C001E003C001E003C003C0078003C0078003C0
078003C0078103800F0307800F0307800F0307800F0303801F0603801E0603C02E0C01C0470C00
E18318003E01E0201F7A9E26>117 D E end
%%EndProlog
%%BeginSetup
%%Feature: *Resolution 300
TeXDict begin
%%EndSetup
%%Page: 1 1
bop 565 482 a Fo(LIBFTP)25 b(User's)f(guide)740 574 y Fn(V)-6
b(ersion)22 b(5.0)796 695 y Fm(Oleg)16 b(Orel)723 869 y(orel@o)q(ea.ihep.su)
765 928 y(orel@cern.c)o(h)705 1026 y(Decem)o(b)q(er)e(13,1995)183
1212 y Fl(License)245 1305 y Fk(This)19 b(library)f(is)h(designed)h(for)f
(free,)h(non-commercial)d(soft)o(w)o(are)i(creation.)34 b(It)19
b(is)183 1355 y(c)o(hangeable)g(and)g(can)h(b)q(e)g(impro)o(v)o(ed.)32
b(The)20 b(author)f(w)o(ould)g(greatly)g(appreciate)h(an)o(y)183
1405 y(advises,)f(new)f(comp)q(onen)o(ts)g(and)g(patc)o(hes)h(of)e(the)i
(existing)f(programs.)29 b(Commercial)183 1454 y(usage)14 b(is)g(also)f(p)q
(ossible)h(with)g(participation)e(of)i(it's)f(author)1169 1439
y Fj(1)183 1597 y Fl(In)n(tro)r(duction)245 1689 y Fk(The)h(basic)f(orien)o
(tation)g(of)g(this)g(library)g(is)g(making)e(user's)j(programs)e(whic)o(h)h
(trans-)183 1739 y(p)q(ort)g(\014les)g(via)f(TCP/IP)g(net)o(w)o(ork.)18
b(It)13 b(con)o(tains)g(set)g(of)f(functions,)h(starting)g(from)d(prim-)183
1789 y(itiv)o(e,)i(suc)o(h)h(as)h(op)q(ening)e(FTP)i(connection)f(to)g(the)h
(serv)o(er,)g(and)f(\014nishing)f(b)o(y)h(high-lev)o(el)183
1839 y(functions,)i(suc)o(h)i(as)e(functions)h(whic)o(h)g(retriev)o(e)h
(\014les)f(via)e(net)o(w)o(ork,)i(making)d(and)j(clos-)183
1888 y(ing)h(c)o(hannels)h(to)g(the)h(serv)o(er.)31 b(All)18
b(functions)g(ha)o(v)o(e)f(protot)o(yp)q(es)i(in)f(common)d(header)183
1938 y(\014le)g(named)g Fi(FtpLibrary)l(.h)p 387 1953 268 2
v -3 w Fk(,)g(whic)o(h)g(m)o(ust)g(b)q(e)h(a)o(v)n(ailable)d(in)i(standard)h
(headers)h(direc-)183 1993 y(tory)271 1977 y Fj(2)289 1993
y Fk(.)h(Those)c(protot)o(yp)q(es)g(almost)d(fully)g(describ)q(e)k(orien)o
(tation)d(and)h(argumen)o(ts)g(of)f(all)183 2042 y(functions,)h(but)h(common)
d(ideology)i(and)h(library)f(comp)q(onen)o(ts)g(should)h(b)q(e)g(men)o
(tioned.)245 2093 y(This)g(library)f(is)h(a)f(clien)o(t)h(and)g(uses)h
(standard)f(FTPD)g(from)e(the)j(other)f(side.)245 2144 y(There)i(are)g
(problems)e(of)g(errors)i(pro)q(cessing)g(in)f(man)o(y)e(op)q(erating)i
(systems)g(includ-)183 2194 y(ing)e(input/output)h(errors.)19
b(The)c(m)o(utual)d(mec)o(hanism)f(of)j(v)n(alue)f(returning)i(of)e(all)g
(func-)183 2243 y(tions)h(is)g(used)i(in)e(this)h(library)m(.)k(\(EXIT)c
(macros,)e(de\014ned)j(in)e(\014le)g(FtpLibrary)m(.h\).)20
b(This)183 2293 y(mec)o(hanism)14 b(allo)o(ws,)h(after)h(the)h(de\014nition)f
(of)g(the)h(error)g(pro)q(cessing)h(functions,)e(write)p 183
2332 573 2 v 229 2358 a Fh(1)246 2370 y Fg(F)m(or)11 b(use)g(this)f(library)g
(for)g(commercial)e(purp)q(ose)h(need)h(to)h(buy)f(license,)g(for)h(do)f(it)h
(need)f(to)h(con)o(tact)183 2410 y(with)g(author)229 2437 y
Fh(2)246 2449 y Fg(for)g(example)e(\\/usr/include)o(")p eop
%%Page: 2 2
bop 1325 147 a Fk(V)m(ariables)13 b(and)g(de\014nitions)p 340
164 1433 2 v 340 307 a(programs,)h(considering)h(the)g(conditions)f(to)h(b)q
(e)g(ideal.)20 b(Data)14 b(transfer)i(functions)f(ha)o(v)o(e)340
357 y(p)q(ossibilit)o(y)g(to)h(preset)i(data)e(stream)g(exp)q(ectation)h
(timeout.)23 b(When)17 b(the)f(set)h(time)e(ex-)340 407 y(pires,)f
(previously)g(set)h(function)e(will)g(b)q(e)h(called.)340 545
y Fl(Last)23 b(ma)t(jo)o(r)d(c)n(hanges)403 636 y Fk(Last)14
b(time)g(to)g(library)g(w)o(as)g(added)h(sev)o(eral)h(extensions)f(for)f
(high)g(lev)o(el)h(op)q(erations:)340 686 y(suc)o(h)h(as)g(FtpStat)f
(\(Chapter)h(1.5,)e(page)h(6\))g(whic)o(h)h(extract)g(maxim)n(um)11
b(of)j(information)340 735 y(ab)q(out)h(sp)q(ecie-fed)i(\014le\(s\))e(and)g
(FtpHTTPGet\(Chapter)h(2.7,)e(page)h(13\))f(whic)o(h)h(receiv)o(e)340
785 y(\014les)g(using)e(as)h(gatew)o(a)o(y)g(HTTP-serv)o(er.)340
923 y Fl(1)67 b(V)-6 b(ariables)24 b(and)e(de\014nitions)340
1022 y Ff(1.1)56 b(Some)17 b(de\014nitions)h(in)g(libftp's)f(header)h(\014le)
g(\(FtpLibrary)-5 b(.h\))403 1149 y Fi(EXIT)p 403 1156 119
2 v 403 1199 a Fk(Main)11 b(macro)h(for)g(return)h(v)n(alue)f(from)e
(library's)i(functions)g(with)g(calling)f(handlers)i(if)340
1249 y(it's)h(need)403 1349 y Fi(MAX)p 523 1349 15 2 v 17 w(ANSWERS)p
403 1356 378 2 v 403 1399 a Fk(Num)o(b)q(er)f(of)g(p)q(ossible)h(go)q(o)q(d)g
(answ)o(ers)h(from)d(FTPD)i(for)f(one)i(request)403 1499 y
Fi(FTP)p 502 1499 15 2 v 17 w(NFDS)p 403 1506 244 2 v 403 1549
a Fk(Maxim)o(um)10 b(n)o(um)o(b)q(ers)j(of)h(one-time)e(op)q(ened)j(\014les)f
(in)g(system)403 1649 y Fi(FTPBUFSIZE)p 403 1656 302 2 v 403
1699 a Fk(Size)c(of)g(blo)q(c)o(k)f(for)h(transmit)f(data)h(via)f(net)o(w)o
(ork.)17 b(By)10 b(default)g(equiv)n(alence)g Fi(BUFSIZ)p 1598
1706 175 2 v 403 1799 a(LQUIT)p 403 1814 153 2 v 403 1849 a
Fk(Error)k(status)h(of)e(lo)q(cal)g(functions.)18 b(If)c(y)o(ou)f(giv)o(e)g
(this)h(status)h(from)d(libftp's)h(function)340 1899 y(y)o(ou)h(m)o(ust)f
(use)h(p)q(error)h(for)f(expand)g(diagnostic.)403 1999 y Fi(QUIT)p
403 2014 124 2 v 403 2049 a Fk(Error)g(status)h(of)e(net)o(w)o(ork)h(op)q
(eration.)k(Use)d(p)q(error.)403 2149 y Fi(Ctrl)p 403 2156
86 2 v -1 w(\(c)o(har\))403 2199 y Fk(Return)f(con)o(trol)g(c)o(haracter)h
(co)q(de)403 2299 y Fi(FtpStrin)o(g)p 403 2314 204 2 v 403
2349 a Fk(Sp)q(ecial)e(t)o(yp)q(e)i(for)e(strings,)h(en)o(tering)h(for)e
(readable)403 2449 y Fi(ST)l(A)l(TUS)p 403 2456 185 2 v 340
2574 a Fk(2)p eop
%%Page: 3 3
bop 183 147 a Fk(V)m(ariables)13 b(and)h(de\014nitions)p 183
164 1433 2 v 245 307 a(Sp)q(ecial)d(t)o(yp)q(e)h(for)g(returned)h(v)n(alue,)e
(if)f(function)i(return)g(v)n(alue)f(suc)o(h)h(t)o(yp)q(e,)g(it)g(is)f(mean)
183 357 y(that)i(y)o(ou)g(m)o(ust)g(c)o(hec)o(k)h(returned)h(v)n(alue)e(and)g
(compare)g(it)g(with)g(OK,)h(QUIT,)f(LQUIT)h(if)183 407 y(handlers)g(w)o
(asn't)g(preseted)245 512 y Fi(FREE)p 245 519 129 2 v(\(data\))245
562 y Fk(Fill)e(data)i(b)o(y)g(zero)245 667 y Fi(FtpError)p
245 682 190 2 v -2 w(\(libftp's)f(call\))245 718 y Fk(Sp)q(ecial)h(macro)e
(for)i(diagnostic)f(bad)h(conditions)245 823 y Fi(FtpAssert)p
245 837 209 2 v -2 w(\(libftp)o('s)f(call\))245 873 y Fk(Sp)q(ecial)h(macro)e
(for)i(automatically)d(return)k(from)d(this)i(function)f(if)g(status)i(is)f
(bad)245 978 y Fi(FtpStatus)p 245 993 208 2 v -3 w(\(FTP)i(*,libftp)o('s)d
(call\))245 1029 y Fk(This)g(macro)f(executes)k(sp)q(eci\014ed)f(function)e
(and)h(return)g(his)g(status,)g(without)f(in)o(ter-)183 1079
y(ruption)g(to)h(handlers)g(inside)g(if)f(last)h(one)g(w)o(as)g(set)183
1200 y Ff(1.2)55 b(Libftp's)18 b(\014le)g(sp)r(eci\014cation)245
1279 y Fk(All)10 b(\014les)i(whic)o(h)f(m)o(ust)f(b)q(e)i(in)o(terprets)g(as)
f(lo)q(cal)g(in)o(terprets)h(as)g(libftp's)e(\014les.)17 b(LIBFTP)183
1329 y(resp)q(onds)d(to)e(three)h(t)o(yp)q(es)h(of)d(\014les)i(suc)o(h)g(as)g
(lo)q(cal)e(\014le,)h(FTP's)h(\014les)g(and)f(program)f(pip)q(es.)183
1379 y(All)i(\014les)h(can)g(b)q(e)h(describ)q(ed)g(as)f(next)h(syn)o(tax:)
245 1483 y Fe(j)p Fi(string)245 1534 y Fk(in)o(terprets)d(string)e(as)g
(shell)g(command,)d(whic)o(h)j(m)o(ust)f(b)q(e)i(executed)h(with)e
(appropriate)183 1584 y(input/output)j(for)h(\014le.)k(It)c(dep)q(ends)h
(where)g(this)f(\014le)g(is)g(sp)q(eci\014ed.)245 1689 y Fi(*STDIN*,)i
(*STDOUT*,)f(*STDERR*)g(or)g(c)o(har)g('-')245 1739 y Fk(op)q(ened)g
(standard)f(streams)245 1844 y Fi(an)o(ything)f(else)245 1895
y Fk(lo)q(cal)g(\014le)183 2017 y Ff(1.3)55 b(The)19 b(FTP)g(data)g
(structure)183 2095 y Fi(1.3.1)48 b(The)15 b(mem)o(b)q(ers)f(of)i(FTP)f
(structure)183 2174 y Fk(FILE)f(*)p Fi(so)q(c)o(k)p 314 2181
90 2 v -15 x Fj(3)913 2174 y Fk(|)f(command)e(c)o(hannel)k(to)e(the)i(serv)o
(er;)183 2274 y(FILE)f(*)p Fi(data)p 314 2281 92 2 v 405 2259
a Fj(4)913 2274 y Fk(|)e(p)q(oin)o(ter)i(to)e(data)h(structure,)i(whic)o(h)d
(de-)913 2324 y(scrib)q(es)k(data)d(c)o(hannel)h(to)g(the)g(serv)o(er;)183
2387 y(in)o(t)f Fi(errno)p 246 2394 112 2 v 554 w Fk(|)j(last)g(returned)i(v)
n(alue.)25 b(When)16 b(v)n(alue)g(is)913 2437 y(lo)o(w)o(er)e(than)f(1,)h(an)
f(error)i(o)q(ccurred;)1594 2574 y(3)p eop
%%Page: 4 4
bop 1325 147 a Fk(V)m(ariables)13 b(and)g(de\014nitions)p 340
164 1433 2 v 340 307 a(c)o(har)i Fi(mo)q(de)p 432 314 114 2
v 525 w Fk(|)d(t)o(yp)q(e)g(of)g(transfer)h(\(v)n(alid)e(v)n(alues:)17
b('A')11 b('I')1071 357 y(....\);)340 540 y(in)o(t)j Fi(c)o(h)p
404 547 47 2 v 620 w Fk(|)21 b(help)g(v)n(ariable.)40 b(Is)22
b(used)g(to)g(con)o(v)o(ert)1071 590 y(ASCI)q(I)13 b(\014les,)h(user)g(of)f
(library)f(for)h(cleaning)1071 640 y(y)o(our)18 b(problems)f(m)o(ust)g
(forget)h(ab)q(out)g(this)1071 690 y(mem)o(b)q(er;)340 871
y(ST)m(A)m(TUS)c(\(*)p Fi(error)p 553 878 105 2 v -2 w Fk(\)\(\))366
b(|)19 b(p)q(oin)o(ter)h(to)g(an)g(error)g(handler.)37 b(It)20
b(is)1071 920 y(called)f(when)h(status)h(from)d(the)i(serv)o(er)i(is)1071
970 y(bad;)340 1011 y(ST)m(A)m(TUS)14 b(\(*)p Fi(debug)p 553
1026 126 2 v -2 w Fk(\)\(\))345 b(|)10 b(p)q(oin)o(ter)h(to)g(a)f(debug)h
(handler.)18 b(Is)11 b(called)1071 1061 y(from)32 b(functions)i(of)f
(sending/receiving)1071 1111 y(messages)14 b(to/from)e(serv)o(er;)340
1294 y(ST)m(A)m(TUS)i(\(*)p Fi(IO)p 553 1301 54 2 v Fk(\)\(\))416
b(|)13 b(p)q(oin)o(ter)i(to)f(Input/Output)h(error)g(han-)1071
1344 y(dler.)27 b(Is)17 b(called)f(when)h(c)o(hannel)g(to)g(serv)o(er)1071
1394 y(is)d(brok)o(en.)340 1567 y(ST)m(A)m(TUS)g(\(*)p Fi(hash)p
553 1574 96 2 v -1 w Fk(\)\(\))375 b(|)27 b(p)q(oin)o(ter)g(to)g(function,)j
(whic)o(h)e(m)o(ust)1071 1616 y(compute)18 b(summary)e(tra\016c.)34
b(This)18 b(func-)1071 1666 y(tion)d(can)i(tak)o(e)f(one)h(argumen)o(t)e
(whic)o(h)h(de-)1071 1716 y(scrib)q(e)e(ho)o(w)f(man)o(y)e(b)o(ytes)j(no)o(w)
f(receiv)o(ed)h(of)1071 1766 y(sended)e(to/from)d(serv)o(er.)19
b(If)11 b(the)h(argumen)o(t)1071 1816 y(is)25 b(equiv)n(alence)h(to)f(zero,)k
(then)d(coun)o(ter)1071 1866 y(m)o(ust)18 b(b)q(e)h(reset)i(to)d(zero.)34
b(But)20 b(of)e(course)1071 1915 y(user)i(can)g(use)g(this)f(handler)h(for)f
(another)1071 1965 y(prop)q(erties)i(of)f(herself)h(program,)f(for)f(ex-)1071
2015 y(ample)14 b(for)i(p)q(errio)q(dicaly)g(called)g(an)o(ything)1071
2065 y(else)i(for)f(c)o(hec)o(king)g(other)h(conditions,)f(b)q(e-)1071
2115 y(cause)i(the)f(transfer)h(pro)q(cedure)h(can)e(tak)o(e)1071
2164 y(large)13 b(time)g(from)f(user's)j(program.)340 2345
y(in)o(t)f Fi(seek)p 404 2352 88 2 v 579 w Fk(|)9 b(the)h(\014rst)g(b)o(yte)g
(in)f(\014le)g(for)g(transfer.)18 b(This)1071 2395 y(option)12
b(can)h(use)h(for)f(re-transfer)i(\014le)e(again)1071 2445
y(after)h(connection)g(is)g(brok)o(en)340 2574 y(4)p eop
%%Page: 5 5
bop 183 147 a Fk(V)m(ariables)13 b(and)h(de\014nitions)p 183
164 1433 2 v 183 307 a(in)o(t)f Fi(\015ags)p 246 322 93 2 v
574 w Fk(|)21 b(the)i(option)e(list)g(for)g(transfer)i(pro)q(ce-)913
357 y(dures)15 b(suc)o(h)g(as:)784 490 y(FTP)p 871 490 13 2
v 15 w(REST)21 b(T)m(urn)32 b(on)g(re-transfer)i(\014le)e(using)1017
540 y(metho)q(d)11 b(of)h(compare)f(size)i(of)f(\014les)g(in)1017
589 y(b)q(oth)i(sides.)728 672 y(FTP)p 815 672 V 15 w(NOEXIT)22
b(Don't)h(exit)h(from)e(standard)i(error)1017 722 y(and)14
b(IO)g(handlers)663 805 y(FTP)p 750 805 V 15 w(HANDLERS)21
b(Enable)13 b(to)h(call)e(handlers)i(for)f(errors)1017 855
y(and)d(debug)i(ev)o(en)o(ts.)18 b(Set)11 b(b)o(y)g(default.)183
994 y(struct)k(timev)n(al)c Fi(timeout)p 449 1001 163 2 v 299
w Fk(|)30 b(Timeout)e(for)i(send/receiv)o(e)i(pro)q(ce-)913
1043 y(dures)183 1095 y(in)o(t)13 b Fi(p)q(ort)p 246 1109 90
2 v 576 w Fk(|)k(P)o(ort)g(for)g(making)e(command)g(connec-)913
1145 y(tion)183 1196 y(FtpString)f Fi(title)p 374 1203 86 2
v 451 w Fk(|)f(Connection)h(iden)o(ti\014cation)183 1297 y(unsigned)g(long)f
Fi(coun)o(ter)p 446 1304 157 2 v 308 w Fk(|)g(coun)o(ter)h(of)f(already)g
(transferred)i(b)o(ytes)183 1463 y Fi(1.3.2)48 b(Initiali)o(zati)o(on)12
b(of)k(FTP)g(structure)245 1542 y Fk(This)g(library)f(ha)o(v)o(e)h(t)o(w)o(o)
f(sp)q(ecial)i(ob)r(jects:)23 b(pro)q(cedure)18 b(FtpCreateOb)r(ject)h(and)d
(ex-)183 1592 y(ternal)j(static)h(structure)i(FtpInit.)34 b(The)20
b(pro)q(cedure)h(FtpCreateOb)r(ject)h(called)d(from)183 1642
y(FtpConnect.)24 b(The)16 b(structure)h(FtpInit)f(can)g(b)q(e)g(mo)q
(di\014ed)e(b)o(y)h(hand)h(or)f(b)o(y)h(using)f(sp)q(e-)183
1692 y(cial)10 b(macros)g(suc)o(h)i(as)g Fi(FtpSetFlag)p 534
1706 233 2 v -3 w Fk(,)f Fi(FtpClearFlag)p 789 1706 278 2 v
-2 w Fk(,)h Fi(FtpT)l(estFlag)p 1091 1706 254 2 v -2 w Fk(,)f
Fi(FtpSetP)o(ort)p 1368 1706 236 2 v -4 w Fk(,)183 1741 y Fi(FtpSetTimeou)o
(t)p 183 1756 320 2 v -3 w Fk(,)e Fi(FtpSetErrorHandler)p 523
1756 425 2 v -4 w Fk(,)h Fi(FtpSetDebug)o(Handl)o(er)p 970
1756 446 2 v -3 w Fk(,)f Fi(FtpSetIOHandler)p 1437 1756 365
2 v -3 w Fk(,)183 1791 y Fi(FtpSetHashHandle)o(r)p 183 1806
417 2 v -3 w Fk(,)p Fi(FtplibD)o(ebu)o(g)p 611 1806 264 2 v
-3 w Fk(.)183 1915 y Ff(1.4)55 b(The)19 b(AR)n(CHIE)p 425 1922
225 2 v 19 w(data)g(structure)245 1995 y Fk(The)10 b Fi(AR)o(CHIE)p
326 2002 192 2 v 11 w Fk(data)f(structure)j(using)e(only)f(with)h(function)f
(FtpArc)o(hie)i(for)f(extract)183 2045 y(result)k(of)g(w)o(orks)g(one.)k
(This)c(structure)i(ha)o(v)o(e)d(four)h(mem)o(b)q(ers)f(suc)o(h)h(as:)183
2096 y(struct)h(tm)d Fi(createtime)p 367 2103 220 2 v 324 w
Fk(Time)g(of)i(\014le)g(creation.)183 2197 y(unsigned)g(long)f
Fi(size)p 446 2204 76 2 v 391 w Fk(size)i(of)e(\014le.)183
2298 y(FtpString)h Fi(host)p 374 2305 88 2 v 450 w Fk(Host)g(whic)o(h)g
(\014le)g(is)g(lo)q(cated)183 2399 y(FtpString)g Fi(\014le)p
374 2406 62 2 v 476 w Fk(F)m(ull)f(path)g(in)h(p)q(oin)o(ted)g(host)g(of)f
(this)h(\014le)1594 2574 y(5)p eop
%%Page: 6 6
bop 1449 147 a Fk(Library's)14 b(routines)p 340 164 1433 2
v 340 307 a Ff(1.5)56 b(The)18 b(FTP)p 697 307 17 2 v 21 w(ST)-5
b(A)g(T)p 582 314 275 2 v 20 w(data)19 b(structure)403 388
y Fk(The)9 b Fi(FTP)p 582 388 15 2 v 17 w(ST)l(A)l(T)p 483
395 235 2 v 10 w Fk(data)g(structure)i(using)e(with)g(function)g
Fi(FtpStat)p 1342 403 162 2 v 7 w Fk(and)g Fi(FtpStatF)l(ree)p
1589 403 252 2 v 340 438 a Fk(for)j(get)h(\014le's)f(prop)q(erties)i(in)e
(remote)g(serv)o(er.)19 b(Using)13 b(this)f(functions)h(and)f(this)g
(structure)340 487 y(y)o(ou)i(can)g(get)g(size)h(of)e(\014les,)h(protection,)
g(o)o(wners)g(and)g(t)o(yp)q(es)h(for)e(\014le.)340 539 y(FtpString)h
Fi(name)p 531 546 112 2 v 428 w Fk(Name)c(of)i(\014le)f(whic)o(h)h(describ)q
(ed)i(in)d(curren)o(t)1071 589 y(structure)340 641 y(c)o(har)k
Fi(t)o(yp)q(e)p 432 656 93 2 v 546 w Fk(T)o(yp)q(e)i(of)f(\014le:)24
b('-')16 b(-)h(regular)f(\014le,)i('d')d(-)i(di-)1071 691 y(rectory)m(,)d
('l')e(-)i(sym)o(b)q(olic)e(link)340 755 y(in)o(t)i Fi(mo)q(de)p
404 762 114 2 v 553 w Fk(Protection)g(of)g(\014le.)340 857
y(in)o(t)g Fi(ino)q(des)p 404 864 133 2 v 533 w Fk(Num)o(b)q(er)f(of)g
(references)k(to)d(this)g(\014le)340 959 y(FtpString)g Fi(user)p
531 966 87 2 v 452 w Fk(Owner's)h(name)d(of)i(this)f(\014le)340
1061 y(FtpString)h Fi(group)p 531 1075 121 2 v 418 w Fk(Group's)f(name)g(of)g
(this)h(\014le)340 1162 y(unsigned)h(long)e Fi(size)p 604 1169
76 2 v 391 w Fk(Size)h(of)f(\014le)h(in)g(b)o(ytes)340 1264
y(in)o(t)g Fi(mon)o(th)p 404 1271 134 2 v 531 w Fk(Mon)o(th)g(of)f(creation)h
(\014le)340 1366 y(in)o(t)g Fi(da)o(y)p 404 1381 74 2 v 593
w Fk(Da)o(y)f(of)g(creation)h(\014le)340 1468 y(FtpString)g
Fi(time)p 531 1475 94 2 v 445 w Fk(Time)e(of)h(creation)i(\014le)f(in)f
(string)h(format)340 1569 y(FtpString)g Fi(link)p 531 1576
79 2 v 460 w Fk(If)h(\014le)g(is)g(sym)o(b)q(olic)e(link,)h(here)i(is)f(name)
f(of)1071 1619 y(p)q(oin)o(ted)g(\014le)340 1683 y(FTP)p 427
1683 13 2 v 16 w(ST)m(A)m(T)f(*)p Fi(next)p 583 1690 93 2 v
395 w Fk(P)o(oin)o(ter)j(to)f(next)h(same)f(structure,)j(other-)1071
1733 y(wise)c(NULL)340 1882 y Fl(2)67 b(Library's)24 b(routines)340
1985 y Ff(2.1)56 b(Connection/Disconnection)17 b(with)i(serv)n(er)403
2124 y Fi(ST)l(A)l(TUS)c(FtpConnect)p 603 2139 249 2 v -2 w(\(FTP)g(**,)h(c)o
(har)g(*hostname)1402 2109 y Fj(5)1437 2124 y Fi(\))403 2176
y Fk(Mak)o(es)c(c)o(hannel)f(to)h(the)g(serv)o(er,)h(at)f(the)g(\\hostname")e
(mac)o(hine.)16 b(Creates)d(FTP)f(data)340 2226 y(structure)g(and)e(returns)h
(p)q(oin)o(ter)f(to)g(it.)16 b(If)9 b(the)i(pro)q(cedure)g
Fi(FtplibDebu)o(g)p 1265 2241 264 2 v -3 w Fk(\(1\))f(w)o(as)f(previ-)340
2276 y(ously)g(called,)h Fi(FtpConnect)p 569 2290 249 2 v 8
w Fk(calls)f(automatically)d Fi(FtpDebug)p 1172 2290 211 2
v 7 w Fk(for)j(the)h Fi(debug)k(mo)q(de)p 1518 2290 255 2 v
340 2326 a Fk(to)g(b)q(e)h(turned)g(on.)i(\(Chapter)e(2.2,)d(page)i(7\).)p
340 2371 573 2 v 387 2398 a Fh(5)404 2410 y Fg(The)g(name)e(of)i(the)f(host)g
(ma)o(y)g(b)q(e)g(sym)o(b)q(olic)f(\(for)h(example)e Fd(dxcern.cern.c)o(h)p
1248 2417 259 2 v -1 w Fg(\))i(or)h(n)o(umeric)e(\(for)340
2449 y(example)e Fd(128.141.201.)q(96)p 479 2456 258 2 v 3
w Fg(\))340 2574 y Fk(6)p eop
%%Page: 7 7
bop 183 147 a Fk(Library's)13 b(routines)p 183 164 1433 2 v
245 307 a Fi(ST)l(A)l(TUS)i(FtpUser)p 445 322 173 2 v -2 w(\(FTP)h(*,)g(c)o
(har)f(*user\))245 357 y Fk(Sends)k(the)g(name)e(of)h(the)h(user)g(to)g(the)g
(serv)o(er.)32 b(The)19 b(connection)g(m)o(ust)e(b)q(e)i(done)183
407 y(b)q(efore)14 b(it.)245 507 y Fi(ST)l(A)l(TUS)h(FtpP)o(assw)o(ord)p
445 521 271 2 v -2 w(\(FTP)g(*,)h(c)o(har)f(*passw)o(ord\))245
556 y Fk(Sends)d Fi(passw)o(ord)p 360 571 191 2 v 9 w Fk(to)e(the)i(serv)o
(er.)18 b(The)11 b(function)g Fi(FtpUser)p 1054 571 173 2 v
9 w Fk(m)o(ust)e(b)q(e)j(called)e(b)q(efore)183 606 y(it.)245
706 y Fi(ST)l(A)l(TUS)15 b(FtpAccoun)o(t)p 445 721 248 2 v
-2 w(\(FTP)g(*,)h(c)o(har)g(*accoun)o(t\))245 756 y Fk(Sends)f(a)f(name)f(of)
h(the)h(accoun)o(t)f(to)g(the)h(serv)o(er.)21 b(The)14 b(name)g(of)f(the)i
(accoun)o(t)g(is)f(not)183 806 y(standard)f(attribute)h(for)f(man)o(y)e
(systems,)i(so)h(this)f(function)g(is)g(used)h(v)o(ery)g(seldom.)i(The)183
855 y(function)d Fi(FtpP)o(assw)o(ord)p 345 870 271 2 v 12
w Fk(m)o(ust)f(b)q(e)j(called)f(b)q(efore)g(it.)245 955 y Fi(ST)l(A)l(TUS)c
(FtpLogin)p 440 970 192 2 v -3 w(\(FTP)g(**,)i(c)o(har)e(*hostname,)g(c)o
(har)g(*user,)g(c)o(har)g(*pass-)183 1005 y(w)o(ord,)15 b(c)o(har)g(*accoun)o
(t\))245 1055 y Fk(Executes)h(functions)e Fi(FtpConnect)p 599
1069 249 2 v -2 w Fk(,)g Fi(FtpUser)p 873 1069 173 2 v -2 w
Fk(,)g Fi(FtpP)o(assw)o(ord)p 1071 1069 271 2 v -3 w Fk(,)g
Fi(FtpAccoun)o(t)p 1367 1069 248 2 v 183 1105 a Fk(\(if)d(necessary\))k
(consisten)o(tly)m(.)i(If)12 b(the)h(name)e(of)g(the)i(accoun)o(t)g(is)f
(absen)o(t,)h(replaces)g(it)f(with)183 1154 y(the)i Fi(NULL)p
254 1161 132 2 v 13 w Fk(v)n(alue.)245 1254 y Fi(ST)l(A)l(TUS)h(FtpBy)o(e)p
445 1269 155 2 v -1 w(\(FTP)g(*\))245 1308 y Fk(Finishes)f(w)o(ork)g(with)f
(the)i(serv)o(er)g(and)f(closes)h(all)d(c)o(hannels.)1232 1293
y Fj(6)245 1408 y Fi(ST)l(A)l(TUS)j(FtpQuic)o(kBy)o(e)p 445
1423 276 2 v -2 w(\(FTP)g(*\))245 1458 y Fk(F)m(ast)10 b(close)h(data)f(and)g
(command)e(connection)j(to)f(serv)o(er)i(without)e(dela)o(ys)g(for)g(w)o
(aiting)183 1508 y(serv)o(er's)15 b(con\014rmation)d(and)i(destro)o(ying)g
(the)g(FTP)h(ob)r(ject.)245 1608 y Fi(ST)l(A)l(TUS)g(FtpAb)q(ort)p
445 1622 202 2 v -2 w(\(FTP)h(*\))245 1657 y Fk(Ab)q(ort)e(last)g(command)d
(passed)k(to)f(serv)o(er)183 1774 y Ff(2.2)55 b(The)19 b(debugging)245
1850 y Fk(There)c(is)f(a)f(p)q(ossibilit)o(y)g(to)h(prede\014ne)h(few)f
(functions,)g(suc)o(h)g(as:)1289 1835 y Fj(7)245 1950 y Fi(FtpSetDebug)o
(Handl)o(er)p 245 1965 446 2 v -3 w(\(FTP)h(*,function\))245
2000 y Fk(Prede\014nes)24 b(function)d(of)h(proto)q(col)f(debugging.)41
b(After)22 b(the)h(function)e(is)h(prede-)183 2050 y(\014ned,)16
b(it)g(is)g(called)g(with)g(ev)o(ery)g(sending/receiving)h(messages)f(from)e
(the)j(serv)o(er.)26 b(The)183 2100 y(function,)16 b(de\014ned)i(as)f(a)f
(debug)h(handler)g(m)o(ust)f(do)g(returns)j(to)d(the)h(calling)f(functions)
183 2149 y(\()p Fi(FtpSendMessage)p 199 2164 351 2 v -3 w Fk(/)p
Fi(FtpGetMessage)p 570 2164 327 2 v -2 w Fk(\),)d(but)h(can)h(also)e(ab)q
(ort)h(the)g(program.)245 2249 y Fi(FtpSetErrorHandl)o(er)p
245 2264 425 2 v -3 w(\(FTP)h(*,function\))p 183 2292 573 2
v 229 2319 a Fh(6)246 2331 y Fg(Y)m(ou)g(can)f(see)g(from)g(the)g
(description)e(of)i(connect/disc)o(on)o(nec)o(t)e(functions,)h(that)h(y)o(ou)
g(can)g(create)183 2370 y(more)c(than)g(one)h(connection)d(to)j(serv)o(ers)g
(sim)o(ultaneo)o(usly)l(.)229 2398 y Fh(7)246 2410 y Fg(If)g(the)f
Fd(NULL)p 341 2417 112 2 v 12 w Fg(v)n(alue)f(is)i(transferred)d(as)j(a)f
(parameter)e Fd(\\function")p 1007 2417 189 2 v 11 w Fg(to)j(the)f
(functions,)e(describ)q(ed)183 2449 y(b)q(elo)o(w,)i(the)h(handling)e(will)j
(b)q(e)f(turned)f(o\013.)1594 2574 y Fk(7)p eop
%%Page: 8 8
bop 1449 147 a Fk(Library's)14 b(routines)p 340 164 1433 2
v 403 307 a(Prede\014nes)h(error)f(handler.)k(If)12 b(the)i(serv)o(er's)g
(answ)o(er)g(means,)d(that)i(the)h(op)q(eration)f(is)340 357
y(not)i(\014nished)h(correctly)m(,)f(this)g(function)f(will)g(b)q(e)h
(called.)21 b(The)15 b(result)h(co)q(de)f(is)g(negativ)o(e,)340
407 y(if)e(an)h(error)h(is)f(o)q(ccurs.)403 508 y Fi(FtpSetIOHandle)o(r)p
403 522 365 2 v -3 w(\(FTP)h(*,function\))403 558 y Fk(Prede\014nes)d
(handler)d(of)h(Input/Output)g(pro)q(cessing.)18 b(This)9 b(function)h(is)f
(called,)h(when)340 607 y(a)18 b(connection)g(to)g(the)g(serv)o(er)h(is)f
(brok)o(en.)30 b(F)m(or)17 b(example,)g(when)h(the)g(net)o(w)o(ork)g(or)g
(the)340 657 y(remote)i(host)g(is)g(do)o(wn.)37 b(This)20 b(handler)g(also)f
(is)h(called)g(after)h(the)f Fi(timeout)p 1474 664 163 2 v
18 w Fk(of)f(one)340 707 y(c)o(haracter)d(w)o(aiting)c(expires.)403
808 y Fi(FtpDebug)p 403 822 211 2 v -3 w(\(FTP)k(*\))403 858
y Fk(T)m(urns)e(on)f(all)g(standard)h(debugging)g(functions.)340
908 y Fi(FtpDebugError)p 340 922 325 2 v 403 w Fk(|)28 b(prin)o(ts)h(a)g
(string,)k(tak)o(en)c(from)e(the)1071 958 y(serv)o(er,)15 b(and)e(ab)q(orts)i
(the)f(program;)340 999 y Fi(FtpDebugDebu)o(g)p 340 1013 346
2 v 382 w Fk(|)28 b(prin)o(ts)h(a)g(string,)k(tak)o(en)c(from)e(the)1071
1048 y(serv)o(er;)340 1092 y Fi(FtpDebugIO)p 340 1106 265 2
v 464 w Fk(|)18 b(prin)o(ts)g(string)h Fi(strerror\(err)o(no\))p
1377 1109 311 2 v 15 w Fk(and)1071 1142 y(ab)q(orts)14 b(the)h(program.)403
1204 y(All)e(function)g(for)h(debugging)f(ha)o(v)o(e)h(three)h(argumen)o(ts:)
340 1254 y(1.)j(P)o(oin)o(ter)c(to)g(FTP)g(data)g(structure;)340
1303 y(2.)29 b(Last)17 b(returned)i(v)n(alue)e(from)f(the)i(serv)o(er.)30
b(When)17 b(errors)i(o)q(ccur,)g(the)f(v)n(alue)f(is)g(less)340
1353 y(than)d(1;)340 1403 y(3.)k(Diagnostic)13 b(string.\(c)o(har)h(*\))403
1504 y Fi(FtplibD)o(ebu)o(g)p 403 1518 264 2 v -3 w(\(y)o(es|no\))403
1554 y Fk(T)m(urns)g(on/o\013)f(autostart)h(debug)h(mo)q(de,)d(when)i
(connection)h(is)f(established.)403 1654 y Fi(FtpSetHashHandle)o(r)p
403 1669 417 2 v -3 w(\(FTP)h(*,function\))403 1705 y Fk(Prede\014nes)d
(handler)e(of)f(function)h(whic)o(h)f(m)o(ust)g(compute)h(tra\016c)g(size.)17
b(This)10 b(function)340 1754 y(ha)o(v)o(e)19 b(only)f(one)g(argumen)o(t)g
(whic)o(h)g(describ)q(e)i(n)o(um)o(b)q(er)e(of)g(transferred)i(b)o(ytes.)33
b(If)18 b(this)340 1804 y(argumen)o(t)13 b(is)h(zero)h(coun)o(ter)g(m)o(ust)d
(b)q(e)j(reset)g(to)f(zero.)403 1905 y Fi(FtpLog)p 403 1920
152 2 v -2 w(\(c)o(har)h(*name)p 817 1905 15 2 v 16 w(of)p
872 1905 V 17 w(log,)g(c)o(har)g(*message\))403 1955 y Fk(Prin)o(t)d(message)
g(to)h(user's)g(screen)i(in)d(libftp's)f(standard)i(format,)e(name)p
1558 1955 13 2 v 14 w(of)p 1606 1955 V 14 w(log)h(m)o(ust)340
2005 y(b)q(e)i(y)o(our)f(program)e(name)h(\(if)g(this)h(function)g(called)g
(from)e(standard)i(handlers)h(then)f(this)340 2054 y(string)20
b(is)f(title)g(from)f(FTP)h(structure\))j(and)d(message)g(with)g(diagnostic)g
(string)g(from)340 2104 y(an)o(ywhere.)340 2222 y Ff(2.3)56
b(Data)19 b(transfer)f(pro)r(cedures)403 2349 y Fi(ST)l(A)l(TUS)d(FtpRetr)p
603 2364 172 2 v -2 w(\(FTP)g(*,)h(c)o(har)g(*command,)e(c)o(har)i(*inp,)e(c)
o(har)h(*out\))403 2399 y Fk(This)j(is)g(basically)f(and)h(single)f(pro)q
(cedure)j(in)e(the)h(library)e(for)h(transfer)h(\014le)f(from)340
2449 y(the)d(serv)o(er.)20 b(One)15 b(c)o(hec)o(k)g(man)o(y)d(option)i(with)f
(customizing)g(its)h(st)o(yle)g(of)g(w)o(orking.)k(This)340
2574 y(8)p eop
%%Page: 9 9
bop 183 147 a Fk(Library's)13 b(routines)p 183 164 1433 2 v
183 307 a(options)k(basically)f(is)i(mem)o(b)q(ers)e(of)h(FTP)h(structure)i
(suc)o(h)f(as)e(timeout,)g(all)g(handlers,)183 357 y(mo)q(de,)12
b(seek.)20 b(If)14 b(in)g(con)o(tin)o(ue)g(of)g(w)o(orking)f(this)h(function)
g(happ)q(en)h(timeout)d(or)j(net)o(w)o(ork)183 407 y(brok)o(ed)i(then)h(this)
f(function)g(automatically)d(called)j(I/O)g(or)g(error)h(handler,)g(if)e(one)
i(is)183 457 y(preseted.)23 b(If)15 b(handler)g(is)f(not)h(set)h(then)g
(FtpRetr)f(return)i(status)e(QUIT)h(or)e(LQUIT)i(as)183 506
y(signal)c(of)i(t)o(yp)q(e)g(of)f(error)i(\(LQUIT)g(is)e(sp)q(ecify)i(error)g
(happ)q(en)f(with)g(lo)q(cal)f(\014lesystem\).)245 660 y Fi(FtpGet)p
245 675 154 2 v -2 w(\(FTP)i(*,)h(c)o(har)g(*in,)e(c)o(har)i(*out\))245
710 y Fk(Calls)d Fi(FtpRetr)p 349 725 172 2 v 12 w Fk(with)g(adaptation)g
(argumen)o(ts)g(to)h(transfer)h(\014le)245 818 y Fi(FtpDirectory)p
245 833 276 2 v -3 w(\(FTP)g(*,)h(c)o(har)g(*pat)902 803 y
Fj(8)919 818 y Fi(,)g(c)o(har)g(*out\))245 869 y Fk(T)m(ransfers)11
b(\014les)g(listing)f(from)f(the)i(serv)o(er,)i(describ)q(ed)f(b)o(y)e
Fi(pat)p 1151 884 69 2 v Fk(,)h(to)f(the)h(lo)q(cal)f(\014le)h
Fi(out)p 1517 876 V -1 w Fk(.)245 973 y Fi(FtpDir)p 245 987
145 2 v -2 w(\(FTP)k(*,)h(c)o(har)f(*out\))245 1023 y Fk(T)m(ransfers)e
(\014les)f(listing)f(of)h(the)h(curren)o(t)h(directory)f(from)d(the)j(serv)o
(er)h(to)e(the)g(lo)q(cal)g(\014le)183 1073 y Fi(out)p 183
1080 69 2 v -1 w Fk(.)245 1177 y Fi(FtpStor)p 245 1191 164
2 v -2 w(\(FTP)j(*,)h(c)o(har)f(*command,)g(c)o(har)g(*inp,)g(c)o(har*)g
(out\))245 1227 y Fk(Store)f(\014le)g(to)g(the)h(serv)o(er.)k(W)m(orks)13
b(lik)o(e)g(FtpRetr.)245 1331 y Fi(FtpPut)p 245 1346 153 2
v -2 w(\(FTP)i(*,)h(c)o(har)f(*in,)g(c)o(har)g(*out\))245 1381
y Fk(Calls)e Fi(FtpStor)p 349 1396 164 2 v 11 w Fk(adaptation)g(argumen)o(ts)
g(to)h(transfer)h(\014le)245 1485 y Fi(FtpCop)o(y)p 245 1500
184 2 v -1 w(\(FTP)g(*ftp)p 647 1485 15 2 v 16 w(from,)g(FTP)h(*ftp)p
987 1485 V 15 w(to,)g(c)o(har)f(*in,)g(c)o(har)g(*out\))245
1536 y Fk(T)m(ransfer)f(\014le)g(b)q(et)o(w)o(een)h(t)o(w)o(o)f(serv)o(er)h
(without)f(connection)g(to)g(clien)o(t's)g(host)245 1639 y
Fi(FtpLink)p 245 1654 169 2 v -2 w(\(FTP)h(*ftp1,)g(FTP)g(*ftp2\))245
1690 y Fk(Mak)o(e)f(data)f(c)o(hanel)h(b)q(et)o(w)o(een)i(b)q(oth)e(serv)o
(ers.)245 1793 y Fi(FtpP)o(assiv)o(eT)l(ransf)o(er)p 245 1808
400 2 v -3 w(\(FTP)c(*ftp)p 858 1793 15 2 v 16 w(from,)g(FTP)h(*ftp)p
1188 1793 V 16 w(to,)g(c)o(har)f(*in,)g(c)o(har)g(*out\))245
1844 y Fk(T)m(ransfer)k(\014le)g(b)q(et)o(w)o(een)h(t)o(w)o(o)f(serv)o(er)h
(via)e(clien)o(t's)h(cac)o(he.)183 1964 y Ff(2.4)55 b(Serv)n(er's)18
b(\014les)g(read/write)g(pro)r(cedures)245 2042 y Fk(This)d(library)f(con)o
(tains)g(sp)q(ecial)h(functions)g(for)f(remote)h(\014les)g(reading)f(and)h
(writing,)183 2092 y(without)d(cop)o(y)h(in)f(adv)n(ance)h(them)e(to)i(lo)q
(cal)f(\014les.)18 b(The)13 b(functions,)f(whic)o(h)h(are)g(describ)q(ed)183
2142 y(b)q(elo)o(w,)19 b(do)f(it.)33 b(After)19 b(the)g(data)g(c)o(hannel)g
(to)f(a)h(remote)f(\014le)h(is)f(created,)j(it)d(b)q(ecomes)183
2192 y(p)q(ossible)f(to)h(read)g(and)f(write)h(c)o(haracters)h(using)e
(standard)h(Input/Output)h(functions)183 2242 y(or)f(using)h(sp)q(ecial)f
(functions)h Fi(FtpRead)p 675 2256 183 2 v -1 w Fk(/)p Fi(FtpW)l(rite)p
879 2256 194 2 v 16 w Fk(and/or)f Fi(FtpGetc)p 1234 2256 175
2 v -2 w Fk(/)p Fi(FtpPutc)p 1429 2256 V -2 w Fk(,)183 2291
y(whic)o(h)12 b(reorganize)g(stream)g(for)g(standard)g(text)h(\014le,)f
(under)h(condition)e(that)h(the)h Fi(ASCI)q(I)p 1480 2298 135
2 v 183 2341 a Fk(mo)q(de)f(is)i(set.)417 2326 y Fj(9)p 183
2371 573 2 v 229 2398 a Fh(8)246 2410 y Fg(This)e(is)f(the)g(\014rst)g
(argumen)o(t)e(for)h Fd(\\ls")p 707 2417 70 2 v 13 w Fg(command)229
2437 y Fh(9)246 2449 y Fg(Of)i(course,)e(suc)o(h)h(functions)e(as)i
Fd(seek)p 689 2456 75 2 v Fg(,)g Fd(io)q(ctl)p 785 2456 78
2 v 1 w Fg(,)h(....)j(can)10 b(not)h(b)q(e)g(used.)1594 2574
y Fk(9)p eop
%%Page: 10 10
bop 1449 147 a Fk(Library's)14 b(routines)p 340 164 1433 2
v 403 307 a Fi(FtpData)p 403 322 177 2 v -2 w(\(FTP)i(*,)g(c)o(har)f
(*command,)g(c)o(har)g(*param,)g(c)o(har)h(*mo)q(de\))403 362
y Fk(Mak)o(es)22 b(data)f(transfer)i(c)o(hannel,)g(with)e(presending)i
(command)c(comp)q(osed)i(from)340 412 y Fi(command)p 340 419
201 2 v 13 w Fk(and)14 b Fi(param)p 636 426 133 2 v -1 w Fk(.)k(The)d(mo)q
(de)d(m)o(ust)h(b)q(e)i Fi(\\r")p 1155 419 70 2 v 13 w Fk(or)f
Fi(\\w")p 1289 419 85 2 v 403 536 a(FtpOp)q(enRead)p 403 551
295 2 v -3 w(\(FTP)i(*,c)o(har)f(*\014lename\))403 591 y Fk(Op)q(ens)g
(\014le)f(named)f Fi(\014lename)p 732 598 174 2 v 11 w Fk(for)h(reading)g(on)
f(serv)o(er)403 715 y Fi(FtpOp)q(enW)l(rite)p 403 730 306 2
v -3 w(\(FTP)i(*,c)o(har)g(*\014lename\))403 770 y Fk(Creates)g(and)f(op)q
(ens)g(\014le)g(named)f Fi(\014lename)p 951 777 174 2 v 12
w Fk(for)g(writing)g(on)h(serv)o(er)403 894 y Fi(FtpOp)q(enApp)q(end)p
403 909 353 2 v -4 w(\(FTP)i(*,c)o(har)f(*\014lename\))403
949 y Fk(Creates)g(and)f(op)q(ens)g(\014le)g(named)f Fi(\014lename)p
951 956 174 2 v 12 w Fk(for)g(app)q(ending)h(on)g(serv)o(er)403
1073 y Fi(FtpOp)q(enDir)p 403 1088 257 2 v -4 w(\(FTP)i(*,)g(c)o(har)f
(*\014les\))403 1128 y Fk(Creates)g(c)o(hannel)f(for)f(directory)i(list)f
(reading,)f(describ)q(ed)i(b)o(y)f(argumen)o(t)f Fi(\014les)p
1600 1135 81 2 v -2 w Fk(.)403 1252 y Fi(ST)l(A)l(TUS)i(FtpRead)p
603 1267 183 2 v -2 w(\(FTP)h(*\))403 1312 y Fk(Reads)h(c)o(haracter)h(from)e
(data)h(stream.)27 b(If)17 b Fi(ASCI)q(I)p 1120 1319 135 2
v 17 w Fk(mo)q(de)g(is)g(set)1482 1297 y Fj(10)1535 1312 y
Fk(con)o(v)o(erts)h(new)340 1361 y(line)g(mark)o(ers.)31 b(When)18
b(the)h(end)g(of)e(\014le)i(is)f(detected)i(or)e(c)o(hannel)h(is)f(brok)o
(en,)h(returns)340 1411 y Fi(EOF)p 340 1418 98 2 v 403 1536
a(FtpW)l(rite)p 403 1550 194 2 v -2 w(\(FTP)c(*,)h(c)o(har)f(c\))403
1590 y Fk(W)m(rites)g(single)h(c)o(haracter)h(to)f(stream,)g(if)f
Fi(ASCI)q(I)p 1081 1597 135 2 v 16 w Fk(mo)q(de)g(is)h(set)h(con)o(v)o(erts)g
(new)f(line)340 1640 y(mark)o(ers.)i(When)c(c)o(hannel)g(is)g(brok)o(en,)f
(returns)j Fi(EOF)p 1119 1647 98 2 v 403 1764 a(in)o(t)e(FtpGetc)p
476 1779 175 2 v -2 w(\(FTP)h(*,FILE)i(*fp\))403 1819 y Fk(Reads)12
b(c)o(haracter)i(from)d(data)h(stream)g(sp)q(eci\014ed)i(b)o(y)e(fp.)17
b(Using)c(macros)e(FTPD)o(A)m(T)m(A)340 1869 y(and)j(FTPCMD)g(y)o(ou)f(can)i
(sp)q(ecify)f(stream)f(need)i(for)f(reading.)1373 1854 y Fj(11)403
1993 y Fi(ST)l(A)l(TUS)h(FtpPutc)p 603 2008 V -2 w(\(FTP)g(*,FILE)i(*fp,)e(c)
o(har)g(c\))403 2048 y Fk(W)m(rites)h(c)o(haracter)h(to)f(data)f(stream)h(sp)
q(eci\014ed)i(b)o(y)d(fp.)24 b(Using)16 b(macros)f(FTPD)o(A)m(T)m(A)340
2098 y(and)f(FTPCMD)g(y)o(ou)f(can)i(sp)q(ecify)f(stream)f(need)i(for)f
(reading.)1373 2083 y Fj(12)403 2222 y Fi(FtpClose)p 403 2237
188 2 v -2 w(\(FTP)h(*\))403 2277 y Fk(Closes)f(op)q(ened)h(c)o(hannel)f(to)g
(serv)o(er)p 340 2331 573 2 v 371 2358 a Fh(10)404 2370 y Fg(By)d(default)371
2398 y Fh(11)404 2410 y Fg(F)m(unctions)e(FtpGetc)h(and)h(FtpPutc)f(ignores)g
(data)g(stream)g(mo)q(de,)g(w)o(orks)h(as)g(binary)f(alw)o(a)o(ys)371
2437 y Fh(12)404 2449 y Fg(F)m(unctions)f(FtpGetc)h(and)h(FtpPutc)f(ignores)g
(data)g(stream)g(mo)q(de,)g(w)o(orks)h(as)g(binary)f(alw)o(a)o(ys)340
2574 y Fk(10)p eop
%%Page: 11 11
bop 183 147 a Fk(Library's)13 b(routines)p 183 164 1433 2 v
183 307 a Ff(2.5)55 b(Other)18 b(commands)f(for)i(serv)n(er)245
436 y Fi(FtpCommand)p 245 450 290 2 v -2 w(\(FTP)14 b(*,)g(c)o(har)f
(*command,)h(c)o(har)f(*param,)h(in)o(t)e(ok1,)j(ok2,)183 485
y(ok3,)h(...,)h(okN,)f(EOF\))245 536 y Fk(Sends)j(a)f(command,)e(comp)q(osed)
i(from)f Fi(command)p 910 543 201 2 v 17 w Fk(and)h Fi(param)p
1214 550 133 2 v 18 w Fk(using)g Fi(sprin)o(tf)p 1478 550 137
2 v 183 585 a Fk(function.)h(Reads)c(an)f(answ)o(er)h(from)e(the)i(serv)o
(er.)21 b(When)15 b(return)g(co)q(de)g(from)e(the)i(serv)o(er)183
635 y(is)e(not)h(included)g(to)g Fi(ok-list)p 515 642 129 2
v -2 w Fk(\()p Fi(ok1)p 660 642 73 2 v Fk(,)p Fi(ok2)p 745
642 V -1 w Fk(...\))k(the)c(sign)g(of)f(co)q(de)i(will)d(b)q(e)j(in)o(v)o
(erted.)245 737 y Fi(FtpT)o(yp)q(e)p 245 751 182 2 v -1 w(\(FTP)g(*,c)o(har)h
(mo)q(de\))245 787 y Fk(Sets)f(transfer)g(mo)q(de,)d(suc)o(h)j(as)f
Fi('A')p 755 794 63 2 v Fk(,)p Fi('I')p 829 794 45 2 v Fk(,)p
Fi('S')p 885 794 54 2 v Fk(,etc...)245 888 y Fi(FtpBinary)p
245 903 217 2 v -2 w(\(FTP)h(*\))245 938 y Fk(Sets)g(binary)e(mo)q(de)245
1040 y Fi(FtpAscii)p 245 1054 178 2 v -2 w(\(FTP)i(*\))245
1090 y Fk(Sets)g Fi(ASCI)q(I)p 333 1097 135 2 v 14 w Fk(mo)q(de)245
1191 y Fi(FtpMkdir)p 245 1206 206 2 v -2 w(\(FTP)g(*,c)o(har)h(*dirname\))245
1241 y Fk(Mak)o(es)e(directory)h(on)e(serv)o(er)245 1343 y
Fi(FtpChdir)p 245 1357 196 2 v -3 w(\(FTP)j(*,c)o(har)f(*dirname\))245
1393 y Fk(Changes)f(w)o(orking)f(directory)i(on)e(serv)o(er)245
1494 y Fi(FtpChmo)q(d)p 245 1509 228 2 v -1 w(\(FTP)i(*,c)o(har)g(*\014le,)g
(in)o(t)f(mo)q(de\))245 1544 y Fk(Changes)d(protection)h(of)f(\014le)g(at)g
(remote)f(serv)o(er,)j(argumen)o(t)d(mo)q(de)g(is)h(protection)h(lik)o(e)183
1594 y(inside)h(regular)h(stat's)h(structure.)245 1695 y Fi(FtpRm)p
245 1710 151 2 v -1 w(\(FTP)g(*,c)o(har)g(*\014lename\))245
1746 y Fk(Remo)o(v)o(es)e(\014le)g(on)h(serv)o(er)245 1847
y Fi(c)o(har)h(*FtpPwd)p 374 1862 169 2 v -1 w(\(FTP)g(*\))245
1897 y Fk(Returns)g(the)f(name)f(of)g(w)o(orking)g(directory)i(on)e(serv)o
(er)245 1998 y Fi(in)o(t)h(FtpSize)p 318 2013 159 2 v -2 w(\(FTP)h(*,c)o(har)
h(*\014lename\))245 2049 y Fk(Returned)f(size)f(\(in)g(b)o(ytes\))h(of)e
(description's)h(\014le.)245 2150 y Fi(ST)l(A)l(TUS)h(FtpStat)p
445 2165 162 2 v -2 w(\(FTP)g(*,c)o(har)h(*paten,FTP)p 1134
2150 15 2 v 16 w(ST)l(A)l(T)g(**stat)p 1415 2150 V 16 w(list\))245
2200 y Fk(Get)e(information)e(ab)q(out)i(\014les)h(sp)q(eci\014ed)h(b)o(y)e
(\\paten".)19 b(This)c(function)f(is)g(parser)h(of)183 2250
y(text)h(output)f(of)g(command)e(ls)j(or)f(dir)g(on)h(UNIX's,)f(VMS's)h(and)f
(MSDOS's)h(op)q(erating)183 2300 y(systems.)k(The)14 b(basic)h(problem)e(of)h
(realization)g(last)g(one)h(is)f(v)o(ery)h(di\013eren)o(t)g(syn)o(taxes)g(of)
183 2350 y(output)g(of)g(di\013eren)o(t)h(realization)e(of)h(UNIX's,)g(ftp's)
g(daemons)f(and)h(programs)f(suc)o(h)i(as)183 2399 y(\\ls")c(for)g(making)e
(output)j(list.)k(So....)f(This)c(function)h(giv)o(e)f(y)o(our)g(garan)o(t)o
(y)g(of)g(righ)o(t)g(w)o(ork)183 2449 y(only)e(if)g(y)o(ou)g(use)h(Berk)o
(eley's)h(ftp)q(d)f(or)g(wuftp)q(d)g(on)f(UNIX,)h(PC)g(TCP/IP)g(on)f(MSDOS)h
(and)1573 2574 y(11)p eop
%%Page: 12 12
bop 1449 147 a Fk(Library's)14 b(routines)p 340 164 1433 2
v 340 307 a(Multinet)h(on)g(AXP)h(and)e(V)-5 b(AX)16 b(VMS's)f(systems,)g
(otherwise)h(function)f(returns)i(empt)o(y)340 357 y(list)403
480 y Fi(ST)l(A)l(TUS)e(FtpStatF)l(ree)p 603 494 252 2 v -3
w(\(FTP)p 972 480 15 2 v 17 w(ST)l(A)l(T)h(*\))403 534 y Fk(F)m(ree)e(memory)
e(from)g(data)h(structures)403 656 y Fi(c)o(har)i(*FtpSyst)p
532 671 165 2 v -2 w(\(FTP)g(*\))403 711 y Fk(FtpStat)f(return)h(name)e(of)g
(op)q(erating)h(system)f(on)h(remote)g(serv)o(er)403 833 y
Fi(FtpMo)o(v)o(e)p 403 848 189 2 v -2 w(\(FTP)i(*,c)o(har)f(*old\014lename,)e
(c)o(har)i(*new\014lename\))403 888 y Fk(Renames)e(\014le)h(from)e
Fi(old\014lename)p 744 895 237 2 v 10 w Fk(to)i Fi(new\014lename)p
1045 895 256 2 v 403 1010 a(FtpP)o(ort)p 403 1025 169 2 v -3
w(\(FTP)i(*,)g(in)o(t)e(a,)i(in)o(t)e(b,)i(in)o(t)d(c,)k(in)o(t)d(d,)h(in)o
(t)f(e,)i(in)o(t)e(f)5 b(\))1511 995 y Fj(13)403 1065 y Fk(A)13
b(command)e(for)i(the)h(serv)o(er)h(for)e(making)e(a)j(new)g(data)f(c)o
(hannel.)18 b Fi(a.b.c.d)p 1480 1072 138 2 v 14 w Fk(is)13
b(an)g(IP)340 1115 y(address)j(of)d(a)g(clien)o(t\(i.e.)18
b(y)o(our)c(IP)g(address\),)h Fi(e*256+f)p 1084 1127 170 2
v 13 w Fk(is)e(a)h(p)q(ort)g(n)o(um)o(b)q(er)403 1237 y Fi(struct)g(hosten)o
(t)f(*FtpGetHost)p 735 1252 252 2 v -2 w(\(c)o(har)i(*hostname\))1368
1222 y Fj(14)403 1291 y Fk(Returned)21 b(p)q(oin)o(ter)f(to)h(structure)h
Fi(hosten)o(t)p 983 1298 154 2 v 18 w Fk(creating)e(using)g(string)h
Fi(hostname)p 1562 1298 200 2 v -2 w Fk(,)340 1341 y(whic)o(h)14
b(con)o(tains)g(name)f(of)g(the)h(computer)g(or)g(its)g(IP)g(address)1350
1326 y Fj(15)340 1482 y Ff(2.6)56 b(F)-5 b(unctions)13 b(for)f
(sending/receiving)e(con)n(trol)i(messages)f(to/from)468 1540
y(serv)n(er)403 1693 y Fi(FtpSendMessage)p 403 1708 351 2 v
-3 w(\(FTP)k(*,)h(c)o(har)g(*message\))403 1748 y Fk(Sends)f(a)e(message)h
(to)f(the)i(serv)o(er)403 1870 y Fi(in)o(t)f(FtpGetMessage)p
476 1885 327 2 v -3 w(\(FTP)i(*\))403 1925 y Fk(Receiv)o(es)f(a)e(message)h
(from)e(the)i(serv)o(er.)403 2047 y Fi(FtpMessage)p 403 2062
249 2 v -1 w(\(in)o(t)f(Num)o(b)q(er\))403 2101 y Fk(Gets)h(a)g(message)f(b)o
(y)h(co)q(de.)403 2224 y Fi(FtpNum)o(b)q(er)p 403 2239 247
2 v -2 w(\(c)o(har)g(*Message\))403 2278 y Fk(Extract)g(message's)g(n)o(um)o
(b)q(er)f(from)f(string.)p 340 2331 573 2 v 371 2358 a Fh(13)404
2370 y Fg(Recommende)o(d)d(in)i(non-trivial)d(situations)371
2398 y Fh(14)404 2410 y Fg(Extension)h(of)i(standard)f(function)f(\\gethostb)
o(yn)o(am)o(e")371 2437 y Fh(15)404 2449 y Fg(F)m(or)i(example"dx)o(unk)o
(8.oea.)o(ihep)o(.su)o(")e(or)i(\\192.102.22)o(9.7)o(1")340
2574 y Fk(12)p eop
%%Page: 13 13
bop 183 147 a Fk(Library's)13 b(routines)p 183 164 1433 2 v
183 307 a Ff(2.7)55 b(High-lev)n(el)16 b(functions)245 426
y Fi(FILE)g(*FtpF)l(ullOp)q(en)p 393 440 267 2 v -4 w(\(c)o(har)f
(*\014lename,c)o(har)e(*mo)q(de\))245 475 y Fk(P)o(arses)i(string)f
Fi(\014lename)p 492 482 174 2 v -2 w Fk(,)f(whic)o(h)h(m)o(ust)f(con)o(tain)h
(a)f(string)h(in)f(format)g(or)183 525 y Fi(host/user/pass)o(w)o(ord:\014)o
(len)o(ame)p 183 542 600 2 v 12 w Fk(or)j Fi(\014lename)p 850
532 174 2 v -2 w Fk(,)f(what)h(corresp)q(onds)h(to)f(remote)f(or)183
575 y(lo)q(cal)c(\014le.)18 b(The)13 b(second)h(argumen)o(t)e(is)g(the)h(t)o
(yp)q(e)h(of)e(op)q(ening,)g(divided)g(in)o(to)g(t)o(w)o(o)g(c)o(harac-)183
625 y(ters:)18 b(\014rst)c(|)e(the)h(mo)q(de)f(of)g(op)q(ening)h
Fi(\\r")p 800 632 70 2 v Fk(,)f Fi(\\w")p 894 632 85 2 v 13
w Fk(or)h Fi(\\a")p 1041 632 74 2 v Fk(,)g(second)h(is)e(the)i(transfer)f(t)o
(yp)q(e)183 675 y(,)g(if)g(con)o(tains)h(c)o(haracter)h Fi(\\b")p
590 682 77 2 v Fk(,)e(then)i(the)f(mo)q(de)f(is)h(binary)m(.)245
766 y Fi(ST)l(A)l(TUS)h(FtpF)l(ullClose)p 445 781 267 2 v -3
w(\(FILE)g(*\))245 816 y Fk(Close)f(\014le)g(op)q(ened)h(b)o(y)e(FtpF)m
(ullOp)q(en.)245 908 y Fi(ST)l(A)l(TUS)d(FtpF)l(ullSyn)n(tax)p
440 923 299 2 v -3 w(\(FtpStrin)o(g)e(source,FtpStri)o(ng)f(host,FtpStri)o
(ng)183 958 y(user,FtpStri)o(n)o(g)13 b(passw)o(ord,FtpStri)o(ng)g(\014le\))
245 1008 y Fk(Mak)o(e)h(out)g(string)g(\\source")g(for)g(next)g(four)g
(parameters.)245 1099 y Fi(FILE)i(*Ftpfop)q(en)p 393 1114 190
2 v -2 w(\(c)o(har)e(*\014le,)h(c)o(har)g(*mo)q(de\))245 1149
y Fk(Op)q(en)j(\014le)e(sp)q(eci\014ed)j(in)d(libftp's)g(\014le)g(sp)q
(eci\014cation.)28 b(W)m(orks)16 b(lik)o(e)g Fi(fop)q(en)p
1335 1164 115 2 v -2 w Fk(.)27 b(\(Chap-)183 1199 y(ter)14
b(1.3,)f(page)h(3\))245 1291 y Fi(ST)l(A)l(TUS)h(Ftpfclose)p
445 1305 189 2 v -2 w(\(FILE)h(*fp\))245 1340 y Fk(Close)e(\014le)g(whic)o(h)
f(op)q(ened)i(using)f(Ftpfop)q(en.)k(W)m(orks)c(lik)o(e)f(fclose.)245
1432 y Fi(ST)l(A)l(TUS)g(FtpArc)o(hie)p 443 1447 213 2 v 668
1417 a Fj(16)717 1432 y Fi(\(c)o(har)f(*what,)i(AR)o(CHIE)g(*result,)d(in)o
(t)h(n)o(um)o(b)q(er\))245 1482 y Fk(Find)i Fi(n)o(um)o(b)q(er)p
344 1489 160 2 v 12 w Fk(en)o(trys)i(in)e(Arc)o(hie's)h(database)g(enrolls)g
(describ)q(ed)h(b)o(y)f Fi(what)p 1403 1489 103 2 v 14 w Fk(argu-)183
1532 y(men)o(t.)k Fi(result)p 306 1539 119 2 v 13 w Fk(m)o(ust)13
b(b)q(e)j(p)q(oin)o(ter)f(to)f(arra)o(y)h(of)f(Arc)o(hie's)h(structures)j(n)o
(um)o(b)q(er)c(of)g(whic)o(h)183 1582 y(m)o(ust)d(b)q(e)i(equiv)n(alence)f
(or)h(higher)f(than)g Fi(n)o(um)o(b)q(er)p 826 1589 160 2 v
-2 w Fk(.)17 b(This)12 b(call)g(return)h(n)o(um)o(b)q(er)f(of)g(en)o(trys)183
1631 y(whic)o(h)e(found)g(in)g(database.)17 b(If)11 b(FtpArc)o(hie)g(return)h
(v)n(alue)e(lo)o(w)o(er)g(than)g(zero)i(then)f(p)q(oin)o(ted)183
1681 y(target)j(not)g(found)f(or)h(arc)o(hie)g(isn't)g(w)o(orks)245
1773 y Fi(ST)l(A)l(TUS)c(FtpHttpGet)p 440 1788 255 2 v -3 w(\(c)o(har)f
(*serv)o(er,)i(in)o(t)e(p)q(ort,)h(c)o(har)g(*sp)q(ec,)i(c)o(har)e(*out\))245
1823 y Fk(This)j(function)f(transfers)j(\014le)e(from)e(remote)h(computer)h
(thru)g(HTTP-serv)o(er,)i(whic)o(h)183 1872 y(m)o(ust)d(b)q(e)i(describ)q(ed)
h(b)o(y)f(t)o(w)o(o)f(\014rsts)h(argumen)o(ts)f(serv)o(er)i(and)e(p)q(ort.)19
b(Ob)r(ject)14 b(whic)o(h)g(m)o(ust)183 1922 y(b)q(e)f(to)q(ok)f(\(probably)g
(ftp's)g(\014le\))h(m)o(ust)f(b)q(e)h(describ)q(ed)h(as)f(HTTP)g(ob)r(jects.)
19 b(This)12 b(function)183 1972 y(alw)o(a)o(ys)g(returns)k(one)e(of)f(sev)o
(eral)i(answ)o(ers)g(suc)o(h)f(as:)201 2053 y(OK)21 b(Ob)r(ject)16
b(w)o(as)d(transfered)j(correctly)m(.)157 2133 y(QUIT)21 b(So)q(c)o(k)o(et's)
15 b(comm)o(unicatio)o(n)c(problem,)h(need)j(to)f(rep)q(eat)h(request)g
(again.)131 2212 y(LQUIT)21 b(Problems)d(with)g(op)q(ening)g(lo)q(cal)f
(\014le,)i(probably)f(no)g(disk)g(space)i(or)e(p)q(ermitions)286
2261 y(problems,)13 b(need)i(to)e(c)o(hec)o(k)i(regular)f(errno)h(v)n
(ariable.)85 2340 y(ENOENT)21 b(Sp)q(eci\014ed)16 b(ob)r(ject)e(do)q(esn't)h
(exists.)p 183 2371 573 2 v 214 2398 a Fh(16)246 2410 y Fg(FtpArc)o(hie)10
b(for)h(making)e(list)i(and)g(sp)q(eci\014catio)o(n)e(of)i(searc)o(hed)e
(\014les)i(runs)f(\\arc)o(hie")f(whic)o(h)i(m)o(ust)g(b)q(e)183
2449 y(accessible)e(for)i(execution)e(in)i(one)f(of)i(directories)c(listed)j
(in)g(P)m(A)m(TH)i(en)o(vironmen)n(t)c(v)n(ariable)1573 2574
y Fk(13)p eop
%%Page: 14 14
bop 1162 147 a Fk(Simple)12 b(example)h(of)g(using)h(LIBFTP)p
340 164 1433 2 v 340 307 a Fl(3)67 b(Simple)22 b(example)g(of)f(using)i
(LIBFTP)403 403 y Fk(Next)12 b(example)d(demonstrate)j(v)o(ery)f(simple)f
(using)h(library)g(calls)f(only)h(Ftpfop)q(en)h(and)340 453
y(Ftpfclose)j(functions)f(whic)o(h)f(discriminate)g(libftp's)g(\014le)h(sp)q
(eci\014cation:)340 606 y Fc(/)p Fe(\003)21 b Fc(Include)h(standar)n(d)f
(libftp's)e(he)n(ader)i Fe(\003)p Fc(/)340 706 y Fb(#include)13
b Fa(<)p Fb(FtpLibrary.h)p Fa(>)340 855 y Fk(main\()p Fi(in)o(t)d
Fk(argc,)k Fi(c)o(har)f Fe(\003)p Fk(argv[]\))340 905 y Fe(f)382
1005 y Fk(FILE)h Fe(\003)p Fk(input,)p Fe(\003)p Fk(output;)382
1054 y Fi(in)o(t)e Fk(c;)382 1204 y Fi(if)17 b Fk(\(argc)p
Fa(<)p Fk(3\))423 1254 y(exit\(fprin)o(tf\(stderr,)p Fb("Usage:)43
b(\045s)22 b(input-file)d(output-file)p Fe(n)p Fb(n")p Fk(,argv[)o(0])o
(\)\);)382 1353 y(FtplibDebug\(y)o(es\);)382 1453 y Fi(if)e
Fk(\(\(input=Ftpfop)q(en\(argv[1],)p Fb("r")p Fk(\)\)==NULL\))423
1503 y Fe(f)465 1553 y Fk(p)q(error\(argv[1]\);)465 1602 y(exit\(1\);)423
1652 y Fe(g)382 1752 y Fi(if)g Fk(\(\(output=Ftpfop)q(en\(argv[2],)p
Fb("w")p Fk(\)\)==NULL\))423 1802 y Fe(f)465 1851 y Fk(p)q(error\(argv[2]\);)
465 1901 y(exit\(1\);)423 1951 y Fe(g)382 2051 y Fi(while)12
b Fk(\()i(\(c=getc\(input\)\))i Fe(6)p Fk(=)e(EOF)h(&&)f(\(putc\(c,output\))p
Fe(6)p Fk(=EOF\))i(\);)382 2150 y Fi(if)h Fk(\(ferror\(input\)\))423
2200 y Fe(f)465 2250 y Fk(p)q(error\(argv[1]\);)465 2300 y(exit\(1\);)423
2350 y Fe(g)382 2449 y Fi(if)g Fk(\(ferror\(output\)\))340
2574 y(14)p eop
%%Page: 15 15
bop 183 147 a Fk(Simple)12 b(example)g(of)i(using)f(LIBFTP)p
183 164 1433 2 v 266 307 a Fe(f)307 357 y Fk(p)q(error\(argv[1]\);)307
407 y(exit\(1\);)266 457 y Fe(g)224 556 y Fk(Ftpfclose\(input\);)224
606 y(Ftpfclose\(output\);)224 706 y(exit\(0\);)183 805 y Fe(g)245
897 y Fk(F)m(or)g(tests)j(w)o(orks)e(this)g(program)e(y)o(ou)h(can)h(try)h
(run)f(one)g(as:)245 996 y(\045)f(example)g(username/passw)o
(ord@hostname:\014lename)f(m)o(y\014le.out)245 1046 y(\045)h(example)g(m)o
(y\014le.input)f(username/passw)o(ord@hostname:\014lename.out)1573
2574 y(15)p eop
%%Page: 16 16
bop 340 370 a Fl(Index)340 452 y Fk(AR)o(CHIE,)14 b(5)340 543
y(BUFSIZ,)h(2)340 633 y(c)o(h,)f(4)340 683 y(coun)o(ter,)h(5)340
733 y(createtime,)f(5)340 783 y(Ctrl,)g(2)340 873 y(data,)f(3)340
923 y(da)o(y)m(,)g(6)340 973 y(debug,)h(4)340 1063 y(EOF,)g(10)340
1113 y(errno,)h(3)340 1163 y(error,)g(4)340 1213 y(EXIT,)f(2)340
1303 y(\014le,)g(5)340 1353 y(\015ags,)g(5)340 1403 y(FREE,)g(3)340
1453 y(FtpAb)q(ort,)h(7)340 1503 y(FtpAccoun)o(t,)g(7)340 1553
y(FtpArc)o(hie,)g(13)340 1602 y(FtpAscii,)f(11)340 1652 y(FtpAssert,)i(3)340
1702 y(FtpBinary)m(,)e(11)340 1752 y(FTPBUFSIZE,)h(2)340 1802
y(FtpBy)o(e,)g(7)340 1851 y(FtpChdir,)f(11)340 1901 y(FtpChmo)q(d,)f(11)340
1951 y(FtpClearFlag,)g(5)340 2001 y(FtpClose,)h(10)340 2051
y(FtpCommand,)d(11)340 2100 y(FtpConnect,)k(6)340 2150 y(FtpCop)o(y)m(,)e(9)
340 2200 y(FtpData,)g(10)340 2250 y(FtpDebug,)h(8)340 2300
y(FtpDebugDebug,)g(8)340 2350 y(FtpDebugError,)h(8)340 2399
y(FtpDebugIO,)f(8)340 2449 y(FtpDir,)g(9)1129 452 y(FtpDirectory)m(,)g(9)1129
502 y(FtpError,)h(3)1129 552 y(Ftpfclose,)f(13)1129 602 y(Ftpfop)q(en,)g(13)
1129 652 y(FtpF)m(ullClose,)f(13)1129 702 y(FtpF)m(ullOp)q(en,)h(13)1129
752 y(FtpF)m(ullSyn)o(tax,)e(13)1129 802 y(FtpGet,)i(9)1129
852 y(FtpGetc,)g(10)1129 902 y(FtpGetHost,)g(12)1129 952 y(FtpGetMessage,)h
(12)1129 1001 y(FtpHttpGet,)f(13)1129 1051 y(FtplibDebug,)f(5,)g(6,)g(8)1129
1101 y(FtpLibrary)m(.h,)g(1)1129 1151 y(FtpLink,)g(9)1129 1201
y(FtpLog,)g(8)1129 1251 y(FtpLogin,)g(7)1129 1301 y(FtpMessage,)i(12)1129
1351 y(FtpMkdir,)f(11)1129 1401 y(FtpMo)o(v)o(e,)g(12)1129
1451 y(FtpNum)o(b)q(er,)f(12)1129 1501 y(FtpOp)q(enApp)q(end,)j(10)1129
1551 y(FtpOp)q(enDir,)e(10)1129 1601 y(FtpOp)q(enRead,)h(10)1129
1650 y(FtpOp)q(enW)m(rite,)f(10)1129 1700 y(FtpP)o(assiv)o(eT)m(ransfer,)g(9)
1129 1750 y(FtpP)o(assw)o(ord,)g(7)1129 1800 y(FtpP)o(ort,)g(12)1129
1850 y(FtpPut,)g(9)1129 1900 y(FtpPutc,)h(10)1129 1950 y(FtpPwd,)f(11)1129
2000 y(FtpQuic)o(kBy)o(e,)g(7)1129 2050 y(FtpRead,)g(10)1129
2100 y(FtpRetr,)g(8)1129 2150 y(FtpRm,)e(11)1129 2200 y(FtpSendMessage,)k(12)
1129 2249 y(FtpSetDebugHandler,)f(5,)e(7)1129 2299 y(FtpSetErrorHandler,)i
(5,)f(7)1129 2349 y(FtpSetFlag,)g(5)1129 2399 y(FtpSetHashHandler,)h(5,)e(8)
1129 2449 y(FtpSetIOHandler,)i(5,)e(8)p eop
%%Page: 17 17
bop 183 147 a Fk(INDEX)1158 b(INDEX)p 183 164 1433 2 v 183
307 a(FtpSetP)o(ort,)14 b(5)183 357 y(FtpSetTimeout,)e(5)183
407 y(FtpSize,)i(11)183 457 y(FtpStat,)f(6,)h(11)183 506 y(FtpStatF)m(ree,)g
(6,)f(12)183 556 y(FtpStatus,)h(3)183 606 y(FtpStor,)g(9)183
656 y(FtpString,)f(2)183 706 y(FtpSyst,)h(12)183 756 y(FtpT)m(estFlag,)f(5)
183 805 y(FtpT)o(yp)q(e,)h(11)183 855 y(FtpUser,)h(7)183 905
y(x)p 221 905 13 2 v 28 w(NFDS,)f(2)183 955 y(x)p 221 955 V
28 w(ST)m(A)m(T,)f(6)183 1005 y(FtpW)m(rite,)g(10)183 1094
y(group,)g(6)183 1184 y(hash,)g(4)183 1234 y(host,)g(5)183
1323 y(ino)q(des,)g(6)183 1373 y(IO,)g(4)183 1463 y(link,)f(6)183
1513 y(LQUIT,)h(2)183 1602 y(x)p 221 1602 V 28 w(ANSWERS,)h(2)183
1652 y(mo)q(de,)e(4,)h(6)183 1702 y(mon)o(th,)e(6)183 1792
y(name,)h(6)183 1841 y(next,)i(6)183 1931 y(p)q(ort,)f(5)183
2021 y(QUIT,)g(2)183 2110 y(seek,)h(4)183 2160 y(size,)g(5,)f(6)183
2210 y(so)q(c)o(k,)h(3)183 2260 y(ST)m(A)m(TUS,)e(2)183 2350
y(time,)g(6)183 2399 y(timeout,)g(5,)h(8)183 2449 y(title,)g(5)971
307 y(t)o(yp)q(e,)h(6)971 399 y(user,)h(6)1573 2574 y(17)p
eop
%%Page: 18 18
bop 340 147 a Fk(CONTENTS)962 b(CONTENTS)p 340 164 1433 2 v
340 307 a Fl(Con)n(ten)n(ts)340 399 y Fi(1)39 b(V)l(ariables)14
b(and)h(de\014niti)o(ons)827 b(2)403 448 y Fk(1.1)41 b(Some)13
b(de\014nitions)h(in)f(libftp's)g(header)i(\014le)f(\(FtpLibrary)m(.h\))i
Fa(:)k(:)g(:)h(:)f(:)g(:)g(:)66 b Fk(2)403 498 y(1.2)41 b(Libftp's)13
b(\014le)h(sp)q(eci\014cation)23 b Fa(:)d(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f
(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)66 b Fk(3)403
548 y(1.3)41 b(The)14 b(FTP)h(data)e(structure)25 b Fa(:)20
b(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f
(:)g(:)g(:)66 b Fk(3)498 598 y(1.3.1)46 b(The)14 b(mem)o(b)q(ers)f(of)g(FTP)h
(structure)22 b Fa(:)f(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)
66 b Fk(3)498 648 y(1.3.2)46 b(Initialization)12 b(of)h(FTP)h(structure)37
b Fa(:)21 b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)66
b Fk(5)403 697 y(1.4)41 b(The)14 b Fi(AR)o(CHIE)p 583 704 192
2 v 1 w Fk(data)g(structure)29 b Fa(:)20 b(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)
f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)66 b Fk(5)403 747 y(1.5)41
b(The)14 b Fi(FTP)p 682 747 15 2 v 18 w(ST)l(A)l(T)p 583 754
235 2 v Fk(data)f(structure)19 b Fa(:)i(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g
(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)66 b Fk(6)340 839 y Fi(2)39
b(Library's)14 b(routines)970 b(6)403 888 y Fk(2.1)41 b
(Connection/Disconnection)14 b(with)g(serv)o(er)31 b Fa(:)21
b(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)66
b Fk(6)403 938 y(2.2)41 b(The)14 b(debugging)35 b Fa(:)20 b(:)g(:)h(:)f(:)g
(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h
(:)f(:)g(:)g(:)66 b Fk(7)403 988 y(2.3)41 b(Data)13 b(transfer)i(pro)q
(cedures)h Fa(:)k(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h
(:)f(:)g(:)h(:)f(:)g(:)g(:)66 b Fk(8)403 1038 y(2.4)41 b(Serv)o(er's)15
b(\014les)f(read/write)h(pro)q(cedures)23 b Fa(:)d(:)g(:)h(:)f(:)g(:)h(:)f(:)
g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)66 b Fk(9)403 1088 y(2.5)41
b(Other)15 b(commands)d(for)h(serv)o(er)37 b Fa(:)20 b(:)g(:)h(:)f(:)g(:)g(:)
h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)45
b Fk(11)403 1137 y(2.6)c(F)m(unctions)14 b(for)g(sending/receiving)g(con)o
(trol)g(messages)f(to/from)f(serv)o(er)j Fa(:)45 b Fk(12)403
1187 y(2.7)c(High-lev)o(el)13 b(functions)42 b Fa(:)20 b(:)g(:)g(:)h(:)f(:)g
(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)h(:)f(:)g(:)h(:)f(:)g(:)g(:)45
b Fk(13)340 1279 y Fi(3)39 b(Simple)13 b(example)h(of)i(using)e(LIBFTP)621
b(14)340 2574 y Fk(18)p eop
%%Trailer
end
userdict /end-hook known{end-hook}if
%%EOF
\End\Of\Shar\
else
echo "will not over write ./doc/libftp.ps"
fi
echo "Finished archive 2 of 8"
exit


Oleg Orel

unread,
Dec 12, 1995, 3:00:00 AM12/12/95
to
Submitted-By: or...@dxunk1.cern.ch (Oleg Orel)
Posting-Number: Volume 29, Issue 65
Archive-Name: libftp-5.0/part04

#!/bin/sh
# to extract, remove the header and type "sh filename"

if `test ! -d ./utils`
then
mkdir ./utils
echo "mkdir ./utils"

fi
if `test ! -s ./utils/glob.h`
then
echo "writing ./utils/glob.h"
cat > ./utils/glob.h << '\End\Of\Shar\'

* @(#)glob.h 8.1 (Berkeley) 6/2/93
*/

#ifndef _GLOB_H_
#define _GLOB_H_


#include <cdefs.h>

struct stat;
typedef struct {
int gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
int gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
int (*gl_errfunc) __P((const char *, int));

/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
void (*gl_closedir) __P((void *));
struct dirent *(*gl_readdir) __P((void *));
void *(*gl_opendir) __P((const char *));
int (*gl_lstat) __P((const char *, struct stat *));
int (*gl_stat) __P((const char *, struct stat *));
} glob_t;

#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
#define GLOB_ERR 0x0004 /* Return on error. */
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
#define GLOB_NOSORT 0x0020 /* Don't sort. */

#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */

#define GLOB_NOSPACE (-1) /* Malloc call failed. */
#define GLOB_ABEND (-2) /* Unignored error. */

__BEGIN_DECLS
int glob __P((const char *, int, int (*)(const char *, int), glob_t *));
void globfree __P((glob_t *));
__END_DECLS

#endif /* !_GLOB_H_ */
\End\Of\Shar\
else
echo "will not over write ./utils/glob.h"
fi
if `test ! -s ./utils/list.c`
then
echo "writing ./utils/list.c"
cat > ./utils/list.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: list.c,v 5.0 1995/12/10 10:34:21 orel Exp $";

/*
$Log: list.c,v $
* Revision 5.0 1995/12/10 10:34:21 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.2 1995/09/09 09:51:49 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.2 1995/09/09 09:51:49 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.1 1995/08/19 18:42:25 orel


* *** empty log message ***
*

* Revision 4.1 1995/08/19 18:42:25 orel


* *** empty log message ***
*

* Revision 4.0 1995/07/11 14:51:08 orel

* Libftp version 4.0
*


* Revision 4.0 1995/07/11 14:51:08 orel

* Libftp version 4.0
*


* Revision 3.1 1995/06/21 09:28:34 orel
* Porting to AIX and some modification..........
*

* Revision 3.1 1995/06/21 09:28:34 orel
* Porting to AIX and some modification..........
*
* Revision 3.0 1995/03/20 05:26:29 orel


* *** empty log message ***
*

* Revision 3.0 1995/03/20 05:26:29 orel


* *** empty log message ***
*

* Revision 1.3 1995/03/20 05:17:54 orel


* *** empty log message ***
*

* Revision 1.2 1995/03/20 05:17:31 orel


* *** empty log message ***
*

* Revision 1.2 1995/03/20 05:17:31 orel


* *** empty log message ***
*

* Revision 1.1 1995/03/16 09:38:04 orel


* Initial revision
*
*/

#include "list.h"
#include "uftp.h"
#include <stdio.h>


list_init(LIST **list)
{
if (*list==NULL) return;

if ((*list)->next!=NULL)
list_init(&((*list)->next));

free(*list);
*list=NULL;
}

list_add(LIST **list,char *item)
{
register LIST *t;

for (t=(*list);;t=t->next)
{
if (t==NULL)
{
t=(LIST *) malloc(sizeof(LIST));
if (t==NULL) return -1;
bzero(t,sizeof *t);
break;
}

if (!strcmp(t->item,item)) return 0; /* ALready in list */

if (t->next==NULL)
{
t = t->next = (LIST *) malloc(sizeof(LIST));
if (t==NULL) return -1;
bzero(t,sizeof *t);
break;
}
}

strcpy(t->item,item);
t->next=NULL;
if ((*list)==NULL) (*list)=t;

return 1;
}

list_count(LIST **list)
{
register int count=0;
register LIST *t;

for(t=(*list);t!=NULL;t=t->next)
count++;

return count;
}

list_remove(LIST **list, char *item)
{
register LIST *t,*prev;

for(t=(*list);t!=NULL;prev=t,t=t->next)
{
if (!strcmp(t->item,item))
{
if ((*list)=t)
{
*list=t->next;
free(t);
return;
}

prev -> next = t -> next;

free(t);
return;
}
}

}

list_sort(LIST **list)
{
LIST *l,*ll;
FtpString tmp;

for (l=(*list);l!=NULL && (l->next)!=NULL ;l=l->next)
for (ll=l;ll!=NULL;ll=ll->next)
if (strcmp(l->item,ll->item)>0)
{
strcpy(tmp,l->item);
strcpy(l->item,ll->item);
strcpy(ll->item,tmp);
}
}
\End\Of\Shar\
else
echo "will not over write ./utils/list.c"
fi
if `test ! -s ./utils/list.h`
then
echo "writing ./utils/list.h"
cat > ./utils/list.h << '\End\Of\Shar\'
#ifndef __LIST_H__
#define __LIST_H__
typedef struct _list
{
char item[1024];
struct _list *next;
} LIST;


int list_init(LIST**);
int list_add(LIST**,char*);
int list_remove(LIST**,char*);
int list_count(LIST**);
#endif


\End\Of\Shar\
else
echo "will not over write ./utils/list.h"
fi
if `test ! -s ./utils/uftp.c`
then
echo "writing ./utils/uftp.c"
cat > ./utils/uftp.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: uftp.c,v 5.0 1995/12/10 10:34:21 orel Exp $";

/*
$Log: uftp.c,v $
* Revision 5.0 1995/12/10 10:34:21 orel


* LIBFTP Version 5.0 (Distributed revision)
*

* Revision 4.6 1995/12/02 11:24:01 orel
* pathes for proxy get thru www-daemon
*

* Revision 4.5 1995/11/09 19:19:04 orel
* Clean problem with end of last command at the end of current command
* if last one shortly then first
* ,
*
* Revision 4.5 1995/11/09 19:19:04 orel
* Clean problem with end of last command at the end of current command
* if last one shortly then first
* ,
*
* Revision 4.4 1995/09/09 09:51:49 orel


* Change type String to FtpString for clean conflicting with
* X11's type string which is pointer to character only.
* Thanks for MIT for this good name of type.
*

* Revision 4.3 1995/09/09 07:48:33 orel
* Some corrections for trafic log file
*

* Revision 4.2 1995/08/19 18:42:25 orel


* *** empty log message ***
*

* Revision 4.1 1995/08/19 18:07:06 orel
* Fitch for calculate trafic for log
*


* Revision 4.0 1995/07/11 14:51:08 orel

* Libftp version 4.0
*


* Revision 4.0 1995/07/11 14:51:08 orel
* Libftp version 4.0
*

* Revision 3.5 1995/07/04 13:37:12 orel


* chenge compctl function
*

* Revision 3.4 1995/06/28 13:52:37 orel


* *** empty log message ***
*

* Revision 3.3 1995/06/28 13:37:26 orel


* *** empty log message ***
*

* Revision 3.2 1995/06/21 09:28:34 orel
* Porting to AIX and some modification..........
*
* Revision 3.1 1995/06/20 15:54:28 orel


* Porting to AIX
*

* Revision 3.0 1995/03/20 05:26:29 orel


* *** empty log message ***
*

* Revision 2.14 1995/03/20 05:17:54 orel


* *** empty log message ***
*

* Revision 2.13 1995/03/20 05:17:31 orel


* *** empty log message ***
*

* Revision 2.13 1995/03/20 05:17:31 orel


* *** empty log message ***
*

* Revision 2.12 1995/03/16 09:38:04 orel
* SIGPIPE, hosts, ........
*
* Revision 2.11 1995/03/07 16:01:40 orel


* *** empty log message ***
*

* Revision 2.10 1995/03/05 15:02:08 orel


* *** empty log message ***
*

* Revision 2.9 1995/02/26 16:41:21 orel


* add recursive rm and recursive put
*

* Revision 2.8 1995/02/26 12:44:02 orel


* *** empty log message ***
*

* Revision 2.7 1995/02/18 15:42:27 orel


* add recursive mget
*

* Revision 2.6 1995/02/17 12:47:14 orel


* add parallel mget
*

* Revision 2.6 1995/02/17 12:47:14 orel
* add parallel mget
*
* Revision 2.5 1995/02/13 16:05:45 orel
* add setargs
*
* Revision 2.4 1995/02/04 09:12:51 orel
* rcs id
*

*/
/* File Transfer Protocol Toolkit based on libftp */

#include "uftp.h"
#include <varargs.h>


FTP *ftp[NFRAMES];
LINKINFO iftp[NFRAMES];
int frame=0;


int status;
jmp_buf start;
int lastcmd=0;
int trymode=1;
int restmode=1;
int hashmode=0;
int sleeptime=30;
int winsize;
int interactive=0;

time_t noopinterval=0;
time_t nooptimeout=1;
time_t prevtime=0;

FtpString prompt="%T %u@%H:%d> ";
FtpString defaultuser;

FtpString www_gateway="www.cern.ch";
int www_port=8080;

ALIAS *firstalias=NULL;
LIST *hosts=NULL;


/* if main have any arguments, interprets each it as command with args */


main(int argc, char **argv)
{
register int i;
register char *p1;

FtpString params;
FtpString tmp1,tmp2;

if (setjmp(start)!=0)
goto main_loop;

setsignals();

#if defined(TIOCGWINSZ) && defined(SIGWINCH)
getwinsz();
#endif

FtpSetErrorHandler(&FtpInit,my_error);
FtpSetIOHandler(&FtpInit,my_error);

strcpy(defaultuser,getpwuid(getuid())->pw_name);


memset(ftp,0,sizeof(FTP*)*NFRAMES);
memset(iftp,0,sizeof(LINKINFO)*NFRAMES);

fprintf(stderr,"Welcome to uftp version %s (%s)\n",
strcpy(tmp1,word(rcsid,3)),
strcpy(tmp2,word(rcsid,4)));

batch(SYSTEMRC);

for (i=1, params[0]=0; i< argc; i++)
{
strcat(params,argv[i]);
if (i+1!=argc) strcat(params," ");
}

load_link("ftp","open");
load_link("ftp","connect");
load_link("ftp","preconnect");


batch(getrcname());
batch(getaliasrcname());
batch(getsetsrcname());

load_compctl();

if (params[0]!=0)
{
FtpString new;

strcpy(new,"open ");

if (ifalias(params)||ifcmd(params))
execute (params);
else
strcat(new,params),
execute(new);
}


gl_tab_hook=/*tab*/compctl_hook;

main_loop:

interactive=1;

setsignals();

while (1)
{

setjmp(start);
if (lastcmd) quit(0);


p1=getline(getprompt());

if (p1==NULL||*p1==0)
{
quit(0);
}

if (strchr(p1,'\n')!=NULL) *(char*)strchr(p1,'\n')=0;

if (*word(p1,1)==0) continue;

gl_histadd(p1);
execute(p1);
}
}
/* Exacute few command separated by ';' . The character ' must use for mark complex
works*/

execute (char *cmd)
{
FtpString w1,w2,w3,w4,w5,w6;
FtpString newcmd;
char *p;


if (!*cmd || *cmd=='#' ) return;

for ( p=newcmd ; *cmd; cmd++)
{
if ( *cmd == '\'' )
{
*p++ = *cmd++;
while ( *cmd != '\'' && *cmd != 0 ) *p++ = *cmd++;
if ( *cmd == 0 )
return puts("Unbalanced \', please corrected!\n");
*p++ = *cmd;
continue;
}

if ( *cmd == ';' )
{
*p=0;
execute(newcmd);
p=newcmd;
continue;
}
*p++ = *cmd;
}


*p=0;
cmd=newcmd;

if ( *cmd=='\\' )
cmd++;
else
{
FtpString new;
strcpy(new,"\\");
strcat(new,expandalias(cmd));
return execute(new);
}

if ( *cmd == '!' )
{
int pid,_pid;
int status;

if (!(pid=fork()))
{
execlp(((char*)getenv("SHELL")==NULL)?"/bin/sh":(char *)getenv("SHELL"),
"shell","-c",cmd+1,NULL);
exit(-1);
}

while(1)
{
_pid=wait(&status);
if (_pid==pid)
return;
}
}


redir(cmd);

if (cmd[strlen(cmd)-1]=='&')
{
FtpString tmp;

cmd[strlen(cmd)-1]=0;

strcpy(tmp,"bg ");
strcat(tmp,cmd);

strcpy(cmd,tmp);
}

strcpy(w1,word(cmd,1));
strcpy(w2,word(cmd,2));
strcpy(w3,word(cmd,3));
strcpy(w4,word(cmd,4));
strcpy(w5,word(cmd,5));
strcpy(w6,word(cmd,6));

return executev(w1,w2,w3,w4,w5,w6);


}

executev(ARGS)
{
CMDS *xcmd = &cmds[0];


if (isdigit(*w1))
return
atoi(w1)<NFRAMES?frame=atoi(w1):0,
executev(w2,w3,w4,w5,w6,"");

while ( xcmd -> cmd != NULL )
{
if ( !strcmp(xcmd->cmd,w1) && (xcmd -> func != NULL) )
{
int status;

if ( xcmd -> need && LINK == NULL)
return puts("Need connection to server");
iftp[frame].lock=1; unsetsignals();
status = (*xcmd->func)(w1,w2,w3,w4,w5,w6);
iftp[frame].lock=0; setsignals();
redirback();
return status;
}
xcmd++;
}

fprintf(stderr,"%s: unknown command\n",w1);
return -1;
}


void intr(int sig)
{
fprintf(stderr,"Interupted by signal %d\n",sig);
if (LINK!=NULL) FtpSetHashHandler(LINK,NULL);
setsignals();
prevtime = time((time_t *)0);
longjmp(start,1);
}

newframe(int connecteble)
{
register int i;

if (connecteble)
for (i=0; i<NFRAMES; i++) if (ftp[i]!=NULL) return frame=i;
for (i=0; i<NFRAMES; i++) if (ftp[i]==NULL) return frame=i;
return -1;
}

STATUS my_error(FTP *ftp, int code, char *msg)
{

if (code==LQUIT||(ftp==NULL)) log(msg);
else
FtpLog(ftp->title,msg);

if ( abs(code) == 530 && (strstr(msg,"anonymous")!=NULL))
{
Ftp_reopen();
longjmp(start,1);
}
longjmp(start,1);
}

char *getrcname()
{
static FtpString rcpath;
struct passwd *pwd=getpwuid(getuid());

sprintf(rcpath,"%s/.uftprc",pwd->pw_dir);
return rcpath;
}

char *getaliasrcname()
{
static FtpString rcpath;
struct passwd *pwd=getpwuid(getuid());

sprintf(rcpath,"%s/.uftp_aliases",pwd->pw_dir);
return rcpath;
}

char *getsetsrcname()
{
static FtpString rcpath;
struct passwd *pwd=getpwuid(getuid());

sprintf(rcpath,"%s/.uftp_sets",pwd->pw_dir);
return rcpath;
}

char *gethostsname()
{
static FtpString rcpath;
struct passwd *pwd=getpwuid(getuid());

sprintf(rcpath,"%s/.uftp_hosts",pwd->pw_dir);
return rcpath;
}

char *makestr(va_alist)
va_dcl
{
char *p1;
va_list args;
static FtpString new;

new[0]=0;

va_start(args);

while(1)
{
p1=va_arg(args,char *);
if (p1==NULL) break;
if (*p1!=0)
{
if (new[0]!=0) strcat(new," ");
strcat(new,p1);
}
}
va_end(args);
return new;
}


#define ADD(str,chr) ( *(str)++ = (chr),*(str)=0)

INLINE ADDSTR(char **str, char *str1)
{
while (*str1) *(*str)++ = *str1++;
**str='\0';
}

char *expandalias(char *str)
{
ALIAS *a=firstalias;
static FtpString new;
FtpString w1={0};
char *p,*p1=new,*args;
int dollar=0;

new[0]=0;

strcpy(w1,word(str,1));

if ( (p=strchr(str,' '))!=NULL )
args=p+1;
else
args="";

while (a)
{
if (!strcmp(a->name,w1))
break;
a=a->next;
}

if (!a)
return str;

for ( p=a->str; *p; p++)
{
if ( *p != '$' )
{
ADD(p1,*p);
continue;
}

dollar=1;
p++;

if (isdigit(*p))
{
ADDSTR(&p1,word(str,(*p)-'0'+1));
continue;
}

switch (*p)
{

case '\0':
case '$': ADD(p1,'$');continue;
case '*': ADDSTR(&p1,args);continue;
default: ADD(p1,'$');ADD(p1,*p);continue;
}
}

if (!dollar)
{
ADD(p1,' ');
ADDSTR(&p1,args);
}

*p=0;

return new;
}

ifalias(char *cmd)
{
if (*getalias(cmd)!=0)
return 1;
return 0;
}

char *getalias(char *cmd)
{
FtpString what;
ALIAS *a=firstalias;


strcpy(what,word(cmd,1));

while ( a!=NULL)
{
if (!strcmp(a->name,what))
return a->str;
a=a->next;
}
return "";
}


ifcmd(char *arg)
{
CMDS *_cmds = &cmds[0];
FtpString cmd;

strcpy(cmd,word(arg,1));

while (1)
{
if (_cmds->cmd==NULL) return 0;
if (!strcmp(cmd,_cmds->cmd)) return 1;
_cmds++;
}
}


char *getprompt()
{

static FtpString _prompt;
FtpString tmp;
char *s;

_prompt[0]=0;

for(s=prompt;*s;s++)
switch (*s)
{
case '%':
switch (*++s)
{

case 'H':
strcat(_prompt,iftp[frame].host);
break;

case 'h':
strcpy(tmp,iftp[frame].host);
if (strchr(tmp,'.')!=NULL) *(char *)strchr(tmp,'.')=0;
strcat(_prompt,tmp);
break;

case 'M':
gethostname(tmp, sizeof tmp);
strcat(_prompt,gethostbyname(tmp)->h_name);
break;

case 'm':
gethostname(tmp, sizeof tmp);
strcpy(tmp,gethostbyname(tmp)->h_name);
if (strchr(tmp,'.')!=NULL) *(char *)strchr(tmp,'.')=0;
strcat(_prompt,tmp);
break;

case 'u':
strcat(_prompt,iftp[frame].user);
break;

case 'd':
strcat(_prompt,iftp[frame].pwd);
break;

case 'D':
strcat(_prompt,(char *)getcwd(tmp,sizeof(tmp)));
break;

case 'f':
sprintf(tmp,"%d",frame);
strcat(_prompt,tmp);
break;

case 'p':
sprintf(tmp,"%d",(LINK==NULL)?0:LINK->port);
strcat(_prompt,tmp);
break;

case 't':

sprintf(tmp,"%d",(LINK==NULL)?0:LINK->timeout.tv_sec);
strcat(_prompt,tmp);
break;

case 'T':



{
time_t t=time((time_t *)0);
struct tm *lt=localtime(&t);

sprintf(tmp,"%02d:%02d:%02d",lt->tm_hour,
lt->tm_min,lt->tm_sec);
strcat(_prompt,tmp);
}
break;

case 'P':

sprintf(tmp,"%d",getpid());
strcat(_prompt,tmp);
break;

default:
sprintf(tmp,"%%%c",*s);
strcat(_prompt,tmp);
break;
}
break;

case '^':

++s;
if (isalpha(*s))
{
sprintf(tmp,"%c",toupper(*s)-'A'+1);
strcat(_prompt,tmp);
}
break;

default:

sprintf(tmp,"%c",*s);
strcat(_prompt,tmp);
break;
}
return _prompt;
}


void noop()
{
int i;
time_t curtime,save;
STATUS (*func1)(),(*func2)(),(*func3)();


if (noopinterval==0) return;

curtime = time((time_t *)0);

signal(SIGALRM,noop);

if (prevtime==0)
{
prevtime=curtime;
alarm(noopinterval);
return;
}

if (curtime-prevtime < noopinterval)
{
alarm(prevtime+noopinterval-curtime);
return;
}

fprintf(stderr,"Waiting...");fflush(stderr);

for (i=0;i<NFRAMES;i++)
{
if ( ftp[i]==NULL || FTPCMD(ftp[i]) == NULL || iftp[i].lock )
continue;

func1=ftp[i]->debug; ftp[i]->debug=NULL;
func2=ftp[i]->error; ftp[i]->error=NULL;
func3=ftp[i]->IO; ftp[i]->IO=NULL;
save = ftp[i]->timeout.tv_sec;
ftp[i]->timeout.tv_sec = nooptimeout;

FtpCommand(ftp[i],"NOOP","",0,EOF);

ftp[i]->timeout.tv_sec = save;
ftp[i]->debug=func1;
ftp[i]->error=func2;
ftp[i]->IO=func3;

}

alarm(noopinterval);
prevtime=curtime;

for (i=0;i<10;i++) putc(8,stderr),putc(' ',stderr),putc(8,stderr);
fflush(stderr);
}


setsignals()
{
signal(SIGINT,intr);
signal(SIGQUIT,intr);

#ifdef SIGURG
signal(SIGURG,SIG_IGN);
#endif

signal(SIGIO,SIG_IGN);
signal(SIGCHLD,SIG_IGN);
signal(SIGPIPE,SIG_IGN);

#if defined(TIOCGWINSZ) && defined(SIGWINCH)
signal(SIGWINCH,getwinsz);
#endif

noop();
}

unsetsignals()
{
signal(SIGALRM,SIG_IGN);
alarm(0);
}


int myhash(FTP *ftp,unsigned int chars)
{

if (chars==0) return ftp -> counter=0;

ftp -> counter += chars;

if (hashmode)
{


fprintf(stderr,"%10u bytes transfered\r",ftp -> counter);
fflush(stderr);
}

if (!lastcmd)
{
noop();
alarm(0);
}
}

char *makefilename(char *f1, char *f2)
{
char *p;

if (*f2!=0)
return f2;

if ( (p=strrchr(f1,'/'))!=NULL)
return p+1;
return f1;
}

redir(char *cmdline)
{
char *p=cmdline;
FtpString result;
char *r=result;

for ( ; *p ; p++ , r++ )
{
if ( *p == '\\' )
{
*r = * ++ p ;
continue;
}

if ( *p == '>' || *p == '<' )
{
FtpString filename;
char *q=filename;
char c = *p;

for (p++;isspace(*p)&&*p!=0;p++);
if (*p=='"')
{
for (p++; *p!='"' && *p!=0 ; p++,q++) *q = *p;
if (*p!='"') p++;
}
else
for (; !isspace(*p) && *p!=0 ; p++,q++) *q = *p;

*q=0;

if ( c == '>' )
output(filename);
else
input(filename);
}
*r = *p;
}
*r=0;
strcpy(cmdline,result);
}

int itty = -1,otty = -1;
FILE *is=NULL, *os=NULL;


input(char *filename)
{

if ((is=Ftpfopen(filename,"r"))==NULL)
{
perror(filename);
return;
}

fflush(stdin);
itty=dup(0);
close(0);
dup2(fileno(is),0);

}

output(char *filename)
{

if ((os=Ftpfopen(filename,"w"))==NULL)
{
perror(filename);
return;
}

fflush(stdout);
otty=dup(1);
close(1);
dup2(fileno(os),1);
}

redirback()
{

if (itty!= -1)
{
fflush(stdin);
close(0);
Ftpfclose(is);
dup2(itty,0);
is=NULL;
itty = -1;
}

if (otty!= -1)
{
fflush(stdout);
close(1);
Ftpfclose(os);
dup2(otty,1);
os=NULL;
otty = -1;
}
}


batch(char *filename)
{
FILE *fp;
FtpString tmp;

if ((fp=fopen(filename,"r"))!=NULL)
{

while ( fgets(tmp, sizeof tmp, fp) != NULL)
{
tmp[strlen(tmp)-1]=0;
execute(tmp);
if (tmp[0]) gl_histadd(tmp);
}
fclose(fp);
}
}

quit(int code)
{
if (ifalias("autoquit"))
execute("autoquit");
exit(code);
}

#if defined(TIOCGWINSZ) && defined(SIGWINCH)

void getwinsz()
{
struct winsize win;

ioctl(0,TIOCGWINSZ,&win);

winsize = win.ws_col;
if (winsize==0) winsize=80;
gl_setwidth(winsize);
gl_redraw_r();
}
#endif


load_compctl()
{
/* Load command(s) */

static char *sets[] = {
"frame","timeout","sleep","debug","bin","try","hash",
"port","prompt","rest","noopinterval","nooptimeout","user",
"wwwgateway","wwwport",
NULL};
char **p;

CMDS *xcmd = &cmds[0];

ALIAS *a=firstalias;

while (xcmd->cmd != NULL) load_key(xcmd->cmd),xcmd++;

/* Load alias(es) */

while (a!=NULL) load_key(a->name),a=a->next;

for (p=sets;*p!=NULL;p++)
{
FtpString tmp;

strcpy(tmp,"set ");
strcat(tmp,*p);
load_key(tmp);
}

load_hosts();

}

load_hosts()
{
FILE *in=fopen(gethostsname(),"r");
FtpString s,ss;

if (in==NULL) return;

while ( fgets(s,sizeof s,in)!=NULL)
{
s[strlen(s)-1]=0;
strcpy(ss,"open ");
strcat(ss,s);
load_key(ss);
}

fclose(in);
}

log_traffic ( char *hf, char *ht, char *ff, char *ft, int counter)


{
time_t t=time((time_t *)0);
struct tm *lt=localtime(&t);

FtpString hostname,txt;
int fd=open(LOG_TRAFFIC_FILE,O_WRONLY|O_CREAT|O_APPEND);

if (fd==-1) return;

while ((status=flock(fd,LOCK_EX)==-1) && errno==EWOULDBLOCK);

if (status==-1) return;

gethostname(hostname, sizeof hostname);


sprintf(txt,"%02d:%02d:%02d %02d:%02d:%02d %s@%s %s:%s -> %s:%s %d bytes\n",
lt->tm_mday,lt->tm_mon+1,lt->tm_year+1900,
lt->tm_hour,lt->tm_min,lt->tm_sec,
getpwuid(getuid())->pw_name,hostname, hf, ff, ht, ft, counter) ;

write(fd,txt,strlen(txt));

close(fd);
}


\End\Of\Shar\
else
echo "will not over write ./utils/uftp.c"
fi
if `test ! -s ./utils/uftp.h`
then
echo "writing ./utils/uftp.h"
cat > ./utils/uftp.h << '\End\Of\Shar\'
#include <sys/types.h>
#include <FtpLibrary.h>
#include <strings.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <arpa/telnet.h>
#include <sys/ioctl.h>
#include <pwd.h>
#include <errno.h>
#include <glob.h>
#include "getline.h"
#include "list.h"

#define SYSTEMRC "/usr/share/etc/uftprc"
#define LINK ftp[frame]
#define NFRAMES 10
#define TIME(proc) settimer(), status = proc , showtimer(), status
#define ARGS char *w1,char *w2,char *w3,char *w4,char *w5,char *w6
#define NULLARGS "","","","","",""
#define log(x) FtpLog("uftp",x)
#define LOG_TRAFFIC_FILE "/usr/share/etc/uftp.log"

#ifdef MIN
#undef MIN
#endif

#define MIN(x,y) ((x)<(y)?(x):(y))
typedef struct
{
FtpString host;
FtpString user;
FtpString pass;
FtpString pwd;
int lock;
} LINKINFO;

typedef struct
{
char *cmd;
int (*func)();
int need;
char *help;
} CMDS;

typedef struct _alias
{
FtpString name,str;
struct _alias *next;
} ALIAS;

typedef struct _token
{
FtpString word;
struct _token *next;
struct _token *shift;
} TOKEN;

extern ALIAS *firstalias;
extern FTP *ftp[NFRAMES];
extern LINKINFO iftp[NFRAMES];
extern LIST *hosts;
extern int frame;
extern int lastcmd;
extern int trymode;
extern int hashmode;
extern int restmode;
extern int sleeptime;
extern int winsize;
extern int interactive;
extern time_t noopinterval,nooptimeout;
extern CMDS cmds[];
extern int status;
extern FtpString prompt;
extern FtpString defaultuser;
extern jmp_buf start;

char *word(char *,int);
char *readline(char *);

#ifndef _AIX
char *getpass(char *);
#endif

char *getrcname();
char *getaliasrcname();
char *getsetsrcname();
char *gethostsname();
char *makestr();
char *expandalias(char *str);
char *getprompt();
char *makefilename(char *,char *);
char *getalias(char *);

int tab_hook(char *,int,int*);
int compctl_hook(char *,int,int*);

int setenv(char *, char*);
int unsetenv(char *);
int printenv();
void getwinsz();

void intr(int);
void noop();
int setargs(char *);

int myhash(FTP *,unsigned int);
STATUS my_error(FTP *, int, char *);


extern FtpString www_gateway;
extern int www_port;


\End\Of\Shar\
else
echo "will not over write ./utils/uftp.h"
fi
if `test ! -s ./utils/uftp.man`
then
echo "writing ./utils/uftp.man"
cat > ./utils/uftp.man << '\End\Of\Shar\'
.TH \fBuftp\fR 1
.SH Name
uftp \- universal file transfer program
.SH Syntax
\fBuftp\fR
.PP
\fBuftp alias_or_command [args]\fR
.PP
\fBuftp hostname\fR

.SH Description


The uftp is user interactive and non-interactive program to the ARPANET File Transfer Protocol (RFC959).
The uftp allows user to transfer files, group of files, threes of directories in foreground and background modes. uftp runs on the client host.


.SH Basic features

Auto retrying of connection to remote node until it is succeeded.
.PP
Automatic reconnection with continue to transfer if the connection was broken.
.PP
Several sessions (frames) simulteniously. Dynamically switching between them.
.PP
Setup commands, which are executed after "open" and "cd" commands. (aliases autologin & autocd )
.PP
Cleaning timeout on the remote server (by default switched off).
.PP
The user can setup a lot of system parameters, like timeouts, reconnect delays, default port number,
automatic binary mode, automatic "hash" mode and interval to clean timeouts on FTP server. (by default it is turned off)
.PP
User can setup the prompt with the descriptions of local and remote directories, full or short site name,
time, frame number,
remote user's name, port number, timeout, process identification.
.PP
Several commands in one line (separated by ';').
.PP
Aliases with arguments, which may contain few commands separated by ';'.
.PP
Redirection input/output irrespective of context or/and command.
.PP
The local files are libftp-files, which split on local filesand pipes. This particular file specification
can be used in any context, including for file names of redirection input/output streams.
.PP
Any command may be executed in background mode, though the current frame is not dropped out and user can continue
his work.
.PP
Creation of alias described the current frame, and save all exist aliases to personal
automatic startup file, which is differ from startup file. This file user can make himself.
.PP
Completion mechanism which predefined to apply existing commands aliases and known hosts and can be modified by user (using command compctl).
.PP
.PP
.PP
Automatic file-search using archie-server that.
.PP
Receiving files thru HTTP-proxyserver.

.SH Environment description

Command line mode supports all edit key bindings and completion mechanism. (uftp using public domain getline library).
Before each command user have the prompt with description of current frame.
If debug mode is enabled user see the protocol between uftp and ftp-daemon (ftpd).

.SH Commands


.IP \fBcompctl\fR 10
[arg1] [arg2] [arg3]

This function gives possibility to manage completion of commands typed by user
in command line. Without any argument last one prints list of already
existed command in compctl-cache. Otherwise you push new one to stack. For
example you push to lines in your startup files such as "compctl set login albert" and "compctl set login manager", if later you press <TAB> after typing "login" you got list with two words, and after pressing "a" or "m" and <TAB> you will complete one from them.


.IP \fBconnect\fR 10
[host-name]

Connect to remote site.

.IP \fBopen\fR 10
[host-name] [user-name] [password] [directory]

Makes connection to remote site, sent login, password and change directory.
If the "try" option is set an attempt to connect will be forced until success.

.IP \fBftp\fR 10
[hostname] [directory]

Anonymous connection to ftp-site.

.IP \fBreopen\fR 10

Reopen broken frame.

.IP \fBpreconnect\fR 10
[host-name] [user-name] [password] [directory]

Makes data for future connection in the cache. If after that you will do some
transfer operation like get or put .... connection will be maded just before
transfer, it can be usable if you don't have access to server right now and
want to keep task for execution at time when it will be possible.

.IP \fBclose\fR 10

Close the current connection.

.IP \fBquit\fR 10
.IP \fBexit\fR 10

Quit from uftp (You can press Control-D)

.IP \fBlist\fR 10

Description list of all frames.

.IP \fBuser\fR 10
[user-name] [password]

Send user's name to site, automatically require password if needed.

.IP \fBpass\fR 10
[password]

Specify user's password.

.IP \fBbin\fR 10

Set binary transfer mode.

.IP \fBascii\fR 10

Set ASCII transfer mode.

.IP \fBcd\fR 10
directory_name

Change the current directory on remote site.

.IP \fBacd\fR 10
[directory_name]

Archie searching by specified pattern with subsequent connection to desired point.
Maximum number of possible points is 20.
Afterwards user can select any point. If user don't specify "directory_name",
last search buffer is displayed for selection, if this buffer is not empty.

.IP \fBlcd\fR 10
directory_name

Local change directory. User can use meta-characters.

.IP \fBabort\fR 10

Abort execute of last procedure with server.

.IP \fBmkdir\fR 10
directory_name

Create new directory on the server.

.IP \fBrm\fR 10
filename_or_pattern

Remove specified file(s) on the server.

.IP \fBmv\fR 10
old_filename new_filename

Move file on the server.

.IP \fBdir\fR 10
[keys] [filename_spec] ....

Make long list of specified file(s) with date, size, etc...

.IP \fBls\fR 10
[keys] [filename_spec] ....

Make short list of specified file(s).

.IP \fBget\fR 10
remote_filename [local_filename_or_directory]

Receive the file from the server to local file system (only one file!).
If option "rest" is turn on then transfer starts from the end of local file.

.IP \fBpget\fR 10
HTTP-file-specification

Receive the file using HTTPD as gateway for transferring. Using that you can transfer files (ftp://hostname/path/file) or other objects (for example: http://www.cern.ch). For setting http-server and his port will use "set wwwgateway" and "set wwwport"

.IP \fBmget\fR 10
[remote_filename] [local_directory]

Receive many files from the server to local file system. If you run this command without arguments you will transfer all files in that directory including subdirectories and his files.

.IP \fBaget\fR 10
[pattern_for_archie]

Getting the file, which need to find via archie service. See also "acd" description.

.IP \fBaaget\fR 10
[pattern_for_archie]

Getting the file, which need to find via archie service and retrieving it
from any host which accessible. If connection to server will broke then
reconnect to another server or some if only one and continue to transfer
from last point.

.IP \fBput\fR 10
local_filename [remote_filename]

Put one file to server.

.IP \fBmput\fR 10
local_filename(s)

Put specified file(s) to server.

.IP \fBcopy\fR 10
[frame/]filename [frame/]filename

Copy one file from first frame to second. If the frame number is not specified
then use current frame number. Transfer operation executes via libftp cache.


.IP \fBccopy\fR 10
[frame/]filename [frame/]filename

Copy one file from first frame to second. If the frame number is not specified
then used current frame number. Transfer operation executes via leased line
between two servers cache.


.IP \fBcat\fR 10
filename

Display context of specified file on screen. For display file with
page-scrolling you can define once command for example "less" as "alias less get $1 |less".

.IP \fBpage\fR 10

The same as cat, but with using of pager. Name of pager specified in environment variable
PAGER or "more" by default. (It's just predefined possibility described bellow)

.IP \fBbg\fR 10
any_command

any_command &

Run any command in background mode. Default output is redirected to
/tmp/uftp-<user_name>/XXXXXX file.

.IP \fBarchie\fR 10
[pattern]

Archie search. In case if argument are omitted, reprint last search. (same for acd and aget)

.IP \fBdup\fR 10

Create new frame as current.

.IP \fBquote\fR 10

Send raw command to server. If option "glassmode" is set then all non-recognized
commands send to server as raw also.

.IP \fBhelp\fR 10
[command]

Print brief help or help for specified command.

.IP \fBsetenv\fR 10
variable_name value

Setup system's environment variable.

.IP \fBunsetenv\fR 10
variable_name

Remove system's environment variable.

.IP \fBenv\fR 10

Print system's environment variables.

.IP \fBalias\fR 10
alias_name alias_string

Makes new alias, if the alias string uftp contains string like $1, $2, $* then
it will be replaced by argument to alias. If this sequences in alias is not found, then
all existing alias's arguments will append to end of alias call string. User can insert to alias
string like \\\> \\\< for future redirect input/output. Quotes ' and " can be used
also.

.IP \fBunalias\fR 10
alias_name

Remove specified alias.

.IP \fBmkalias\fR 10
alias_name

Makes new alias, which user can use in future for login to this point again.
See also "savealiases"

.IP \fBsavealiases\fR 10

Save all aliases in startup file.


.SH Libftp file specification

All local files interpret as libftp's files. Libftp responds to two types of files such
as local file and program


pipes. All files can be described as next syntax:

|string - interprets string as shell command, which must be \


executed with appropriate input/output for file. It depends where
this file is specified.

*STDIN*, *STDOUT*, *STDERR* or char '-' - opened streams.

anything - local file name.

.SH String syntax

The strings starting from char '!' interpret as shell command.
The strings or aliases containing one or few char ';' will be executed as a chain commands.
The chains of characters between " or ' interpret as one set without syntax resolving.
In any command string user can redirect input or/and output
using char > and < . For the complex file name it must quoted by ' or ".

Examples:

dir >filename

cat filename >'|mail -s "my files" fi...@hostname.domain'

dir -R etc bin >"|gzip >result.gz"

put - < "|finger @hostname" newfile.finger


.SH Options (command set)

.IP \fBset\fR


Show all current settings.

.IP \fBset\fR
frame <frame_number>

Switch to another frame. You can also switch by insert on frame number to the
begin of command line.

.IP \fBset\fR
timeout <seconds>

Set timeout for send/receive operations.

.IP \fBset\fR
noop <secs>

Set interval for send NOOP command to each connected server for cleaning
timeouts.

.IP \fBset\fR
nooptimeout <seconds>

Set timeout for NOOP operation.

.IP \fBset\fR
sleep <secs>

Set pause interval between transfer attempts.

.IP \fBset\fR
debug <y|n>

Enable or disable protocol debug output

.IP \fBset\fR
try <y|n>

Enable or disable retrys after lost peer.

.IP \fBset\fR
hash <y|n>

Enable or disable trace for the transfer operations.

.IP \fBset\fR
restore <y|n>

Enable or disable default transfer starting from end of file.

.IP \fBset\fR
bin <y|n>

Automatic binary mode.

.IP \fBset\fR
prompt <prompt_string>

Set the prompt. Prompt is a string, which may contain %<char>
or ^<char> combitanions with the next embodies:

%H, %h - full and short remote host names
%M, %m - full and short local host names
%u - remote user's name
%d - remote current directory
%D - local current directory
%f - number of current frame
%p - the ftp's port number
%t - timeout
%T - current time
%P - uftp process id
%% - character %
^<char>- control character
%^ - character ^


.IP \fBset\fR
port <number>

Set default FTP's port for next sessions.

.IP \fBset\fR
user <user_name>

Set default user's name.

.IP \fBset\fR
wwwgateway <host_name>

Set www proxy gateway name or it's address.

.IP \fBset\fR
wwwport <port_number>

Set port number for http-proxy server.

.IP \fBsavesets\fR

Save all sets to startup file.

.SH Startup file

User can modify his startup file created automatically. This file may
contain some uftp's commands separated by new-line. The name of this file is ~/.uftprc.
The file ~/.uftp_aliases ~/.uftp_sets is created automatically by uftp's command "savealias" or "savesets",
so it is not needed to edit handy.
The file ~/.uftp_hosts can contain list of hosts for uftp's command which have host's name as argument.

.SH Author of uftp and libftp

Oleg Orel

Europien Organization for Nuclear Research
Geneva, SWITZERLAND

E-mail: or...@dxunk1.cern.ch

.SH See also (and compare)

\fBncftp\fR (1), \fBftp\fR (1), \fBftpd\fR (8)
\End\Of\Shar\
else
echo "will not over write ./utils/uftp.man"
fi
echo "Finished archive 4 of 8"
exit


0 new messages