[win32] - make it compile on win32
[deb_libnfs.git] / lib / pdu.c
index 8aefa5743d9d76f14f98b4d7e780d7ffb09d132a..d7426ced53c82a50748b243d130b09ad2c1dab06 100644 (file)
--- a/lib/pdu.c
+++ b/lib/pdu.c
    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
+#ifdef WIN32
+#include "win32_compat.h"
+#ifndef MSG_DONTWAIT
+#define MSG_DONTWAIT 0
+#endif
+#else
+#include <strings.h>
+#endif/*WIN32*/
 
 #include <stdio.h>
-#include <strings.h>
 #include <stdlib.h>
+#include <errno.h>
 #include <rpc/rpc.h>
 #include <rpc/xdr.h>
 #include <rpc/rpc_msg.h>
@@ -32,16 +40,15 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi
        struct rpc_msg msg;
 
        if (rpc == NULL) {
-               printf("trying to allocate rpc pdu on NULL context\n");
                return NULL;
        }
 
        pdu = malloc(sizeof(struct rpc_pdu));
        if (pdu == NULL) {
-               printf("Failed to allocate pdu structure\n");
+               rpc_set_error(rpc, "Out of memory: Failed to allocate pdu structure");
                return NULL;
        }
-       bzero(pdu, sizeof(struct rpc_pdu));
+       memset(pdu, 0, sizeof(struct rpc_pdu));
        pdu->xid                = rpc->xid++;
        pdu->cb                 = cb;
        pdu->private_data       = private_data;
@@ -49,9 +56,11 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi
        pdu->xdr_decode_bufsize = xdr_decode_bufsize;
 
        xdrmem_create(&pdu->xdr, rpc->encodebuf, rpc->encodebuflen, XDR_ENCODE);
-       xdr_setpos(&pdu->xdr, 4); /* skip past the record marker */
+       if (rpc->is_udp == 0) {
+               xdr_setpos(&pdu->xdr, 4); /* skip past the record marker */
+       }
 
-       bzero(&msg, sizeof(struct rpc_msg));
+       memset(&msg, 0, sizeof(struct rpc_msg));
        msg.rm_xid = pdu->xid;
         msg.rm_direction = CALL;
        msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
@@ -62,7 +71,7 @@ struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int versi
        msg.rm_call.cb_verf = rpc->auth->ah_verf;
 
        if (xdr_callmsg(&pdu->xdr, &msg) == 0) {
-               printf("xdr_callmsg failed\n");
+               rpc_set_error(rpc, "xdr_callmsg failed");
                xdr_destroy(&pdu->xdr);
                free(pdu);
                return NULL;
@@ -85,6 +94,7 @@ void rpc_free_pdu(struct rpc_context *rpc _U_, struct rpc_pdu *pdu)
        }
 
        xdr_destroy(&pdu->xdr);
+
        free(pdu);
 }
 
@@ -95,6 +105,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;
@@ -121,7 +142,7 @@ int rpc_get_pdu_size(char *buf)
        size = ntohl(*(uint32_t *)buf);
 
        if ((size & 0x80000000) == 0) {
-               printf("cant handle oncrpc fragments\n");
+               /* cant handle oncrpc fragments */
                return -1;
        }
 
@@ -132,22 +153,25 @@ static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, XDR *
 {
        struct rpc_msg msg;
 
-       bzero(&msg, sizeof(struct rpc_msg));
+       memset(&msg, 0, 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) {
-                       printf("xdr_replymsg failed in portmap_getport_reply\n");
+                       rpc_set_error(rpc, "xdr_replymsg failed in portmap_getport_reply");
                        pdu->cb(rpc, RPC_STATUS_ERROR, "Failed to allocate buffer for decoding of XDR reply", pdu->private_data);
                        return 0;
                }
-               bzero(pdu->xdr_decode_buf, pdu->xdr_decode_bufsize);
+               memset(pdu->xdr_decode_buf, 0, pdu->xdr_decode_bufsize);
        }
        msg.acpted_rply.ar_results.where = pdu->xdr_decode_buf;
        msg.acpted_rply.ar_results.proc  = pdu->xdr_decode_fn;
 
        if (xdr_replymsg(xdr, &msg) == 0) {
-               printf("xdr_replymsg failed in portmap_getport_reply\n");
+               rpc_set_error(rpc, "xdr_replymsg failed in portmap_getport_reply");
                pdu->cb(rpc, RPC_STATUS_ERROR, "Message rejected by server", pdu->private_data);
                if (pdu->xdr_decode_buf != NULL) {
                        free(pdu->xdr_decode_buf);
@@ -193,17 +217,19 @@ int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size)
        int pos, recordmarker;
        unsigned int xid;
 
-       bzero(&xdr, sizeof(XDR));
+       memset(&xdr, 0, sizeof(XDR));
 
        xdrmem_create(&xdr, buf, size, XDR_DECODE);
-       if (xdr_int(&xdr, &recordmarker) == 0) {
-               printf("xdr_int reading recordmarker failed\n");
-               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) {
-               printf("xdr_int reading xid failed\n");
+               rpc_set_error(rpc, "xdr_int reading xid failed");
                xdr_destroy(&xdr);
                return -1;
        }
@@ -213,15 +239,19 @@ 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) {
-                       printf("rpc_procdess_reply failed\n");
+                       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;
        }
-       printf("No matching pdu found for xid:%d\n", xid);
+       rpc_set_error(rpc, "No matching pdu found for xid:%d", xid);
        xdr_destroy(&xdr);
        return -1;
 }