Article 12655 of alt.sources:
Newsgroups: alt.sources
Path: nntpd.lkg.dec.com!pa.dec.com!news1.digital.com!nntp-hub2.barrnet.net!nntp-sc.barrnet.net!ratatosk.yggdrasil.com!news.duke.edu!news.mathworks.com!tank.news.pipex.net!pipex!oleane!jussieu.fr!univ-lyon1.fr!swidir.switch.ch!CERN.ch!orel
From: orel@lpuds.oea.ihep.su (Oleg Orel)
Subject: libftp & uftp version 4.0 (Part 4)
X-Nntp-Posting-Host: dxunk1.cern.ch
Message-ID: <DBxCHs.2tG@news.cern.ch>
Sender: news@news.cern.ch (USENET News System)
Organization: CERN European Lab for Particle Physics
X-Newsreader: TIN [version 1.2 PL0]
Date: Tue, 18 Jul 1995 18:25:04 GMT
Lines: 1520


#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./FtpStor.c`
then
echo "writing ./FtpStor.c"
cat > ./FtpStor.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpStor.c,v 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpStor.c,v $
 * 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 FtpStor (FTP * con , char * command ,
		       char *in , char * out)
{
  FILE *i;
  char buffer[FTPBUFSIZ];
  int size;

  con->seek=0;

  if ( FtpTestFlag(con,FTP_REST) && 
      (con->seek=FtpSize(con,out))<0 )
    con->seek=0;
  
  
  if ( FtpError(FtpData(con,command,out,"w")))
    {
      if (con->seek==0) return EXIT(con,con->errno);

      con -> seek =0;
      if ( FtpError(FtpData(con,command,out,"w")) )
	return EXIT(con,con->errno);
    }
  

  if ( (i=Ftpfopen(in,"rb")) == NULL )
    return EXIT(con,LQUIT);

  if (con->seek) fseek(i,con->seek,0);
  
  
  while ( (size=read ( fileno(i) , buffer, FTPBUFSIZ ))>0) 
    FtpWriteBlock(con,buffer,size);
  
  Ftpfclose(i);
  return FtpClose(con);
}







\End\Of\Shar\
else
  echo "will not over write ./FtpStor.c"
fi
if `test ! -s ./FtpSyst.c`
then
echo "writing ./FtpSyst.c"
cat > ./FtpSyst.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpSyst.c,v 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpSyst.c,v $
 * Revision 4.0  1995/07/11  07:00:26  orel
 * Libftp Version 4.0
 *
 * Revision 3.1  1995/06/20  15:53:29  orel
 * *** empty log message ***
 *
 * Revision 3.1  1995/06/20  15:53:29  orel
 * *** empty log message ***
 *
 * Revision 3.0  1995/03/20  05:26:07  orel
 * *** empty log message ***
 *
 * Revision 1.2  1995/03/14  10:47:44  orel
 * add UNKNOWN system type
 *
 * Revision 1.2  1995/03/14  10:47:44  orel
 * add UNKNOWN system type
 *
 * Revision 1.1  1995/03/05  15:02:26  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"

char * FtpSyst(FTP * con)
{
  String tmp;
  static String tmp1;
  int i;
  
  if ( FtpSendMessage(con,"SYST") == QUIT )
    return (char *) EXIT(con,QUIT);
  if ( (i=FtpGetMessage(con,tmp)) == QUIT )
    return (char *) EXIT(con,QUIT);
  
  if ( i != 215 && i != 200 )
    strcpy(tmp1,"UNKNOWN");
  else
    strcpy(tmp1,word(tmp,2));

  con -> errno = i;
  return tmp1;
}
\End\Of\Shar\
else
  echo "will not over write ./FtpSyst.c"
fi
if `test ! -s ./FtpType.c`
then
echo "writing ./FtpType.c"
cat > ./FtpType.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpType.c,v 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpType.c,v $
 * 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 FtpType(FTP *ftp, char type)
{
  STATUS p;
  
  if ((p=FtpCommand(ftp,"TYPE %c",type,200,EOF))>0)
    ftp->mode=(int)type;
  return p;
}

  
\End\Of\Shar\
else
  echo "will not over write ./FtpType.c"
fi
if `test ! -s ./Ftp_etclib.c`
then
echo "writing ./Ftp_etclib.c"
cat > ./Ftp_etclib.c << '\End\Of\Shar\'
#include "FtpLibrary.h"

