Article 12650 of alt.sources:
Newsgroups: alt.sources
Path: nntpd.lkg.dec.com!pa.dec.com!news1.digital.com!nntp-hub2.barrnet.net!newsfeed.internetmci.com!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 5)
X-Nntp-Posting-Host: dxunk1.cern.ch
Message-ID: <DBxCIJ.33E@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:30 GMT
Lines: 2349

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

/*
	$Log: FtpData.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.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;
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpDebug.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: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)
{
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpFilenameChecker.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: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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpFull.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.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;
  String 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 ( String source ,
		       String host ,
		       String user ,
		       String passwd ,
		       String file)

{
  char *in,*out;
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpGetHost.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 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"



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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpGood.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 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 ./FtpIO.c`
then
echo "writing ./FtpIO.c"
cat > ./FtpIO.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpIO.c,v 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpIO.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.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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpInit.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"

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 ./FtpLogin.c`
then
echo "writing ./FtpLogin.c"
cat > ./FtpLogin.c << '\End\Of\Shar\'
static char rcsid[] = "$Id: FtpLogin.c,v 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpLogin.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 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpMessage.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"


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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpMove.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 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpOpenDir.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 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)
{
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpPasv.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  exist
ing  programs.
Commercial  usage is  also  possible  with  participation of it's author.



*/

#include "FtpLibrary.h"


char * FtpPasv (FTP *ftp)
{
  char *msg;
  static String 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)
{
  
  String PORT;

  strcpy(PORT,FtpPasv(ftp1));

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

STATUS FtpPassiveTransfer(FTP *ftp1, FTP *ftp2, char *f1, char *f2)
{
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpPort.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 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)
{
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpPwd.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 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)
{
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpRetr.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 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpSize.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"

int FtpSize(FTP * con, char *filename)
{
  String 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 4.0 1995/07/11 07:00:26 orel Exp $";

/*
	$Log: FtpStat.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 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)
{
  String 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 )
{
  String 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)
{
  String 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)
{
  String 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)
{
  String 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 5 of 6"
exit


--
``


