fix implicit decl warnings
[deb_libnfs.git] / lib / libnfs-zdr.c
index e439249abb7b67cd506a94960b1cc96e3fc1082b..b6b3ed984bfc35edcf2ed3e0be693861cf88500b 100644 (file)
  * i.e. zdrmem_create() buffers.
  * It aims to be compatible with normal rpcgen generated functions.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include "win32_compat.h"
+#endif
+
+#ifdef AROS
+#include "aros_compat.h"
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
 
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
+#include <unistd.h>
 #include "libnfs-zdr.h"
 
 struct opaque_auth _null_auth;
@@ -116,7 +133,7 @@ bool_t libnfs_zdr_u_quad_t(ZDR *zdrs, uint64_t *u)
                *u = ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]);
                zdrs->pos += 4;
                *u <<= 32;
-               *u |= ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]);
+               *u |= (uint32_t)ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]);
                zdrs->pos += 4;
                return TRUE;
                break;
@@ -160,9 +177,15 @@ bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize
 }
 
 
-bool_t libnfs_zdr_enum(ZDR *zdrs, int32_t *e)
+bool_t libnfs_zdr_enum(ZDR *zdrs, enum_t *e)
 {
-       return libnfs_zdr_u_int(zdrs, (uint32_t *)e);
+       bool_t ret;
+       int32_t i = *e;
+
+       ret = libnfs_zdr_u_int(zdrs, (uint32_t *)&i);
+       *e = i;
+
+       return ret;     
 }
 
 bool_t libnfs_zdr_bool(ZDR *zdrs, bool_t *b)
@@ -205,6 +228,9 @@ bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size)
        case ZDR_ENCODE:
                memcpy(&zdrs->buf[zdrs->pos], objp, size);
                zdrs->pos += size;
+               if (zdrs->pos & 3) {
+                       memset(&zdrs->buf[zdrs->pos], 0x00, 4 - (zdrs->pos & 3));
+               }
                zdrs->pos = (zdrs->pos + 3) & ~3;
                return TRUE;
        case ZDR_DECODE:
@@ -269,7 +295,7 @@ bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize
        }
 
        for (i = 0; i < *size; i++) {
-               if (proc(zdrs, *arrp + i * elsize)) {
+               if (!proc(zdrs, *arrp + i * elsize)) {
                        return FALSE;
                }
        }
@@ -286,36 +312,48 @@ static bool_t libnfs_opaque_auth(ZDR *zdrs, struct opaque_auth *auth)
                return FALSE;
        }
 
-       if (!libnfs_zdr_bytes(zdrs, &auth->oa_base, &auth->oa_length, &auth->oa_length)) {
+       if (!libnfs_zdr_bytes(zdrs, &auth->oa_base, &auth->oa_length, auth->oa_length)) {
                return FALSE;
        }
 
        return TRUE;
 }
 
