/* ***************************************************************************** * * Copyright 1989, Xylogics, Inc. ALL RIGHTS RESERVED. * * ALL RIGHTS RESERVED. Licensed Material - Property of Xylogics, Inc. * This software is made available solely pursuant to the terms of a * software license agreement which governs its use. * Unauthorized duplication, distribution or sale are strictly prohibited. * * Module Description:: * * Compatibility routines for those lacking systems: * sendto sendmsg recvfrom recvmsg * * Original Author: Dave Harris Created on: June 10, 1986 * * Module Reviewers: * * harris lint * * Revision Control Information: * * $Header: /annex/release10.1/src/libannex/RCS/sendrecv.c,v 1.13 1995/09/08 13:35:21 mason Exp $ * * This file created by RCS from: * * $Source: /annex/release10.1/src/libannex/RCS/sendrecv.c,v $ * * Revision History: * * $Log: sendrecv.c,v $ * Revision 1.14 1995/10/11 13:57:38 mason * #endif EXOS -> #endif /* EXOS * / * * Revision 1.13 1995/09/08 13:35:21 mason * #endif NT32 -> #endif +*NT32*+ because SCO complained * * Revision 1.12.5.2 1995/08/30 17:00:35 slu * Cleanup debug statement. * * Revision 1.12.5.2 1995/08/30 17:00:35 slu * Cleanup debug statement. * * Revision 1.12.5.1 1995/08/16 12:44:04 slu * Support NT. * * Revision 1.12 1994/11/22 13:39:53 parker * Changed NT support to use the NuTcracker library. * * Revision 1.11 1994/11/16 09:25:40 parker * Changes for port to Windows NT * * Revision 1.10 1991/08/06 09:07:32 emond * Added Scott's change to allow NEED_0_SENDTO. * * Revision 1.9 91/05/01 22:41:47 emond * Changed name of replacement functions. i.e. _sendto to xylo_sendto. * This is to prevent the conflict with lib on HP's. * * Revision 1.8 90/02/15 15:37:48 loverso * clobber #else/#endif TAG * * Revision 1.7 89/04/27 13:41:04 loverso * Add missing { } * * Revision 1.6 89/04/12 15:07:16 loverso * Add debug messages * * Revision 1.5 89/04/11 01:07:49 loverso * reflect differences from EXOS socket calls and real socket calls * * Revision 1.4 89/04/05 12:40:19 loverso * Changed copyright notice * * Revision 1.3 88/05/24 18:35:52 parker * Changes for new install-annex script * * Revision 1.1 88/04/15 11:58:20 mattes * Initial revision * * Revision 2.3 87/08/27 10:37:39 mattes * #include changes for UMAX V * * Revision 2.2 87/06/10 18:12:42 parker * Added support for Xenix/Excelan PC. * * Revision 2.0 86/06/13 12:57:22 harris * Branch for development 2.0. * * Revision 1.1.1.1 86/06/10 16:38:53 harris * Branch created for "Release_1". * * Revision 1.1 86/06/10 16:33:57 harris * Initial revision * * * This file is currently under revision by: * * $Locker: $ * ***************************************************************************** */ #define RCSDATE $Date: 1995/09/08 13:35:21 $ #define RCSREV $Revision: 1.13 $ #define RCSID "$Header: /annex/release10.1/src/libannex/RCS/sendrecv.c,v 1.13 1995/09/08 13:35:21 mason Exp $" #ifndef lint static char rcsid[] = RCSID; #endif /* Include Files */ /* * The include of config.h could probably be moved down after the other * includes (just like it was necessary for LINUX) but this has not yet * been tested for all the supported platforms. */ #include #include #include #ifndef _WIN32 #include #include #include #else #include "../inc/port/xuio.h" #endif #include "../inc/config.h" /* Defines */ #define MSGBUFSIZE 2048 /* Forward Function Declarations */ extern char *bcopy(); extern int debug; #ifndef SLIP /* * recvfrom, recvmsg: quick and dirty interface routines * for the Excelan 4.1c environment. * Some socket addresses, flags,and some other arguments are ignored, * but probably should be checked. */ xylo_recvfrom(s,msg,len,flags,from,fromlen) int s,len,flags; int *fromlen; char *msg; struct sockaddr_in *from; { int ret; if (debug) fprintf(stderr, "libannex recvfrom\n"); if (from) { *fromlen = sizeof(struct sockaddr_in); #ifdef EXOS ret = receive(s, from, msg, len); #else /* XXX */ if (debug) fprintf(stderr, "NOT IMPLEMENTED!\n"); ret = recv(s, msg, len, flags); #endif } else ret = read(s, msg, len); /* XXX ignores flags */ if (debug > 1) { int i; fprintf(stderr, "recv'd %d bytes:", ret); for (i = 0; i < ret; i++) { if (i%16 == 0) fprintf(stderr, "\n%3d: ", i); fprintf(stderr, "%2x ", msg[i]); } fputs("\n", stderr); } return ret; } #endif /* * recvmsg() is scatter/gather version of recvfrom() */ xylo_recvmsg(s,msg,flags) int s,flags; struct msghdr *msg; { static char buffer[MSGBUFSIZE]; struct sockaddr_in *from; int bufsize = 0; int nread; int i; /* * NOTE: this assumes that the entire message was * passed atomically to socket, the data is "padded" * to each vector length. It can then copy data to vectors * in msg from buffer. */ if (debug) fprintf(stderr, "libannex recvmsg\n"); from = (struct sockaddr_in *) msg->msg_name; if (from) { #ifdef EXOS nread = receive(s, from, buffer, MSGBUFSIZE); #else int fromsize = sizeof(*from); #ifdef _WIN32 /* * With Windows NT/Winsock you can not do a recvfrom() on a connected socket. * So we check for connected by calling getpeername() first.. */ if(getpeername(s,(struct sockaddr *)from, &fromsize) == 0) nread = recv(s, buffer, MSGBUFSIZE, 0); else nread = recvfrom(s, buffer, MSGBUFSIZE, 0, (struct sockaddr *)from, &fromsize); if(nread == -1 && debug) fprintf(stderr,"recvfrom Failed: %d\n", GetLastError()); #else nread = recvfrom(s, buffer, MSGBUFSIZE, 0, (struct sockaddr *)from, &fromsize); if(nread == -1) perror("recvfrom Failed:"); #endif #endif /* EXOS */ } else { #ifdef EXOS struct sockaddr_in who; nread = receive(s, &who, buffer, MSGBUFSIZE); #else nread = read(s, buffer, MSGBUFSIZE); #endif } if (nread == -1) return(nread); if (debug > 1) { fprintf(stderr, "recv'd %d bytes:", nread); for (i = 0; i < nread; i++) { if (i%16 == 0) fprintf(stderr, "\n%3d: ", i); fprintf(stderr, "%2x ", buffer[i]); } fputs("\n", stderr); } for (i = 0; i < msg->msg_iovlen; i++) { if ((bufsize > MSGBUFSIZE) || (bufsize > nread)) { return(-1); } bcopy(buffer+bufsize, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); bufsize += msg->msg_iov[i].iov_len; } return (nread); } #ifndef SLIP /* * sendto, sendmsg: interface routines for the Excelan environment. * Some socket addresses, flags, and some other arguments are ignored, * but probably should be checked. * * "s" is a descriptor for a UDP socket * "msg" pointer to message * "len" size of message * "to" if non-zero, names recipient of message * if zero, indicates socket is connect()ed to peer * "tolen" length of recipients name */ xylo_sendto (s,msg,len,flags,to,tolen) int s,len,flags,tolen; char *msg; struct sockaddr_in *to; { int nwritten = 0, nremain = len; char *residmsg = msg; if (debug) fprintf(stderr, "libannex sendto\n"); /* If address is passed, assume we have not been "connect()"ed * so, use send(). Otherwise, assume we have been "connect()"ed * and we can use write(). */ do { if (to) { #ifdef EXOS nwritten = send(s, to, residmsg, nremain); #else #ifdef NEED_0_SENDTO #undef sendto nwritten = sendto(s, msg, len, flags, to, tolen); #define sendto xylo_sendto #else /* XXX to who? */ if (debug) fprintf(stderr, "NOT IMPLEMENTED!\n"); nwritten = send(s, residmsg, nremain, flags); #endif #endif } else nwritten = write(s, residmsg, nremain); if (nwritten < 0) { perror("sendto: send|write"); return(nwritten); } nremain -= nwritten; residmsg += nwritten; } while (nremain > 0); return(len); } #endif /* * sendmsg() is scatter/gather version of sendto() */ xylo_sendmsg (s,msg,flags) int s, flags; struct msghdr *msg; { int bufsize = 0; static char buffer[MSGBUFSIZE]; int i; if (debug) fprintf(stderr, "libannex sendmsg\n"); /* * loop, concatenating vector messages into one large message * NOTE: this assumes that the entire message must be * passed atomically to socket, hence the malloc of buffer. * Otherwise, loop could do writes for each element of vector. * Sigh. */ for (i = 0; i < msg->msg_iovlen; i++) { bcopy(msg->msg_iov[i].iov_base, buffer+bufsize, msg->msg_iov[i].iov_len); bufsize += msg->msg_iov[i].iov_len; } if(msg->msg_name) return sendto(s, buffer, bufsize, flags, (struct sockaddr *)msg->msg_name, msg->msg_namelen); return send(s, buffer, bufsize, flags); }