/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ipc_recv
- ipc_send
/* Low level TCP socket routines. These routines are used by both
client and server API's.
Rick Smereka, Copyright (C) 1998-2006.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, get a copy via the Internet at
http://gnu.org/copyleft/gpl.html or write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
You can contact the author via email at rsmereka@future-lab.com
Original version for CodeWarrior V4 under Windows 32bit.
Dec/98, Rick Smereka
Ported to HP-UX under GNU C 2.8.1.
Jan/99, Rick Smereka
Ported to Red Hat Linux 5.2, Jul/99, Rick Smereka
Ported to Debian Linux. Nov/2002, Rick Smereka
Changed 'ipc_send' to send the data length before the actual data
and changed 'ipc_recv' to receive the data length before the
actual data. Feb/2006, Rick Smereka
Commented out calls to 'log_file_date' unless there is an error.
Sep/2006, Rick Smereka */
#include "stdhead.h"
#include "flsocket.h"
#include "ipcomm.h"
#ifdef OS_WIN32
int ipc_recv(SOCKET sock, char *buf)
#endif
#ifdef OS_UNIX
int ipc_recv(int sock, char *buf)
#endif
{
/* Receive up to 'IPC_MAXREC' - 1 bytes from the
socket which is assumed to be open. Function
returns the number of bytes read upon success,
zero otherwise. */
char mname[] = "ipc_recv", *fbuf;
int charRecv, len, pos = 0, done = FALSE;
if ((fbuf = (char *)malloc(IPC_SR_BUFSIZE)) == (char *)NULL)
{
log_file_date("%s:alloc fail[fbuf]", mname);
return(FALSE);
}
// receive fixed size header wich must contain length of data
#ifdef OS_WIN32
charRecv = recv(sock, (LPSTR)fbuf, IPC_HEAD_SIZE, NO_FLAGS);
#endif
#ifdef OS_UNIX
charRecv = recv(sock, fbuf, IPC_HEAD_SIZE, NO_FLAGS);
#endif
if (charRecv == SOCKET_ERROR)
{
free(fbuf);
log_file_date("%s:bad rc[-1] from recv[header]", mname);
return(0);
}
if (charRecv != IPC_HEAD_SIZE)
{
free(fbuf);
log_file_date("%s:received improper header size", mname);
return(0);
}
fbuf[IPC_HEAD_SIZE] = EOS;
// log_file_date("%s:recv header=%s[%d]", mname, fbuf, strlen(fbuf));
if (!qatoi(fbuf, &len))
{
free(fbuf);
log_file_date("%s:header length is non-numeric", mname);
return(0);
}
while(!done)
{
#ifdef OS_WIN32
charRecv = recv(sock, (LPSTR)fbuf, (IPC_SR_BUFSIZE - 1), NO_FLAGS);
#endif
#ifdef OS_UNIX
charRecv = recv(sock, fbuf, (IPC_SR_BUFSIZE - 1), NO_FLAGS);
#endif
if (charRecv == SOCKET_ERROR)
{
free(fbuf);
log_file_date("%s:bad rc[-1] from recv", mname);
return(0);
}
fbuf[charRecv] = EOS;
// log_file_date("%s:received %d byte(s)", mname, charRecv);
if ((strlen(fbuf) + strlen(buf)) >= IPC_MAXREC)
{
log_file_date("%s:too much data", mname);
free(fbuf);
return(0);
}
strncpy(&buf[pos], fbuf, charRecv);
if (charRecv > 0)
pos += charRecv;
buf[pos] = EOS;
// we are done when we have received all bytes according to header
if (pos >= len)
done = TRUE;
}
free(fbuf);
// log_file_date("%s:received total of %d byte(s)", mname, pos);
return(pos);
}
#ifdef OS_WIN32
int ipc_send(SOCKET sock, char *buf)
#endif
#ifdef OS_UNIX
int ipc_send(int sock, char *buf)
#endif
{
/* Send data to the socket. Function returns the
number of bytes sent upon success, zero
otherwise. */
char *fbuf, header[IPC_HEAD_SIZE + 1], mname[] = "ipc_send";
int len, charSent, pos = 0, bytesToGo, done = FALSE;
int chunk;
len = strlen(buf);
if (!len)
return(0);
// send fixed size header first consisting of data size
sprintf(header, "%010d", len);
// log_file_date("%s:header to send is %s[%d]", mname, header, strlen(header));
if ((charSent = send(sock, header, IPC_HEAD_SIZE, NO_FLAGS)) ==
SOCKET_ERROR)
{
log_file_date("%s:bad rc[%d] from send[header]", mname, charSent);
return(FALSE);
}
// if less than 'IPC_SR_BUFSIZE' to send, use one shot
if (len < IPC_SR_BUFSIZE)
{
if ((charSent = send(sock, buf, len, NO_FLAGS)) == SOCKET_ERROR)
{
log_file_date("%s:bad rc[%d] from send", mname, charSent);
return(FALSE);
}
return(charSent);
}
if ((fbuf = (char *)malloc(IPC_SR_BUFSIZE)) == (char *)NULL)
{
log_file_date("%s:alloc fail[fbuf]", mname);
return(FALSE);
}
bytesToGo = len;
// send one buffer length at a time
while(!done)
{
if (bytesToGo > (IPC_SR_BUFSIZE - 1))
chunk = IPC_SR_BUFSIZE - 1;
else
chunk = bytesToGo;
strncpy(fbuf, &buf[pos], chunk);
fbuf[chunk] = EOS;
if ((charSent = send(sock, fbuf, chunk, NO_FLAGS)) == SOCKET_ERROR)
{
pos = 0;
log_file_date("%s:bad rc[%d] from send", mname, charSent);
break;
}
bytesToGo -= chunk;
pos += charSent;
if (bytesToGo <= 0)
done = TRUE;
}
free(fbuf);
//log_file_date("ipc_send:sent total of %d byte(s)", pos);
return(pos);
}