-static bool_t libnfs_rpc_call_body(ZDR *zdrs, struct call_body *cmb)
+static bool_t libnfs_rpc_call_body(struct rpc_context *rpc, ZDR *zdrs, struct call_body *cmb)
 {
-       if (!libnfs_zdr_u_int(zdrs, &cmb->cb_rpcvers)) {
+       if (!libnfs_zdr_u_int(zdrs, &cmb->rpcvers)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "RPCVERS");
                return FALSE;
        }
 
-       if (!libnfs_zdr_u_int(zdrs, &cmb->cb_prog)) {
+       if (!libnfs_zdr_u_int(zdrs, &cmb->prog)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "PROG");
                return FALSE;
        }
 
-       if (!libnfs_zdr_u_int(zdrs, &cmb->cb_vers)) {
+       if (!libnfs_zdr_u_int(zdrs, &cmb->vers)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "VERS");
                return FALSE;
        }
 
-       if (!libnfs_zdr_u_int(zdrs, &cmb->cb_proc)) {
+       if (!libnfs_zdr_u_int(zdrs, &cmb->proc)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "PROC");
                return FALSE;
        }
 
-       if (!libnfs_opaque_auth(zdrs, &cmb->cb_cred)) {
+       if (!libnfs_opaque_auth(zdrs, &cmb->cred)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "CRED");
                return FALSE;
        }
 
-       if (!libnfs_opaque_auth(zdrs, &cmb->cb_verf)) {
+       if (!libnfs_opaque_auth(zdrs, &cmb->verf)) {
+               rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode "
+                       "VERF");
                return FALSE;
        }
 
@@ -324,25 +362,25 @@ static bool_t libnfs_rpc_call_body(ZDR *zdrs, struct call_body *cmb)
 
 static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar)
 {
-       if (!libnfs_opaque_auth(zdrs, &ar->ar_verf)) {
+       if (!libnfs_opaque_auth(zdrs, &ar->verf)) {
                return FALSE;
        }
 
-       if (!libnfs_zdr_u_int(zdrs, &ar->ar_stat)) {
+       if (!libnfs_zdr_u_int(zdrs, &ar->stat)) {
                return FALSE;
        }
 
-       switch (ar->ar_stat) {
+       switch (ar->stat) {
        case SUCCESS:
-               if (!ar->ar_results.proc(zdrs, ar->ar_results.where)) {
+               if (!ar->reply_data.results.proc(zdrs, ar->reply_data.results.where)) {
                        return FALSE;
                }
                return TRUE;
        case PROG_MISMATCH:
-               if (!libnfs_zdr_u_int(zdrs, &ar->ar_vers.low)) {
+               if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.low)) {
                        return FALSE;
                }
-               if (!libnfs_zdr_u_int(zdrs, &ar->ar_vers.high)) {
+               if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.high)) {
                        return FALSE;
                }
                return TRUE;
@@ -353,71 +391,114 @@ static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar)
        return FALSE;
 }
 
-static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *RP_dr)
+static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *rr)
 {
-printf("rejected reply\n");
-exit(10);
+       if (!libnfs_zdr_u_int(zdrs, &rr->stat)) {
+               return FALSE;
+       }
+
+       switch (rr->stat) {
+       case RPC_MISMATCH:
+               if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.low)) {
+                       return FALSE;
+               }
+               if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.high)) {
+                       return FALSE;
+               }
+               return TRUE;
+       case AUTH_ERROR:
+               if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.stat)) {
+                       return FALSE;
+               }
+               return TRUE;
+       default:
+               return TRUE;
+       }
+
+       return FALSE;
 }
 
