static char const rcsid[] = "@(#)$Id: swbsdz.c,v 1.1 2001/05/21 04:09:49 jgibbons Exp $"; /* ** CONFIDENTIAL & PROPRIETARY INFORMATION ** Distribution to Authorized Personnel Only ** Copyright (c) 2001 Protogate, Inc. ** All Rights Reserved ** ** This document contains confidential and proprietary information of ** Protogate, Inc, ("Protogate") and is protected by copyright, trade secret ** and other state and federal laws. The possession or receipt of this ** information does not convey any right to disclose its contents, reproduce ** it, or use, or license the use, for manufacture or sale, the information ** or anything described therein. Any use, disclosure, or reproduction ** without Protogate's prior written permission is strictly prohibited. ** ** Software and Technical Data Rights ** ** Protogate software products and related documentation will be furnished ** hereunder with "Restricted Rights" in accordance with: ** ** A. Subparagraph (c)(1)(ii) of the clause entitled Rights in Technical Data ** and Computer Software (OCT 1988) located at DFARS 252.227-7013; or ** ** B. Subparagraph (c)(2) of the clause entitled Commercial Computer Software - ** Restricted Rights (JUN 1987) located at FAR 52.227.19. */ /**************************************************************************** * * FILE: swbsdz.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 implements one of 2 behaviors, * depending on the value of the first argument: it either * compresses all the data it receives from the Message Switch, * returning the compressed data to the Message Switch, or it * uncompresses all the data it receives from the Message Switch, * returning the uncompressed data to the Message Switch. * If the first argument is 0 it compresses, else it * uncompresses. * * 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:swbsdz~0~maxbufsize~idstring (for compression) * prog:swbsdz~1~maxbufsize~idstring (for uncompression) * * The real first argument (the file descriptor of the pipe, * which is immediately after the swbsdz program name in the * call to this program) is not included in the endpoint * specification because it is inserted by the Message Switch. * * The second argument is either 0 or not; if it is zero then * this program acts as a data compressor, else it acts as a * data uncompressor. * * The third argument is taken as the maximum size of the * resulting data, in bytes. * * The fourth argument is ignored by this program, but can be * used to differentiate between several compression streams, * by choosing a different idstring for each stream. This * takes advantage of the fact that the Message Switch assumes * that each differing endpoint string should define a * different endpoint. * * CALLING SEQUENCE: * arg0: swbsdz * arg1: the file descriptor of a pipe which connects to the * Message Switch. * arg2: 0=compressor, else=decompressor * arg3: Maximum resulting buffer size, in bytes * arg4: id string (unused) * * REVISION HISTORY: * * Date Programmer Description * ------- ------------ --------------- * 21may01 Jeff Gibbons Original creation. * *****************************************************************************/ /* Include files */ #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/time.h> #include <string.h> #include <zlib.h> /* Defines */ #define OK 0 /* Typedefs */ /* Global Data */ /* Local Function Prototypes */ /* Local Static Data */ static unsigned char rcv_message[ 16384 ]; static unsigned char snd_message[ 16512 ]; /* Extern Data Declarations */ /* Extern Function Prototypes */ /* Function Definitions */ /**************************************************************************** * * PROGRAM: main.c * * DESCRIPTION: Main entry point for the swbsdz program. * * CALLING SEQUENCE: described above in file header. * * REVISION HISTORY: * * Date Programmer Description * ------- ------------ --------------- * 21may01 Jeff Gibbons Original creation. * *****************************************************************************/ int main( int argc, char **argv ) { int iFd; int iBehavior; int iMaxSize; #define RCV_MAXSIZE (iMaxSize + 128) #define SND_MAXSIZE (iMaxSize + 256) uLong uRcvLen; uLong uSndLen; int iResult; fd_set sReadFds; Bytef *rcv_message; Bytef *snd_message; static const char* myVersion = ZLIB_VERSION; if ( argc < 4 ) { printf( "swbsdz: called incorrectly: calling sequence should be:\n" ); printf( " swbsdz \"filedescriptor\" \"0 or 1\" " " \"max result size\" \"ident string\"\n" ); exit( 1 ); } #ifdef DEBUG else { int ii; printf( "swbsdz debug: Initializing with these arguments:\n" ); for ( ii = 0; ii < argc; ii++ ) printf( " arg%d: %s.\n", ii, argv[ii] ); printf( "\n" ); } #endif if (zlibVersion()[0] != myVersion[0]) /* major number difference */ { printf( "swbsdz: ERROR: incompatible zlib version.\n" ); printf( "swbsdz: ERROR: compiled with %s, using %s.\n", ZLIB_VERSION, zlibVersion() ); exit(1); } else if ( strcmp(zlibVersion(), ZLIB_VERSION) != 0 ) /* minor # diff */ { printf( "swbsdz: WARNING: different zlib version.\n" ); printf( "swbsdz: WARNING: compiled with %s, using %s.\n", ZLIB_VERSION, zlibVersion() ); } iFd = atoi( argv[ 1 ] ); iBehavior = atoi( argv[ 2 ] ); iMaxSize = atoi( argv[ 3 ] ); if ( 65536 < iMaxSize ) { printf( "swbsdz: WARNING: maxsize is too large; limiting to 65535.\n" ); iMaxSize = 65535; } rcv_message = (Bytef *)malloc( iMaxSize + 128 ); if ( ( NULL == ( rcv_message = (Bytef *)malloc( RCV_MAXSIZE ) ) ) || ( NULL == ( snd_message = (Bytef *)malloc( SND_MAXSIZE ) ) ) ) { printf( "swbsdz: ERROR: malloc failure.\n" ); close(iFd); exit(1); } FD_ZERO( &sReadFds ); while ( 1 ) { uSndLen = iMaxSize; FD_SET( iFd, &sReadFds ); select( iFd + 1, &sReadFds, NULL, NULL, NULL ); if ( 0 > ( uRcvLen = read( iFd, rcv_message, RCV_MAXSIZE ) )) { perror( "\nERROR: swbsdz failed reading pipe: " ); printf( "swbsdz: ERROR: failed reading pipe, errno %d.\n", errno ); printf( "swbsdz: ERROR: (behavior=%s size=%s id=%s err=%d).\n", argv[2], argv[3], argv[4], iResult ); } /* if arg2==0 (compressing was requested) */ else if ( ( 0 == iBehavior ) && ( Z_OK > ( iResult = compress( snd_message, &uSndLen, (const Bytef *)rcv_message, uRcvLen ) ) ) || ( 0 != iBehavior ) && ( Z_OK > ( iResult = uncompress( snd_message, &uSndLen, (const Bytef *)rcv_message, uRcvLen ) ) ) ) { printf( "swbsdz: ERROR: comp/uncomp failed (bhv=%s size=%s id=%s err=%d).\n", argv[2], argv[3], argv[4], iResult ); /* compression or uncompression failed; send unaltered data */ if ( iMaxSize < uRcvLen ) { uRcvLen = iMaxSize; } if ( uRcvLen != write( iFd, rcv_message, (int)uRcvLen ) ) { perror( "\nERROR: swbsdz failed writing pipe: " ); printf( "swbsdz: ERROR: failed writing pipe, errno %d.\n", errno ); printf( "swbsdz: ERROR: (behavior=%s size=%s id=%s err=%d).\n", argv[2], argv[3], argv[4], iResult ); } } else if ( uSndLen != write( iFd, snd_message, (int)uSndLen ) ) { perror( "\nERROR: swbsdz failed writing pipe: " ); printf( "swbsdz: ERROR: failed writing pipe, errno %d.\n", errno ); printf( "swbsdz: ERROR: (behavior=%s size=%s id=%s err=%d).\n", argv[2], argv[3], argv[4], iResult ); } } close(iFd); exit(0); }