Merge branch 'win32' into win32-3
[deb_libnfs.git] / lib / pdu.c
index a12d30b2501e342a9d76fa91102521b973b668c7..6cb85ae8028e436e1eed5dda5f3ff89586dfdf79 100644 (file)
--- a/lib/pdu.c
+++ b/lib/pdu.c
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <stdio.h>
+#if defined(WIN32)
+#include <winsock2.h>
+#define MSG_DONTWAIT 0
+#else
 #include <strings.h>
+#endif
+
+#include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <rpc/rpc.h>
 #include <rpc/xdr.h>
 #include <rpc/rpc_msg.h>
@@ -97,6 +104,17 @@ int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu)
 
        size = xdr_getpos(&pdu->xdr);
 
+       /* for udp we dont queue, we just send it straight away */
+       if (rpc->is_udp != 0) {
+               if (sendto(rpc->fd, rpc->encodebuf, size, MSG_DONTWAIT, rpc->udp_dest, sizeof(struct sockaddr_in)) < 0) {
+                       rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno));
+                       rpc_free_pdu(rpc, pdu);
+                       return -1;
+               }
+               SLIST_ADD_END(&rpc->waitpdu, pdu);
+               return 0;
+       }
+
        /* write recordmarker */
        xdr_setpos(&pdu->xdr, 0);
        recordmarker = (size - 4) | 0x80000000;
@@ -137,6 +155,9 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR *
        bzero(&msg, sizeof(struct rpc_msg));
        msg.acpted_rply.ar_verf = _null_auth;
        if (pdu->xdr_decode_bufsize > 0) {
+               if (pdu->xdr_decode_buf != NULL) {
+                       free(pdu->xdr_decode_buf);
+               }
                pdu->xdr_decode_buf = malloc(pdu->xdr_decode_bufsize);
                if (pdu->xdr_decode_buf == NULL) {
                        rpc_set_error(rpc, "xdr_replymsg failed in portmap_getport_reply");
@@ -198,10 +219,12 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size)
        bzero(&xdr, sizeof(XDR));
 
        xdrmem_create(&xdr, buf, size, XDR_DECODE);
-       if (xdr_int(&xdr, &recordmarker) == 0) {
-               rpc_set_error(rpc, "xdr_int reading recordmarker failed");
-               xdr_destroy(&xdr);
-               return -1;
+       if (rpc->is_udp == 0) {
+               if (xdr_int(&xdr, &recordmarker) == 0) {
+                       rpc_set_error(rpc, "xdr_int reading recordmarker failed");
+                       xdr_destroy(&xdr);
+                       return -1;
+               }
        }
        pos = xdr_getpos(&xdr);
        if (xdr_int(&xdr, (int *)&xid) == 0) {
@@ -215,12 +238,16 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size)
                if (pdu->xid != xid) {
                        continue;
                }
-               SLIST_REMOVE(&rpc->waitpdu, pdu);
+               if (rpc->is_udp == 0 || rpc->is_broadcast == 0) {
+                       SLIST_REMOVE(&rpc->waitpdu, pdu);
+               }
                if (rpc_process_reply(rpc, pdu, &xdr) != 0) {
                        rpc_set_error(rpc, "rpc_procdess_reply failed");
                }
                xdr_destroy(&xdr);
-               rpc_free_pdu(rpc, pdu);
+               if (rpc->is_udp == 0 || rpc->is_broadcast == 0) {
+                       rpc_free_pdu(rpc, pdu);
+               }
                return 0;
        }
        rpc_set_error(rpc, "No matching pdu found for xid:%d", xid);