INLINE char *findspace(char *str)
{
  while ( !isspace(*str) && *str != '\0' ) str++;
  return str;
}


    
char *word(char *str, int n)
{
  String new;
  register char *p1, *p2;
  register int i;
  
  strcpy(new,str);
  
  p1=new;

  while (isspace(*p1)) p1++;

  if (n>1 )
    for (i=0;i<n-1;i++) /* Skip n-1 words */
      {
	if ((*p1=='"')||(*p1=='\'')) 
	  {
	    p1=(char *)strchr(p1+1,*p1);
	    if (p1==NULL) return "";
	    p1++;
	    while ( isspace(*p1) ) p1++;
	    continue;
	  }
	p1=findspace(p1);
	if ( *p1=='\0' ) return "";
	p1++;
	while ( isspace(*p1) ) p1++;
      }

  if ((*p1=='"')|(*p1=='\''))
    {
      p2=(char *)strchr(p1+1,*p1);
      if (p2==NULL) return p1+1;
      *p2=0;
      return p1+1;
    }
  
  if  ((p2=findspace(p1)) != NULL )
    {
      *p2=0;
      return p1;
    }
  return "";
}


\End\Of\Shar\
else
  echo "will not over write ./Ftp_etclib.c"
fi
if `test ! -s ./Ftpfopen.c`
then
echo "writing ./Ftpfopen.c"
cat > ./Ftpfopen.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: Ftpfopen.c,v 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: Ftpfopen.c,v $
 * 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  existing  programs.
Commercial  usage is  also  possible  with  participation of it's author.



*/

#include <FtpLibrary.h>

#define NFSD 256

static int fds_types[FTP_NFDS];
static int init=0;

enum {T_EMPTY=0,T_FILE,T_STREAM,T_PIPE,T_FULL};

FILE *Ftpfopen(char *filename,char *mode)
{
  FILE *fp;
  
  if (!init)
    { 
      bzero(fds_types,FTP_NFDS*sizeof(fds_types[0]));
      init=1;
    }

  if (!strcmp(filename,"*STDIN*") || (!strcmp(filename,"-") && (mode[0]=='r')) )
    {
      fds_types[fileno(stdin)]=T_STREAM;
      return stdin;
    }
  
  if (!strcmp(filename,"*STDOUT*") || (!strcmp(filename,"-") && (mode[0]=='w')))
    {
      fds_types[fileno(stdout)]=T_STREAM;
      return stdout;
    }
  
  if (strcmp(filename,"*STDERR*")==0)
    {
      fds_types[fileno(stderr)]=T_STREAM;
      return stderr;
    }
  


  if (*filename=='|') 
    {
      fp=popen(filename+1,mode);
      if (fp==NULL) return fp;
      fds_types[fileno(fp)]=T_PIPE;
      return fp;
    }

  fp=fopen(filename,mode);
  if (fp==NULL) return fp;
  fds_types[fileno(fp)]=T_FILE;
  return fp;
  
}

int Ftpfclose(FILE *fp)
{

  if (!init)
    { 
      bzero(fds_types,FTP_NFDS*sizeof(fds_types[0]));
      init=1;
    }

  switch (fds_types[fileno(fp)])
    {
    
    case T_FILE:
      
      return fclose(fp);
      
    case T_STREAM:

      return fflush(fp);
      
    case T_PIPE:
      
      return pclose(fp);
      
    default:

      return -1;
    }

}



\End\Of\Shar\
else
  echo "will not over write ./Ftpfopen.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>

#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>


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 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 String[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;
  String title;    /* Using for FtpLog, FtpConnect lets hostname */
  unsigned long counter; 
                   /* Using by FtpHash */
} FTP;

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


typedef struct __ftp_stat__
{
  char type;        /* Type of file dir, regular, ..... */
  int  mode;        /* Protections */
  int  inodes;
  String user;
  String group;
  unsigned long size;
  int month;
  int day;
  String time;
  String name;
  String 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(String,String,String,String,String);
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);
char   *FtpSlash(char *,char *);
#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 ! -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$";

/*
	$Log$

*/

