rx-warning-cleanup-and-afsconfig-20010605
[openafs.git] / src / rx / rx_xmit_nt.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /* NT does not have uio structs, so we roll our own sendmsg and recvmsg.
11  *
12  * The dangerous part of this code is that it assumes that iovecs 0 and 1
13  * are contiguous and that all of 0 is used before any of 1.
14  * This is true if rx_packets are being sent, so we should be ok.
15  */
16
17 #include <afs/param.h>
18 #if defined(AFS_NT40_ENV) || defined(AFS_DJGPP_ENV)
19
20 #ifdef AFS_NT40_ENV
21 #include <winsock2.h>
22 #else
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 typedef int SOCKET;
31 #endif
32
33 #include "rx.h"
34 #include "rx_packet.h"
35 #include "rx_globals.h"
36 #include "rx_xmit_nt.h"
37 #ifdef AFS_NT40_ENV
38 #include <malloc.h>
39 #endif
40 #include <errno.h>
41
42 int recvmsg(int socket, struct msghdr *msgP, int flags)
43 {
44     char rbuf[RX_MAX_PACKET_SIZE];
45     int size;
46     int code;
47     int off, i, n;
48     int allocd = 0;
49
50
51     size = rx_maxJumboRecvSize;
52     code = recvfrom((SOCKET)socket, rbuf, size, flags,
53                     (struct sockaddr*)(msgP->msg_name),
54                     &(msgP->msg_namelen));
55
56     if (code>0) {
57         size = code;
58         
59         for (off = i = 0; size > 0 && i<msgP->msg_iovlen; i++) {
60             if (msgP->msg_iov[i].iov_len) {
61                 if (msgP->msg_iov[i].iov_len < size) {
62                     n = msgP->msg_iov[i].iov_len;
63                 }
64                 else {
65                     n = size;
66                 }
67                 memcpy(msgP->msg_iov[i].iov_base, &rbuf[off], n);
68                 off += n;
69                 size -= n;
70             }
71         }
72
73         /* Accounts for any we didn't copy in to iovecs. */
74         code -= size;
75     }
76     else {
77         code = -1;
78     }
79
80     return code;
81 }
82
83 int sendmsg(int socket, struct msghdr *msgP, int flags)
84 {
85     char buf[RX_MAX_PACKET_SIZE];
86     char *sbuf=buf;
87     int size, tmp;
88     int code;
89     int off, i, n;
90     int allocd = 0;
91
92     for (size = i = 0; i<msgP->msg_iovlen; i++)
93         size += msgP->msg_iov[i].iov_len;
94          
95     if (msgP->msg_iovlen <= 2) {
96         sbuf = msgP->msg_iov[0].iov_base;
97     }
98     else {
99         /* Pack data into array from iovecs */
100         tmp = size;
101         for (off = i = 0; tmp > 0 && i<msgP->msg_iovlen; i++) {
102             if (msgP->msg_iov[i].iov_len > 0 ) {
103                 if (tmp > msgP->msg_iov[i].iov_len)
104                     n = msgP->msg_iov[i].iov_len;
105                 else
106                     n = tmp;
107                 memcpy(&sbuf[off], msgP->msg_iov[i].iov_base, n);
108                 off += n;
109                 tmp -= n;
110             }
111         }
112     }
113
114     code = sendto((SOCKET)socket, sbuf, size, flags,
115                   (struct sockaddr*)(msgP->msg_name), msgP->msg_namelen);
116
117 #ifdef AFS_NT40_ENV
118     if (code == SOCKET_ERROR) {
119         code = WSAGetLastError();
120         switch (code) {
121         case WSAEINPROGRESS:
122         case WSAENETRESET:
123         case WSAEWOULDBLOCK:
124         case WSAENOBUFS:
125             errno = 0;
126             break;
127         default:
128             errno = EIO;
129             break;
130         }
131         code = -1;
132     }
133 #endif /* AFS_NT40_ENV */
134
135     if (code < size) {
136         errno = EIO;
137         code = -1;
138     }
139
140     return code;
141
142 }
143
144
145
146
147 #endif /* AFS_NT40_ENV || AFS_DJGPP_ENV */