Code:
#include "tcputil.h"
int Connect( char* szHostName, char* szServName )
{
SOCKADDR_IN sockAddr;
LPHOSTENT sockHost;
LPSERVENT sockServ;
int nSockClient=0;
int nPortNo=0;
int nSockLen=0;
char* szAddr = NULL;
if( !szServName )
szServName = szHostName;
/* Retrieve IP address */
if( !(sockHost=gethostbyname( szHostName )) )
return -1;
/* If port name specified then convert it into a port number */
nPortNo = atoi(szServName);
if (nPortNo == 0)
{
if( !(sockServ=getservbyname(szServName, "tcp")) )
return -2;
/* Byte ordering */
nPortNo = htons( sockServ->s_port );
}
else
{
/* Byte ordering */
nPortNo = htons( nPortNo );
}
/* Convert to network address */
memset( &sockAddr, 0, sizeof(sockAddr) );
memcpy( &sockAddr.sin_addr.s_addr, sockHost->h_addr, sockHost->h_length );
szAddr = inet_ntoa( sockAddr.sin_addr );
sockAddr.sin_family = sockHost->h_addrtype;
sockAddr.sin_addr.s_addr = inet_addr( szAddr );
sockAddr.sin_port = htons(nPortNo);
/* Log the server's address */
/* SysLog( "IpAddr[%s] Port[%d]", szAddr, nPortNo);
*/
/* create a socket stream */
if( (nSockClient = socket( AF_INET, SOCK_STREAM, 0 )) < 0 )
return -3;
nSockLen = sizeof(sockAddr);
if( connect( nSockClient, (LPSOCKADDR) &sockAddr, nSockLen ) < 0 ) {
shutdown( nSockClient, 2 );
close( nSockClient );
return -4;
}
return nSockClient;
}
int CreateListener( char* szServName )
{
SOCKADDR_IN sockAddr;
SOCKADDR_IN sockClient;
LPSERVENT sockServ;
LPHOSTENT sockHost;
USHORT nPortNo = 0;
int nSockListen = 0;
int nSockLen = 0;
int nCtr = 0;
char hostName[STRLEN] = "";
/* Get the host name */
if( !szServName ) {
gethostname( hostName, sizeof(hostName) );
if( !(sockHost = gethostbyname(hostName)) )
return (-1);
szServName = hostName;
}
/* Get the port number assigned to atm_server */
if( !(sockServ = getservbyname(szServName, "tcp")) )
return (-1);
/* Create socket */
if( (nSockListen = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
return -1;
/* Convert port number to short */
nPortNo = sockServ->s_port ;
printf( "BIND on Port Number [%d]\n", nPortNo );
/* Rebind until port is available */
while( 1 ) {
bzero( (char*) &sockAddr, sizeof(sockAddr) );
sockAddr.sin_addr.s_addr = htonl( INADDR_ANY );
sockAddr.sin_family = AF_INET;
sockAddr.sin_port = nPortNo;
nSockLen = sizeof(sockAddr);
if( !bind(nSockListen, (LPSOCKADDR) &sockAddr, nSockLen ) )
break;
else {
if( nCtr > MAX_RETRY ) {
shutdown( nSockListen, 2 );
close( nSockListen );
return (-1);
}
/* Increment portno and retries */
nPortNo++;
nCtr++;
printf( "REBINDING[%d]...", nPortNo );
}
}
/* Listen for client connections */
if( listen(nSockListen, MAX_LISTEN) < 0 ) {
shutdown( nSockListen, 2 );
close( nSockListen );
return (-1);
}
return( nSockListen );
}
char* GetPeerName( int nSock )
{
SOCKADDR sockAddr;
LPSOCKADDR_IN lpSockAddr = (LPSOCKADDR_IN)&sockAddr;
LPHOSTENT lpHostEnt = NULL;
unsigned long nSize = sizeof(SOCKADDR);
/* get the peer name */
if( getpeername(nSock, &sockAddr, &nSize) < 0 )
return( NULL );
if( !(lpHostEnt=gethostbyaddr((char*)&lpSockAddr->sin_addr, 4, AF_INET)) )
return( NULL );
return( lpHostEnt->h_name );
}
char* GetPeerAddr( int nSock )
{
SOCKADDR sockAddr;
LPSOCKADDR_IN lpSockAddr = (LPSOCKADDR_IN)&sockAddr;
unsigned long nSize = sizeof(SOCKADDR);
/* get the peer name */
if( getpeername(nSock, &sockAddr, &nSize) < 0 )
return NULL;
else
return( inet_ntoa(lpSockAddr->sin_addr) );
}
int IsPeerSockValid( int nSock )
{
SOCKADDR sockAddr;
LPSOCKADDR_IN lpSockAddr = (LPSOCKADDR_IN)&sockAddr;
LPHOSTENT lpHostEnt = NULL;
unsigned long nSize = sizeof(SOCKADDR);
/* get the peer name */
if( getpeername(nSock, &sockAddr, &nSize) < 0 )
{
return( -1 );
}
if( !(lpHostEnt=gethostbyaddr((char*)&lpSockAddr->sin_addr, 4, AF_INET)) )
{
return( -1 );
}
return( 0 );
}
void SigChild( int nRC )
{
int pid, status;
#ifdef __OS_DEC_UNIX__
while((pid = wait3((union wait *)&status, WNOHANG, (struct rusage *)0))>0);
#elif defined(__OS_SEQ_UNIX__)
while((pid = wait3((int*)&status, WNOHANG, (struct rusage *)0))>0);
#endif
}
char* GetDate( char* pStr )
{
static char pszTime[STRLEN] = "";
time_t timeNow;
timeNow = time( &timeNow );
strftime( pszTime, sizeof(pszTime), "%Y%m%d%H%M%S", localtime(&timeNow) );
return pszTime;
}
int RecvExt( int nSock, char* pStr, int nLen, int nTime )
{
int nRC = 0;
memset( pStr, 0, sizeof(pStr) );
/* set an alarm of nTime secs */
alarm( nTime );
nRC = recv( nSock, pStr, nLen, 0 );
if( errno == ETIME || errno == EINTR || nRC == 0 ) {
alarm( 0 );
return( -1 );
}
/* reset all alarm(s) */
alarm( 0 );
return( nRC );
}
/*
* Function to write a message to a socket.
* The message will be formatted in the form:
* 4-char length + data
*
* Parameters:
* nSock - socket to write message to
* dataBuff - buffer containing data to send in message
* dataLen - length of data
* timeout - timeout period (secs), or 0 for no timeout
* errBuff - buffer for error message (must be > 200 chars big)
*
* Returns 0 on success, or -1 on error.
* In the event of an error an error message is also placed in errBuff.
*/
int writeMessage(
int nSock,
char* dataBuff,
int dataLen,
unsigned long timeout,
char* errBuff
)
{
char* pBuf;
long dataWritten;
/* create a buffer containing 4 char length plus data */
if ( (pBuf = (char*)malloc(dataLen+4)) == NULL )
{
sprintf(errBuff, "ERROR: malloc() failed - out of memory!" );
return -1;
}
sprintf(pBuf, "%04d", dataLen );
memcpy(pBuf+4, dataBuff, dataLen);
dataLen += 4;
if (timeout > 0)
{
alarm(timeout);
}
/* send the message */
dataWritten = writeData( nSock, pBuf, dataLen, (timeout > 0) );
if (timeout > 0)
{
alarm(0); /* MUST turn alarm off */
}
if (dataWritten != dataLen)
{
if (dataWritten == 0)
{
sprintf(errBuff, "ERROR: write() returned 0 (eof)" );
}
else if (errno == EINTR)
{
sprintf(errBuff, "ERROR: signal or timeout during write()");
}
else
{
sprintf(errBuff,
"ERROR: write() for %d chars of data returned %d, errno = %d:%s",
dataLen, dataWritten, errno, strerror(errno));
}
free(pBuf);
return -1;
}
free(pBuf);
return 0;
}
/*
* Function to read a message from a socket.
* The message is expected to be formatted in the form:
* 4-char length + data
*
* Parameters:
* nSock - socket to read message from
* dataBuff - destination buffer for data part of message
* buffLen - length of buffer
* timeout - timeout period (secs), or 0 for no timeout
* errBuff - buffer for error message (must be > 200 chars big)
*
* Returns length of data read on success, or -1 on error.
* (A length of zero can occur if a message length of zero is received.)
* In the event of an error an error message is also placed in errBuff.
*/
int readMessage(
int nSock,
char* dataBuff,
int buffLen,
unsigned long timeout,
char* errBuff
)
{
char szLength[10];
long dataRead;
long dataLen;
if (timeout > 0)
{
alarm(timeout);
}
/* read 4-char message length */
memset( szLength, 0x00, sizeof(szLength));
dataRead = readData( nSock, szLength, 4 , (timeout > 0));
if ( isdigit(szLength[0]) && isdigit(szLength[1])
&& isdigit(szLength[2]) && isdigit(szLength[3]) )
{
dataLen = atoi(szLength);
}
else
{
/* non-numeric char received in length part of message - error */
dataLen = 0;
}
if ( (dataRead != 4) || (dataLen == 0) || (dataLen >= buffLen) )
{
if (timeout > 0)
{
alarm(0); /* MUST turn alarm off */
}
if (dataRead == 0)
{
sprintf(errBuff, "ERROR: read() for length returned 0 (eof)" );
return -1;
}
else if (dataRead != 4)
{
if (errno == EINTR)
{
sprintf(errBuff,
"ERROR: signal or timeout during read() for length");
}
else
{
sprintf(errBuff,
"ERROR: read() for length returned %d [%s], errno = %d:%s",
dataRead, szLength, errno, strerror(errno) );
}
return -1;
}
else if (dataLen == 0)
{
sprintf(errBuff, "ERROR: Message length of zero received [%s]",
szLength);
return 0;
}
else if (dataLen >= buffLen)
{
sprintf(errBuff, "ERROR: Message length of %d is too big, MAXLEN = %d",
dataLen, buffLen);
return -1;
}
}
/* now read the actual message data */
memset( dataBuff, 0x00, buffLen );
dataRead = readData( nSock, dataBuff, dataLen, (timeout > 0) );
if (timeout > 0)
{
alarm(0); /* MUST turn alarm off */
}
if (dataRead != dataLen)
{
if (dataRead == 0)
{
sprintf(errBuff, "ERROR: read() for data returned 0 (eof)" );
}
else if (errno == EINTR)
{
sprintf(errBuff, "ERROR: signal or timeout during read() for data");
}
else
{
sprintf(errBuff,
"ERROR: read() for data returned %d, errno = %d:%s",
dataRead, errno, strerror(errno) );
}
return -1;
}
return dataRead;
}
/*
* Function to write data to specified file descriptor.
* Works correctly even if a signal interrupts the write() system call.
*
* Parameters:
* fd - file descriptor to write data to
* dataBuff - buffer containing data to send
* dataLen - length of data
* sigExit - if non-zero then will exit on signal, else ignores signal
*
* Returns number of bytes successfully written, or -1 on error.
* Note that if the return value is less than dataLen (but not -1) then
* it implies that the file descriptor has been closed.
*/
int writeData(
int fd,
char* dataBuff,
int dataLen,
int sigExit
)
{
long writtenLen;
char* dataPtr;
int dataSentLen;
int toSendLen;
errno = 0; /* must do this to allow caller to check for EINTR */
dataPtr = dataBuff;
dataSentLen = 0;
toSendLen = dataLen;
while (toSendLen > 0)
{
writtenLen = write( fd, dataPtr, toSendLen );
if (writtenLen == -1)
{
/* error or signal occurred */
if ((errno == EINTR) && !sigExit)
{
errno = 0;
continue; /* ignore signal */
}
return -1; /* exit on error or signal */
}
if (writtenLen == 0)
{
/* end of file occurred */
break;
}
dataSentLen += writtenLen;
toSendLen -= writtenLen;
dataPtr += writtenLen;
}
return dataSentLen;
}
/*
* Function to read data from specified file descriptor.
* Works correctly even if a signal interrupts the read() system call.
*
* Parameters:
* fd - file descriptor to read data from
* dataBuff - destination buffer for data
* dataLen - length of data to be read
* sigExit - if non-zero then will exit on signal, else ignores signal
*
* Returns number of bytes successfully read, or -1 on error.
* Note that if the return value is less than dataLen (but not -1) then
* it implies that the file descriptor has been closed.
*/
int readData(
int fd,
char* dataBuff,
int dataLen,
int sigExit
)
{
long readLen;
char* dataPtr;
int dataReadLen;
int toReadLen;
errno = 0; /* must do this to allow caller to check for EINTR */
dataPtr = dataBuff;
dataReadLen = 0;
toReadLen = dataLen;
while (toReadLen > 0)
{
readLen = read( fd, dataPtr, toReadLen );
if (readLen == -1)
{
/* error or signal occurred */
if ((errno == EINTR) && !sigExit)
{
errno = 0;
continue; /* ignore signal */
}
return -1; /* exit on error or signal */
}
if (readLen == 0)
{
/* end of file occurred */
break;
}
dataReadLen += readLen;
toReadLen -= readLen;
dataPtr += readLen;
}
return dataReadLen;
}
int GetProcInfo( char* pStr, PROCINFO* pInfo )
{
int nRC = 0;
char szCom[100] = "";
char* pszFile = NULL;
char* p = NULL;
/* get the process info */
sprintf( szCom, "ps -eaf | grep %s | grep -v grep > /tmp/procinfo", pStr );
nRC = system( szCom );
if( (pszFile = GetFileContent( "/tmp/procinfo" )) == NULL )
return( -1 );
/* get the owner */
memset( pInfo, 0, sizeof(PROCINFO) );
p = strtok( pszFile, " " );
strcpy( pInfo->szOwner, p );
/* get the PID */
p = strtok( NULL, " " );
pInfo->nPid = atol( p );
/* TODO: get additional info */
/* cleanup allocated resources */
remove( "/tmp/procinfo" );
return 0;
}
/*
** EOF
*/
cat tcputil.h
#ifndef __TCPUTIL_H__
#define __TCPUTIL_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include "errsocket.h"
#include "utils.h"
/*
** macro definition for max length, retry, etc.
*/
#define MAX_RETRY 10
#define MAX_LISTEN 5
#define MAX_CONNECTION 30
/*
** socket type definitions
*/
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr_in* LPSOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
typedef struct sockaddr* LPSOCKADDR;
typedef struct hostent HOSTENT;
typedef struct hostent* LPHOSTENT;
typedef struct servent SERVENT;
typedef struct servent* LPSERVENT;
/*
** process info
*/
typedef struct tagPROCINFO {
char szOwner[15];
int nPid;
char szTty[15];
char szIdleTm[6];
} PROCINFO;
/*
** client/server function prototypes
*/
int Connect ( char*, char* );
int CreateListener ( char* );
char* GetPeerAddr ( int );
char* GetPeerName ( int );
int IsPeerSockValid ( int );
int RecvExt ( int, char*, int, int );
int writeMessage(
int nSock,
char* dataBuff,
int dataLen,
unsigned long timeout,
char* errBuff
);
int readMessage(
int nSock,
char* dataBuff,
int buffLen,
unsigned long timeout,
char* errBuff
);
int writeData(
int fd,
char* dataBuff,
int dataLen,
int sigExit
);
int readData(
int fd,
char* dataBuff,
int dataLen,
int sigExit
);
/*
** signal function(s)
*/
void SigChild ();
int GetProcInfo ( char*, PROCINFO* );
/*
** date/time function(s)
*/
char* GetDate ( char* );
#endif /* __TCPUTIL_H__ */
Please help me resolve this issue.