/* 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
if `test ! -s ./doc/example.tex`
then
echo "writing ./doc/example.tex"
cat > ./doc/example.tex << '\End\Of\Shar\'
%%
%% Creator: ansic2latex (from <stdin>)
%% Date:    Tue Dec 27 16:14:26 1994
%%
\expandafter\ifx\csname indentation\endcsname\relax
\newlength{\indentation}\fi
\setlength{\indentation}{0.5em}
\begin{flushleft}
\mbox{}\\
{\em /$\ast$\hspace*{1\indentation}Include\hspace*{1\indentation}standard\hspace*{1\indentation}libftp's\hspace*{1\indentation}header\hspace*{1\indentation}$\ast$/}\mbox{}\\
\mbox{}\\
{\tt\#include} $<${\tt FtpLibrary.h}$>$ \mbox{}\\
\mbox{}\\
\mbox{}\\
main({\bf int\/} argc, {\bf char\/} $\ast$argv[])\mbox{}\\
\{\mbox{}\\
\mbox{}\\
\hspace*{2\indentation}FILE $\ast$input,$\ast$output;\mbox{}\\
\hspace*{2\indentation}{\bf int\/} c;\mbox{}\\
\hspace*{2\indentation}\mbox{}\\
\mbox{}\\
\hspace*{2\indentation}{\bf if\/} (argc$<$3)\mbox{}\\
\hspace*{4\indentation}exit(fprintf(stderr,{\tt "Usage: \%s input-file output-file$\backslash$n"},argv[0]));\mbox{}\\
\mbox{}\\
\hspace*{2\indentation}FtplibDebug(yes);\mbox{}\\
\hspace*{2\indentation}\mbox{}\\
\hspace*{2\indentation}{\bf if\/} ((input=Ftpfopen(argv[1],{\tt "r"}))==NULL)\mbox{}\\
\hspace*{4\indentation}\{\mbox{}\\
\hspace*{6\indentation}perror(argv[1]);\mbox{}\\
\hspace*{6\indentation}exit(1);\mbox{}\\
\hspace*{4\indentation}\}\mbox{}\\
\hspace*{2\indentation}\mbox{}\\
\hspace*{2\indentation}{\bf if\/} ((output=Ftpfopen(argv[2],{\tt "w"}))==NULL)\mbox{}\\
\hspace*{4\indentation}\{\mbox{}\\
\hspace*{6\indentation}perror(argv[2]);\mbox{}\\
\hspace*{6\indentation}exit(1);\mbox{}\\
\hspace*{4\indentation}\}\mbox{}\\
\hspace*{2\indentation}\mbox{}\\
\hspace*{2\indentation}{\bf while\/} ( (c=getc(input)) $\neq$ EOF \&\&  (putc(c,output)$\neq$EOF) );\mbox{}\\
\mbox{}\\
\hspace*{2\indentation}{\bf if\/} (ferror(input))\mbox{}\\
\hspace*{4\indentation}\{\mbox{}\\
\hspace*{6\indentation}perror(argv[1]);\mbox{}\\
\hspace*{6\indentation}exit(1);\mbox{}\\
\hspace*{4\indentation}\}\mbox{}\\
\hspace*{2\indentation}\mbox{}\\
\hspace*{2\indentation}{\bf if\/} (ferror(output))\mbox{}\\
\hspace*{4\indentation}\{\mbox{}\\
\hspace*{6\indentation}perror(argv[1]);\mbox{}\\
\hspace*{6\indentation}exit(1);\mbox{}\\
\hspace*{4\indentation}\}\mbox{}\\
\mbox{}\\
\hspace*{2\indentation}Ftpfclose(input);\mbox{}\\
\hspace*{2\indentation}Ftpfclose(output);\mbox{}\\
\mbox{}\\
\hspace*{2\indentation}exit(0);\mbox{}\\
\hspace*{2\indentation}\mbox{}\\
\}\mbox{}\\
\end{flushleft}
\End\Of\Shar\
else
  echo "will not over write ./doc/example.tex"
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}}
\author{Oleg Orel}
\date{\today}
\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.

\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{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{FREE}(data)}{Full 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}

\subsection{Libftp's file specification}

All files wich must be interprets as local interprets as libftp's files. 
Libftp responds to three types of files such
 as local file, ftp 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 retransfer 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 retransfer 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 hardlers 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{String \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}.

\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{String \toindex{host}}{Host which file is located}

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


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

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{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{String \toindex{user}}{Owner's name of this file}

\tc{String \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{String \toindex{time}}{Time of creation file in string format}

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

\tc{FTP\_STAT *\toindex{next}}{Next one structure}



\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 precopying 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)}
{ Creats and opens file named \ts{filename} for writing on server}

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

\ttt{\toindex{FtpOpenDir}(FTP~*, char~*files)}
{
  Creats 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 ignories 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 ignories 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{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~*patern,FTP\_STAT **stat\_list)} 
{Get information about files specified by ``patern''. This function is pareser
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
diferent 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}

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

\ttt{char *\toindex{FtpSyst}}{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 *)}
{  
Clode file opened by FtpFullOpen.
}

\ttt{STATUS \toindex{FtpFullSyntax}(String source,String host,String user,String password,String 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}(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}


\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 4 of 6"
exit

--
``