-static bool_t libnfs_rpc_reply_body(ZDR *zdrs, struct reply_body *rmb)
+static bool_t libnfs_rpc_reply_body(struct rpc_context *rpc, ZDR *zdrs, struct reply_body *rmb)
 {
-       if (!libnfs_zdr_u_int(zdrs, &rmb->rp_stat)) {
+       if (!libnfs_zdr_u_int(zdrs, &rmb->stat)) {
+               rpc_set_error(rpc, "libnfs_rpc_reply_body failed to decode "
+                       "STAT");
                return FALSE;
        }
 
-       switch (rmb->rp_stat) {
+       switch (rmb->stat) {
        case MSG_ACCEPTED:
-               if (!libnfs_accepted_reply(zdrs, &rmb->rp_acpt)) {
+               if (!libnfs_accepted_reply(zdrs, &rmb->reply.areply)) {
+                       rpc_set_error(rpc, "libnfs_rpc_reply_body failed to "
+                               "decode ACCEPTED");
                        return FALSE;
                }
                return TRUE;
        case MSG_DENIED:
-               if (!libnfs_rejected_reply(zdrs, &rmb->rp_rjct)) {
+               if (!libnfs_rejected_reply(zdrs, &rmb->reply.rreply)) {
+                       rpc_set_error(rpc, "libnfs_rpc_reply_body failed to "
+                               "decode DENIED");
                        return FALSE;
                }
                return TRUE;
        }
 
+       rpc_set_error(rpc, "libnfs_rpc_reply_body failed to "
+               "decode. Neither ACCEPTED nor DENIED");
        return FALSE;
 }
 
-static bool_t libnfs_rpc_msg(ZDR *zdrs, struct rpc_msg *msg)
+static bool_t libnfs_rpc_msg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg)
 {
-       if (!libnfs_zdr_u_int(zdrs, &msg->rm_xid)) {
+       int ret;
+
+       if (!libnfs_zdr_u_int(zdrs, &msg->xid)) {
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode XID");
                return FALSE;
        }
 
-       if (!libnfs_zdr_u_int(zdrs, &msg->rm_direction)) {
+       if (!libnfs_zdr_u_int(zdrs, &msg->direction)) {
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode DIRECTION");
                return FALSE;
        }
 
-       switch (msg->rm_direction) {
+       switch (msg->direction) {
        case CALL:
-               return libnfs_rpc_call_body(zdrs, &msg->ru.RM_cmb);
-               break;
+               ret = libnfs_rpc_call_body(rpc, zdrs, &msg->body.cbody);
+               if (!ret) { 
+                       rpc_set_error(rpc, "libnfs_rpc_msg failed to encode "
+                               "CALL, ret=%d: %s", ret, rpc_get_error(rpc));
+               }
+               return ret;
        case REPLY:
-               return libnfs_rpc_reply_body(zdrs, &msg->ru.RM_rmb);
-               break;
+               ret = libnfs_rpc_reply_body(rpc, zdrs, &msg->body.rbody);
+               if (!ret) { 
+                       rpc_set_error(rpc, "libnfs_rpc_msg failed to decode "
+                               "REPLY, ret=%d: %s", ret, rpc_get_error(rpc));
+               }
+               return ret;
        default:
+               rpc_set_error(rpc, "libnfs_rpc_msg failed to decode. "
+                       "Neither CALL not REPLY");
                return FALSE;
        }
 }
 
-bool_t libnfs_zdr_callmsg(ZDR *zdrs, struct rpc_msg *msg)
+bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg)
 {
-       return libnfs_rpc_msg(zdrs, msg);
+       return libnfs_rpc_msg(rpc, zdrs, msg);
 }
 
-bool_t libnfs_zdr_replymsg(ZDR *zdrs, struct rpc_msg *msg)
+bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg)
 {
-       return libnfs_rpc_msg(zdrs, msg);
+       return libnfs_rpc_msg(rpc, zdrs, msg);
 }
 
-AUTH *authnone_create(void)
+struct AUTH *authnone_create(void)
 {
-       AUTH *auth;
+       struct AUTH *auth;
 
-       auth = malloc(sizeof(AUTH));
+       auth = malloc(sizeof(struct AUTH));
 
        auth->ah_cred.oa_flavor = AUTH_NONE;
        auth->ah_cred.oa_length = 0;
@@ -432,20 +513,22 @@ AUTH *authnone_create(void)
        return auth;
 }
 
-AUTH *libnfs_authunix_create(char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups)
+struct AUTH *libnfs_authunix_create(char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups)
 {
-       AUTH *auth;
+       struct AUTH *auth;
        int size;
        uint32_t *buf;
        int idx;
 
        size = 4 + 4 + ((strlen(host) + 3) & ~3) + 4 + 4 + 4 + len * 4;
-       auth = malloc(sizeof(AUTH));
+       auth = malloc(sizeof(struct AUTH));
+       memset(auth, 0x00, sizeof(struct AUTH));
        auth->ah_cred.oa_flavor = AUTH_UNIX;
        auth->ah_cred.oa_length = size;
        auth->ah_cred.oa_base = malloc(size);
 
-       buf = auth->ah_cred.oa_base;
+       memset(auth->ah_cred.oa_base, 0x00, size);
+       buf = (uint32_t *)auth->ah_cred.oa_base;
        idx = 0;
        buf[idx++] = htonl(time(NULL));
        buf[idx++] = htonl(strlen(host));
@@ -468,12 +551,16 @@ AUTH *libnfs_authunix_create(char *host, uint32_t uid, uint32_t gid, uint32_t le
        return auth;
 }
 
-AUTH *libnfs_authunix_create_default(void)
+struct AUTH *libnfs_authunix_create_default(void)
 {
-       return libnfs_authunix_create("libnfs", getuid(), -1, 0, NULL);
+#ifdef WIN32
+       return libnfs_authunix_create("libnfs", 65534, 65534, 0, NULL);
+#else
+       return libnfs_authunix_create("libnfs", getuid(), getgid(), 0, NULL);
+#endif
 }
 
-void libnfs_auth_destroy(AUTH *auth)
+void libnfs_auth_destroy(struct AUTH *auth)
 {
        if (auth->ah_cred.oa_base) {
                free(auth->ah_cred.oa_base);