xref: /openbsd/gnu/usr.bin/cvs/os2/porttcp.c (revision 13571821)
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 *
SockStrError(int SockErrno)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 *
HostStrError(int HostErrno)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
IbmSockSend(int Socket,const void * Buffer,int Len,int Flags)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
IbmSockRecv(int Socket,const void * Buffer,int Len,int Flags)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