static char const rcsid[] =
"@(#)$Id: swbsdftp.c,v 1.3 2000/06/25 04:49:46 jgibbons Exp $";
/*
** Copyright (c) 2000 Relcast Engineering
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
*/
/****************************************************************************
*
* FILE: swbsdftp.c
*
* DESCRIPTION: This file implements an example external program for use
* with the Message Switch, as configured by the "prog:" keyword
* in switch.cfg. This program sends all the data it receives
* from the Message Switch to an FTP server, creating a sequence
* of files in a specified directory there. The filenames
* are of a form specified in argument 6, which is expected to
* contain a string with a "printf"-style formatting code
* embedded in it; that code will be transformed into a sequence
* of increasing digits, so that each filename is unique.
* For example, a 6th argument of "ftp%d" would result in a
* sequence of filenames "ftp1", "ftp2", "ftp3", etc.
*
* To specify this program as an endpoint for switch
* specifications in the switch.cfg Message Switch configuration
* file, the endpoint should have a format like this:
*
* prog:swbsdftp~192.168.135.22~anonymous~jgibbons~incoming~ftp%d
*
* The first argument (the file descriptor of the pipe, which
* is immediately after the swbsdftp program name in the call to
* this program) is not included in the endpoint specification
* because it is inserted by the Message Switch.
*
* CALLING SEQUENCE:
* arg0: swbsdftp
* arg1: the file descriptor of a pipe which connects to the
* Message Switch.
* arg2: IP address of an FTP server
* arg3: Login name on FTP server
* arg4: password on FTP server
* arg5: directory on FTP server
* arg6: destination base filename on FTP server (this basename
* should contain a "%d" or "%x" formatting specifier)
*
* REVISION HISTORY:
*
* Date Programmer Description
* ------- ------------ ---------------
* 09jun00 Jeff Gibbons Original creation.
*
*****************************************************************************/
/* Include files */
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#include <ftpio.h>
/* Defines */
#define OK 0
/* Typedefs */
/* Global Data */
unsigned char rcv_message[ 16384 ];
/* Local Function Prototypes */
/* Local Static Data */
/* Extern Data Declarations */
/* Extern Function Prototypes */
/* Function Definitions */
/****************************************************************************
*
* PROGRAM: main.c
*
* DESCRIPTION: Main entry point for the swbsdftp program.
*
* CALLING SEQUENCE: described above in file header.
*
* REVISION HISTORY:
*
* Date Programmer Description
* ------- ------------ ---------------
* 09jun00 Jeff Gibbons Original creation.
* 21jun00 Jeff Gibbons Modified to use new pipe method of communication
* with Message Switch, rather than socket.
*
*****************************************************************************/
int
main( int argc, char **argv )
{
int iTotSize;
int iFd;
int iResult;
char clientFileName[ 256 ];
int clientFileIndex = 0;
FILE *pFtpCtrl;
FILE *pFtpFile;
fd_set sReadFds;
if ( argc < 7 )
{
printf( "swbsdftp: called incorrectly: calling sequence should be:\n" );
printf( " swbsdftp \"filedescriptor\" \"machine\""
" \"username\" \"password\" \"directory\""
" \"basefilename\"\n" );
exit( 1 );
}
#ifdef DEBUG
else
{
int ii;
printf( "swbsdftp debug: Initializing with these arguments:\n" );
for ( ii = 0; ii < argc; ii++ )
printf( " arg%d: %s.\n", ii, argv[ii] );
printf( "\n" );
}
#endif
iFd = atoi( argv[ 1 ] );
FD_ZERO( &sReadFds );
while ( 1 )
{
clientFileIndex++;
clientFileIndex %= 1000000000;
/*
** The filename argument in switch.cfg should be of the form:
** "file%d.ftp" ( this program will replace the "%d" with an increasing
** sequence of digits, so each new ftp'ed file has a unique name ).
*/
sprintf( clientFileName, argv[ 6 ], clientFileIndex );
/* printf( "swbsdftp debug: writing to file: %s\n", clientFileName ); */
pFtpCtrl = pFtpFile = NULL;
FD_SET( iFd, &sReadFds );
select( iFd + 1, &sReadFds, NULL, NULL, NULL );
if ( 0 > ( iTotSize = read( iFd, &rcv_message, sizeof(rcv_message) ) ) )
{
perror( "\nERROR: swbsdftp failed reading pipe: " );
printf( "swbsdftp: failed reading Message Switch pipe, errno %d.\n",
errno );
printf( "swbsdftp: for machine: %s\n", argv[2] );
printf( "swbsdftp: username: %s\n", argv[3] );
/* don't display password */
/* printf( "swbsdftp: password: %s\n", argv[4] ); */
printf( "swbsdftp: directory: %s\n", argv[5] );
printf( "swbsdftp: basefile: %s\n", argv[6] );
}
else if ( NULL == ( pFtpCtrl = ftpLogin( argv[2],
argv[3],
argv[4],
0, 0, &iResult ) ) )
{
printf(
"swbsdftp: unable to login to %s with username %s, error %d.\n",
argv[2], argv[3], iResult );
}
else if ( OK != ( iResult = ftpChdir( pFtpCtrl, argv[5] ) ) )
{
printf( "swbsdftp: FTP chdir to ftp://%s/%s returned error %d:\n",
argv[2], argv[5], iResult );
printf( " %s\n", ftpErrString( iResult ) );
}
else if ( OK != ( iResult = ftpAscii( pFtpCtrl ) ) )
{
printf(
"swbsdftp: unable to set ftp mode to ASCII on %s, error %d:\n %s\n",
argv[2], iResult, ftpErrString( iResult ) );
}
else if ( NULL == ( pFtpFile = ftpPut( pFtpCtrl, clientFileName ) ) )
{
printf( "swbsdftp: STORE cmd on ftp://%s/%s/%s failed.\n",
argv[2], argv[5], clientFileName );
}
else
{
fwrite( rcv_message, sizeof( char ), iTotSize, pFtpFile );
}
if ( NULL != pFtpFile )
fclose( pFtpFile );
if ( NULL != pFtpCtrl )
fclose( pFtpCtrl );
}
close(iFd);
exit(0);
}