1 /**************************************************************** 2 ** 3 ** PORTTCP.C - Support for portable TCP/IP 4 ** 5 ****************************************************************/ 6 7 #define TCPIP_IBM_NOHIDE 8 #include <stdio.h> 9 #include "tcpip.h" 10 11 /* 12 * Common unknown error buffer 13 */ 14 static char ErrUnknownBuf[36]; 15 16 #ifndef SockStrError 17 18 /**************************************************************** 19 * Routine: SockStrError 20 * Returns: Pointer to static buffer 21 * Action : Convert SOCK_ERRNO into error text 22 ****************************************************************/ 23 24 const char * 25 SockStrError(int SockErrno) 26 { 27 #if defined (TCPIP_IBM) && defined (IBM_CPP) 28 switch (SockErrno) 29 { 30 case SOCEPERM: return "Not owner"; 31 case SOCESRCH: return "No such process"; 32 case SOCEINTR: return "Interrupted system call"; 33 case SOCENXIO: return "No such device or address"; 34 case SOCEBADF: return "Bad file number"; 35 case SOCEACCES: return "Permission denied"; 36 case SOCEFAULT: return "Bad address"; 37 case SOCEINVAL: return "Invalid argument"; 38 case SOCEMFILE: return "Too many open files"; 39 case SOCEPIPE: return "Broken pipe"; 40 case SOCEOS2ERR: return "OS/2 Error"; 41 case SOCEWOULDBLOCK: return "Operation would block"; 42 case SOCEINPROGRESS: return "Operation now in progress"; 43 case SOCEALREADY: return "Operation already in progress"; 44 case SOCENOTSOCK: return "Socket operation on non-socket"; 45 case SOCEDESTADDRREQ: return "Destination address required"; 46 case SOCEMSGSIZE: return "Message too long"; 47 case SOCEPROTOTYPE: return "Protocol wrong type for socket"; 48 case SOCENOPROTOOPT: return "Protocol not available"; 49 case SOCEPROTONOSUPPORT: return "Protocol not supported"; 50 case SOCESOCKTNOSUPPORT: return "Socket type not supported"; 51 case SOCEOPNOTSUPP: return "Operation not supported on socket"; 52 case SOCEPFNOSUPPORT: return "Protocol family not supported"; 53 case SOCEAFNOSUPPORT: 54 return "Address family not supported by protocol family"; 55 case SOCEADDRINUSE: return "Address already in use"; 56 case SOCEADDRNOTAVAIL: return "Can't assign requested address"; 57 case SOCENETDOWN: return "Network is down"; 58 case SOCENETUNREACH: return "Network is unreachable"; 59 case SOCENETRESET: return "Network dropped connection on reset"; 60 case SOCECONNABORTED: return "Software caused connection abort"; 61 case SOCECONNRESET: return "Connection reset by peer"; 62 case SOCENOBUFS: return "No buffer space available"; 63 case SOCEISCONN: return "Socket is already connected"; 64 case SOCENOTCONN: return "Socket is not connected"; 65 case SOCESHUTDOWN: return "Can't send after socket shutdown"; 66 case SOCETOOMANYREFS: return "Too many references: can't splice"; 67 case SOCETIMEDOUT: return "Connection timed out"; 68 case SOCECONNREFUSED: return "Connection refused"; 69 case SOCELOOP: return "Too many levels of symbolic links"; 70 case SOCENAMETOOLONG: return "File name too long"; 71 case SOCEHOSTDOWN: return "Host is down"; 72 case SOCEHOSTUNREACH: return "No route to host"; 73 case SOCENOTEMPTY: return "Directory not empty"; 74 75 default: 76 sprintf( ErrUnknownBuf, "SockStrErrno( %d ) unknown", SockErrno ); 77 return ErrUnknownBuf; 78 } 79 #else 80 #error SockStrError not supported for this OS 81 #endif 82 } 83 84 #endif /* SockStrError */ 85 86 87 /**************************************************************** 88 * Routine: HostStrError 89 * Returns: Pointer to static buffer 90 * Action : Convert HOST_ERRNO into error text 91 ****************************************************************/ 92 93 const char * 94 HostStrError(int HostErrno) 95 { 96 switch (HostErrno) 97 { 98 case HOST_NOT_FOUND: 99 return "Host not found"; 100 case TRY_AGAIN: 101 return "Host not found (suggest try again)"; 102 case NO_RECOVERY: 103 return "Non-recoverable error: FORMERR, REFUSED, NOTIMP"; 104 case NO_DATA: 105 return "No Data (valid name, but no record of requested type)"; 106 107 default: 108 sprintf( ErrUnknownBuf, "HostStrErrno( %d ) unknown", HostErrno ); 109 return ErrUnknownBuf; 110 } 111 } 112 113 114 #if defined( TCPIP_IBM ) 115 /**************************************************************** 116 * Routine: IbmSockSend 117 * Returns: same as send 118 * Action : Do the right thing for IBM TCP/IP which includes 119 * the following two stupidities: 120 * 1) Never try to send more than 32K 121 * 2) Never pass a buffer that crosses a 64K boundary 122 * If Flags is non-zero, this function only attempts 123 * to deal with condition (1) above. 124 ****************************************************************/ 125 126 int 127 IbmSockSend (int Socket, const void *Buffer, int Len, int Flags) 128 { 129 int Sent, ToSend, TotalSent = 0; 130 131 const char *Tmp = Buffer; 132 133 /* 134 * If Flags have been passed in, the 64K boundary optimization 135 * can not be performed. For example, MSG_PEEK would not work 136 * correctly. 137 */ 138 if (Flags) 139 return send (Socket, (char *) Buffer, min (0x7FFF, Len), Flags); 140 141 do 142 { 143 /* Never send across a 64K boundary */ 144 ToSend = min (Len, (int) (0x10000 - (0xFFFF & (long) Tmp))); 145 146 /* Never send more than 32K */ 147 if (ToSend > 0x7FFF) 148 ToSend = 0x7FFF; 149 150 Sent = send (Socket, (char *) Tmp, ToSend, 0); 151 if (Sent < 0) 152 { 153 if ((TotalSent > 0) && (SOCK_ERRNO == EWOULDBLOCK)) 154 return TotalSent; 155 if (SOCK_ERRNO == EINTR) 156 continue; 157 return Sent; 158 } 159 if (Sent < ToSend) 160 return TotalSent + Sent; 161 162 Tmp += Sent; 163 TotalSent += Sent; 164 Len -= Sent; 165 } while (Len > 0); 166 167 return TotalSent; 168 } 169 170 171 172 /**************************************************************** 173 * Routine: IbmSockRecv 174 * Returns: same as recv 175 * Action : Do the right thing for IBM TCP/IP which includes 176 * the following two stupidities: 177 * 1) Never try to recv more than 32K 178 * 2) Never pass a buffer that crosses a 64K boundary 179 * If Flags is non-zero, this function only attempts 180 * to deal with condition (1) above. 181 ****************************************************************/ 182 183 int 184 IbmSockRecv (int Socket, const void *Buffer, int Len, int Flags) 185 { 186 int Recvd, ToRecv, TotalRecvd = 0; 187 188 char *Tmp = Buffer; 189 190 /* If Flags have been passed in, the 64K boundary optimization 191 probably can not be performed. */ 192 193 if (Flags) 194 return recv (Socket, Buffer, min (0x7FFF, Len), Flags); 195 196 do 197 { 198 /* Never send across a 64K boundary */ 199 ToRecv = min( Len, (int)( 0x10000 - ( 0xFFFF & (long)Tmp ))); 200 201 /* Never send more than 32K */ 202 if( ToRecv > 0x7FFF ) 203 ToRecv = 0x7FFF; 204 205 Recvd = recv (Socket, Tmp, ToRecv, 0); 206 if (Recvd <= 0) 207 { 208 if ((TotalRecvd > 0) 209 && (Recvd == 0 || (SOCK_ERRNO == EWOULDBLOCK ))) 210 return TotalRecvd; 211 if (SOCK_ERRNO == EINTR) 212 continue; 213 214 return Recvd; 215 } 216 if (Recvd < ToRecv) 217 return TotalRecvd + Recvd; 218 219 Tmp += Recvd; 220 TotalRecvd += Recvd; 221 Len -= Recvd; 222 } while (Len > 0); 223 224 return TotalRecvd; 225 } 226 #endif /* defined( TCPIP_IBM ) */ 227 228