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); }