/*
 * nasd_pdrive_client_dce.c
 *
 * Wrappers for new drive RPCs
 *
 * Author: Jim Zelenka
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1997,1998,1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */

#include <nasd/nasd_options.h>
#if NASD_RPC_PACKAGE == NASD_RPC_PACKAGE_DCE
#include <dce/dce_error.h>
#include <nasd/nasd_freelist.h>
#include <nasd/nasd_pdrive_client.h>
#include <nasd/nasd_pdrive_client_dce.h>
#include <nasd/nasd_marshall.h>
#include <nasd/nasd_security.h>
#include <nasd/nasd_security_cl.h>
#include <nasd/nasd_nonce_mgmt.h>
#include <nasd/nasd_mem.h>
#include <sys/errno.h>

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#ifdef _KERNEL

#include <dce/ker/pthread_exc.h>

/* this doesnt exist in the kernel DCE header files for whatever reason */
#define exc_get_status(e,s) ( \
   (e)->kind == _exc_kind_status ? \
        (*(s) = (e)->match.value, 0) : \
        -1)

#endif /* _KERNEL */

#define NASD_DCE_SEC_OP_DECL \
        nasd_security_param_otw_t sec_param_otw; \
        nasd_capability_otw_t capability_otw; \
        nasd_digest_nonce_otw_t args_digest_otw; \
        nasd_digest_nonce_otw_t res_digest_otw; \
        nasd_iv_t icv; \
        nasd_status_t sec_rc;

#define NASD_DCE_OP_DECL \
        NASD_DCE_SEC_OP_DECL



nasd_status_t
nasd_cl_dce_init(
  nasd_shutdown_list_t  *sl)
{
  nasd_status_t rc;

  rc = nasd_cl_pipe_init(sl);
  if (rc)
    return(rc);

  return(NASD_SUCCESS);
}

nasd_status_t
nasd_cl_dce_bind(
  nasd_drive_handle_t   handle,
  char                 *drive_name,
  char                 *portnum,
  int                   binding_type,
  void                 *binding_param,
  int                   binding_param_len)
{
  nasd_drive_handle_dce_t *rpch;
  nasd_status_t rc;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  if (binding_type == NASD_BIND_DCE_DIRECT_TCP) {
    rc = nasd_dce_direct_bind_to_server((unsigned_char_t *)"ncadg_ip_tcp",
      (unsigned_char_t *)drive_name, (unsigned_char_t *)portnum,
      &rpch->h);
  } else if (binding_type == NASD_BIND_DCE_DIRECT_UDP) {
    rc = nasd_dce_direct_bind_to_server((unsigned_char_t *)"ncadg_ip_udp",
      (unsigned_char_t *)drive_name, (unsigned_char_t *)portnum,
      &rpch->h);
  }
  else {
    rc = NASD_BAD_HANDLE_TYPE;
  }
  if (rc) {
    return(rc);
  }

  return(NASD_SUCCESS);
}

nasd_status_t
nasd_cl_dce_unbind(
  nasd_drive_handle_t  handle)
{
  nasd_drive_handle_dce_t *rpch;
  int ret;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  ret = nasd_dce_direct_unbind_server(&rpch->h);
  if (ret)
    return(NASD_FAIL);

  return(NASD_SUCCESS);
}

void
nasd_cl_p_fr_alloc(state, bsize, buf, bcount)
  rpc_ss_pipe_state_t    state;
  unsigned int           bsize;
  nasd_byte_t          **buf;
  unsigned int          *bcount;
{
  nasd_cl_fo_state_t *s;
  nasd_uint32 bc;

  s = (nasd_cl_fo_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_read_alloc(s, bsize, buf, &bc);
  *bcount = bc;
}

void
nasd_cl_p_fw_alloc(state, bsize, buf, bcount)
  rpc_ss_pipe_state_t    state;
  unsigned int           bsize;
  nasd_byte_t          **buf;
  unsigned int          *bcount;
{
  nasd_cl_fo_state_t *s;
  nasd_uint32 bc;

  s = (nasd_cl_fo_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_write_alloc(s, bsize, buf, &bc);
  *bcount = bc;
}

void
nasd_cl_p_fr_push(state, buf, count)
  rpc_ss_pipe_state_t  *state;
  idl_char             *buf;
  unsigned32            count;
{
  nasd_cl_fo_state_t *s;

  s = (nasd_cl_fo_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_read_push(s, buf, count);
}

void
nasd_cl_p_fw_pull(
  rpc_ss_pipe_state_t  *state,
  idl_char             *buf,
  unsigned32            in_count,
  unsigned32           *out_countp)
{
  nasd_cl_fo_state_t *s;

  s = (nasd_cl_fo_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_write_pull(s, buf, in_count, out_countp);
}

void
nasd_cl_p_fr_list_alloc(
  rpc_ss_pipe_state_t    state,
  unsigned int           bsize,
  nasd_byte_t          **buf,
  unsigned int          *bcount)
{
  nasd_cl_fo_list_state_t *s;
  nasd_uint32 bc;

  s = (nasd_cl_fo_list_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_read_alloc_list(s, bsize, buf, &bc);
  *bcount = bc;
}


void
nasd_cl_p_fw_list_alloc(
  rpc_ss_pipe_state_t    state,
  unsigned int           bsize,
  nasd_byte_t          **buf,
  unsigned int          *bcount)
{
  nasd_cl_fo_list_state_t *s;
  nasd_uint32 bc;

  s = (nasd_cl_fo_list_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_write_alloc_list(s, bsize, buf, &bc);
  *bcount = bc;
}

void
nasd_cl_p_fr_list_push(
  rpc_ss_pipe_state_t  *state,
  idl_char             *buf,
  unsigned32            count)
{
  nasd_cl_fo_list_state_t *s;

  s = (nasd_cl_fo_list_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_read_push_list(s, buf, count);
}

void
nasd_cl_p_fw_list_pull(
  rpc_ss_pipe_state_t  *state,
  idl_char             *buf,
  unsigned32            in_count,
  unsigned32           *out_countp)
{
  nasd_cl_fo_list_state_t *s;

  s = (nasd_cl_fo_list_state_t *)state;
  NASD_ASSERT(s->dce_bug != 0);

  nasd_pipe_cb_write_pull_list(s, buf, in_count, out_countp);
}

/*
 * BEGIN RPC WRAPPERS
 *
 * If the status field is set in a call to these routines (ie:
 * an RPC failure occurs) then the nasd_status is considered meaningless.
 */

void
nasd_cl_prpc_null_dr(
  nasd_drive_handle_t    handle,
  nasd_res_t            *res,
  error_status_t        *status)
{
  nasd_drive_handle_dce_t *rpch;
  nasd_res_otw_t res_otw;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  TRY {
    nasd_p_null_dr(rpch->h, res_otw, status);
    nasd_res_t_unmarshall(res_otw, res);
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_sync_dr(
  nasd_drive_handle_t    handle,
  nasd_res_t            *res,
  error_status_t        *status)
{
  nasd_drive_handle_dce_t *rpch;
  nasd_res_otw_t res_otw;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  TRY {
    nasd_p_sync_dr(rpch->h, res_otw, status);
    nasd_res_t_unmarshall(res_otw, res);
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_part_creat_dr(
  nasd_drive_handle_t           handle,
  nasd_key_t                    in_key,
  nasd_security_param_t        *sec_param,
  nasd_capability_t            *capability,
  nasd_p_part_creat_dr_args_t  *args,
  nasd_p_part_creat_dr_res_t   *res,
  error_status_t               *status)
{
  nasd_p_part_creat_dr_args_otw_t args_otw;
  nasd_p_part_creat_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_part_creat_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_part_creat_otw_dr(rpch->h, sec_param_otw, capability_otw,
                             args_digest_otw, args_otw, res_otw,
                             res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_part_creat_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_create_dr__otw_provided(
  nasd_drive_handle_t       handle,
  nasd_key_t                in_key,
  nasd_security_param_t    *sec_param,
  nasd_capability_t        *capability,
  nasd_p_create_dr_args_t  *args,
  nasd_p_create_dr_res_t   *res,
  nasd_cl_p_otw_buf_t      *otw,
  error_status_t           *status)
{
  nasd_drive_handle_dce_t *rpch;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 otw->sec_param_otw, otw->capability_otw,
                 otw->args_digest_otw, otw->args_otw,
                 sizeof(nasd_p_create_dr_args_otw_t),
                 nasd_p_create_dr_args_t_marshall,
                 otw->icv, in_key, NULL);

  TRY {
    nasd_p_create_otw_dr(rpch->h, otw->sec_param_otw, otw->capability_otw,
                         otw->args_digest_otw, otw->args_otw, otw->res_otw,
                         otw->res_digest_otw, status);

    otw->sec_rc = nasd_unpack_res(handle,
                                  sec_param, capability, otw->res_otw,
                                  sizeof(nasd_p_create_dr_res_otw_t),
                                  otw->res_digest_otw, res,
                                  nasd_p_create_dr_res_t_unmarshall,
                                  otw->icv, in_key, NULL);
    if(otw->sec_rc) {
      res->nasd_status = otw->sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_getattr_dr(
  nasd_drive_handle_t        handle,
  nasd_key_t                 in_key,
  nasd_security_param_t     *sec_param,
  nasd_capability_t         *capability,
  nasd_p_getattr_dr_args_t  *args,
  nasd_p_getattr_dr_res_t   *res,
  error_status_t            *status)
{
  nasd_p_getattr_dr_args_otw_t args_otw;
  nasd_p_getattr_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_getattr_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_getattr_otw_dr(rpch->h, sec_param_otw, capability_otw,
                          args_digest_otw, args_otw, res_otw,
                          res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_getattr_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_range_read_dr(
  nasd_drive_handle_t        handle,
  nasd_key_t                 in_key,
  nasd_security_param_t     *sec_param,
  nasd_capability_t         *capability,
  int                        is_read2,
  nasd_p_smpl_op_dr_args_t  *args,
  nasd_mem_list_t           *memlist,
  nasd_p_fastread_dr_res_t  *res,
  error_status_t            *status)
{
  nasd_p_smpl_op_dr_args_otw_t args_otw;
  nasd_p_fastread_dr_res_otw_t res_otw;
  nasd_cl_fo_list_state_t *statep;
  nasd_byte_pipe_t pipe;
  nasd_drive_handle_dce_t *rpch;
  nasd_len_t out_len;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  out_len = 0;
  res->out_datalen = 0;

  res->nasd_status = nasd_check_mem_list(memlist);
  if (res->nasd_status) {
    return;
  }

  NASD_FREELIST_GET(nasd_cl_fo_list_state_freelist, statep, push_cur,
                    (nasd_cl_fo_list_state_t *));
  if (statep == NULL) {
    res->nasd_status = NASD_NO_MEM;
    *status = 0;
    return;
  }

  bzero(&statep->context, sizeof(nasd_security_context_t));
  statep->dce_bug = 1;
  statep->out_lenp = &out_len;
  statep->targetlen = args->in_len;
  statep->badstate = 0;
  statep->alloc_buf = statep->push_buf = memlist->addr;
  statep->alloc_len = statep->push_len = memlist->len;
  statep->alloc_cur = statep->push_cur = memlist;
  statep->alloc_elem = statep->push_elem = 0;
  statep->alloc_off = statep->push_off = 0;
  statep->push_adj = args->in_offset;
  statep->status = NASD_SUCCESS;

  pipe.state = (rpc_ss_pipe_state_t)statep;
  pipe.alloc = (void (*)())nasd_cl_p_fr_list_alloc;
  pipe.push = (void (*)())nasd_cl_p_fr_list_push;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_smpl_op_dr_args_t_marshall,
                 icv, in_key, &statep->context);

  TRY {
    if (is_read2) {
      nasd_p_read2_simple_otw_dr(rpch->h, sec_param_otw, capability_otw,
                                 args_digest_otw, args_otw, pipe, res_otw,
                                 res_digest_otw, status);
    }
    else {
      nasd_p_read_simple_otw_dr(rpch->h, sec_param_otw, capability_otw,
                                args_digest_otw, args_otw, pipe, res_otw,
                                res_digest_otw, status);
    }

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_fastread_dr_res_t_unmarshall,
                             icv, in_key, &statep->context);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }

  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY

  if (statep->status || statep->badstate) {
    if(statep->status)
      res->nasd_status = statep->status;
    else
      res->nasd_status = NASD_MEM_LIST_ERR;
  }
  NASD_FREELIST_FREE(nasd_cl_fo_list_state_freelist, statep, push_cur);
}

void
nasd_cl_prpc_range_tread_dr(
  nasd_drive_handle_t         handle,
  nasd_key_t                  in_key,
  nasd_security_param_t      *sec_param,
  nasd_capability_t          *capability,
  int                         is_read2,
  nasd_p_thrtl_op_dr_args_t  *args,
  nasd_mem_list_t            *memlist,
  nasd_p_fastread_dr_res_t   *res,
  error_status_t             *status)
{
  nasd_p_thrtl_op_dr_args_otw_t args_otw;
  nasd_p_fastread_dr_res_otw_t res_otw;
  nasd_cl_fo_list_state_t *statep;
  nasd_byte_pipe_t pipe;
  nasd_drive_handle_dce_t *rpch;
  nasd_len_t out_len;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;
  out_len = 0;
  res->out_datalen = 0;

  if (is_read2) {
    res->nasd_status = NASD_OP_NOT_SUPPORTED;
    return;
  }

  res->nasd_status = nasd_check_mem_list(memlist);
  if (res->nasd_status) {
    return;
  }

  NASD_FREELIST_GET(nasd_cl_fo_list_state_freelist, statep, push_cur,
                    (nasd_cl_fo_list_state_t *));
  if (statep == NULL) {
    res->nasd_status = NASD_NO_MEM;
    *status = 0;
    return;
  }

  statep->dce_bug = 1;
  statep->out_lenp = &out_len;
  statep->targetlen = args->in_len;
  statep->badstate = 0;
  statep->alloc_buf = statep->push_buf = memlist->addr;
  statep->alloc_len = statep->push_len = memlist->len;
  statep->alloc_cur = statep->push_cur = memlist;
  statep->alloc_elem = statep->push_elem = 0;
  statep->alloc_off = statep->push_off = 0;
  statep->push_adj = args->in_offset;
  statep->status = NASD_SUCCESS;

  pipe.state = (rpc_ss_pipe_state_t)statep;
  pipe.alloc = (void (*)())nasd_cl_p_fr_list_alloc;
  pipe.push = (void (*)())nasd_cl_p_fr_list_push;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_thrtl_op_dr_args_t_marshall,
                 icv, in_key, &statep->context);

  TRY {
    nasd_p_tread_simple_otw_dr(rpch->h, sec_param_otw, capability_otw,
                               args_digest_otw, args_otw, pipe, res_otw,
                               res_digest_otw, status);
    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_fastread_dr_res_t_unmarshall,
                             icv, in_key, &statep->context);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY

  if (statep->status || statep->badstate) {
    if(statep->status)
      res->nasd_status = statep->status;
    else
      res->nasd_status = NASD_MEM_LIST_ERR;
  }
  NASD_FREELIST_FREE(nasd_cl_fo_list_state_freelist, statep, push_cur);
}

void
nasd_cl_prpc_range_write_dr(
  nasd_drive_handle_t         handle,
  nasd_key_t                  in_key,
  nasd_security_param_t      *sec_param,
   nasd_capability_t          *capability,
  nasd_p_smpl_op_dr_args_t   *args,
  nasd_mem_list_t            *memlist,
  nasd_p_fastwrite_dr_res_t  *res,
  error_status_t             *status)
{
  nasd_p_smpl_op_dr_args_otw_t args_otw;
  nasd_p_fastwrite_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  nasd_cl_fo_list_state_t *statep;
  nasd_byte_pipe_t pipe;
  nasd_len_t out_len;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;
  out_len = 0;
  res->out_datalen = 0;

  res->nasd_status = nasd_check_mem_list(memlist);
  if (res->nasd_status) {
    return;
  }
  
  NASD_FREELIST_GET(nasd_cl_fo_list_state_freelist, statep, push_cur,
                    (nasd_cl_fo_list_state_t *));
  if (statep == NULL) {
    res->nasd_status = NASD_NO_MEM;
    *status = 0;
    return;
  }

  bzero(&statep->context, sizeof(nasd_security_context_t));
  statep->dce_bug = 1;
  statep->out_lenp = &out_len;
  statep->targetlen = args->in_len;
  statep->badstate = 0;
    statep->alloc_cur = statep->push_cur = memlist;
    statep->alloc_buf = statep->push_buf = memlist->addr;
    statep->alloc_len = statep->push_len = memlist->len;
  statep->alloc_elem = statep->push_elem = 0;
  statep->alloc_off = statep->push_off = 0;
  statep->alloc_adj = statep->push_adj = args->in_offset;
  statep->digest_alloc_cur = statep->digest_pull_cur = NULL;
  statep->alloc_digest = statep->pull_digest = 0;
  statep->next_alloc_digest_off = statep->next_pull_digest_off =
    ((args->in_offset/NASD_SEC_HMAC_BLOCKSIZE)+1) * NASD_SEC_HMAC_BLOCKSIZE;
  statep->status = NASD_SUCCESS;

  pipe.state = (rpc_ss_pipe_state_t)statep;
  pipe.alloc = (void (*)())nasd_cl_p_fw_list_alloc;
  pipe.pull = (void (*)())nasd_cl_p_fw_list_pull;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_smpl_op_dr_args_t_marshall,
                 icv, in_key, &statep->context);
  TRY {
    nasd_p_write_simple_otw_dr(rpch->h, sec_param_otw, capability_otw,
                               args_digest_otw, args_otw, pipe, res_otw,
                               res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_fastwrite_dr_res_t_unmarshall,
                             icv, in_key, &statep->context);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY


  if (statep->status || statep->badstate) {
    if(statep->status)
      res->nasd_status = statep->status;
    else
      res->nasd_status = NASD_MEM_LIST_ERR;
  }
  NASD_FREELIST_FREE(nasd_cl_fo_list_state_freelist, statep, push_cur);
}

void
nasd_cl_prpc_setattr_dr__otw_provided(
  nasd_drive_handle_t        handle,
  nasd_key_t                 in_key,
  nasd_security_param_t     *sec_param,
  nasd_capability_t         *capability,
  nasd_p_setattr_dr_args_t  *args,
  nasd_p_setattr_dr_res_t   *res,
  nasd_cl_p_otw_buf_t       *otw,
  error_status_t            *status)
{
  nasd_drive_handle_dce_t *rpch;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 otw->sec_param_otw, otw->capability_otw,
                 otw->args_digest_otw, otw->args_otw,
                 sizeof(nasd_p_setattr_dr_args_otw_t),
                 nasd_p_setattr_dr_args_t_marshall,
                 otw->icv, in_key, NULL);

  TRY {
    nasd_p_setattr_otw_dr(rpch->h, otw->sec_param_otw, otw->capability_otw,
                          otw->args_digest_otw, otw->args_otw, otw->res_otw,
                          otw->res_digest_otw, status);

    otw->sec_rc = nasd_unpack_res(handle,
                                  sec_param, capability, otw->res_otw,
                                  sizeof(nasd_p_setattr_dr_res_otw_t),
                                  otw->res_digest_otw, res,
                                  nasd_p_setattr_dr_res_t_unmarshall,
                                  otw->icv, in_key, NULL);
    if(otw->sec_rc) {
      res->nasd_status = otw->sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_flush_obj_dr(
  nasd_drive_handle_t          handle,
  nasd_key_t                   in_key,
  nasd_security_param_t       *sec_param,
  nasd_capability_t           *capability,
  nasd_p_flush_obj_dr_args_t  *args,
  nasd_p_flush_obj_dr_res_t   *res,
  error_status_t              *status)
{
  nasd_p_flush_obj_dr_args_otw_t args_otw;
  nasd_p_flush_obj_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_flush_obj_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_flush_obj_otw_dr(rpch->h, sec_param_otw, capability_otw,
                            args_digest_otw, args_otw,res_otw,
                            res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_flush_obj_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_eject_obj_dr(
  nasd_drive_handle_t          handle,
  nasd_key_t                   in_key,
  nasd_security_param_t        *sec_param,
  nasd_capability_t            *capability,
  nasd_p_eject_obj_dr_args_t  *args,
  nasd_p_eject_obj_dr_res_t   *res,
  error_status_t              *status)
{
  nasd_p_eject_obj_dr_args_otw_t args_otw;
  nasd_p_eject_obj_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_eject_obj_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_eject_obj_otw_dr(rpch->h, sec_param_otw, capability_otw,
                            args_digest_otw, args_otw,res_otw,
                            res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_eject_obj_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_remove_dr(
  nasd_drive_handle_t       handle,
  nasd_key_t                in_key,
  nasd_security_param_t    *sec_param,
  nasd_capability_t        *capability,
  nasd_p_remove_dr_args_t  *args,
  nasd_p_remove_dr_res_t   *res,
  error_status_t           *status)
{
  nasd_p_remove_dr_args_otw_t args_otw;
  nasd_p_remove_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_remove_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_remove_otw_dr(rpch->h, sec_param_otw, capability_otw,
                         args_digest_otw, args_otw, res_otw,
                         res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_remove_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_initialize_dr(
  nasd_drive_handle_t           handle,
  nasd_p_initialize_dr_args_t  *args,
  nasd_p_initialize_dr_res_t   *res,
  error_status_t               *status)
{
  nasd_p_initialize_dr_args_otw_t args_otw;
  nasd_p_initialize_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_p_initialize_dr_args_t_marshall(args, args_otw);

  TRY {
    nasd_p_initialize_otw_dr(rpch->h, args_otw, res_otw, status);
    nasd_p_initialize_dr_res_t_unmarshall(res_otw, res);
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_strt_iread_dr(
  nasd_drive_handle_t           handle,
  nasd_key_t                    in_key,
  nasd_security_param_t        *sec_param,
  nasd_capability_t            *capability,
  nasd_p_strt_iread_dr_args_t  *args,
  nasd_p_strt_iread_dr_res_t   *res,
  error_status_t               *status)
{
  nasd_p_strt_iread_dr_args_otw_t args_otw;
  nasd_p_strt_iread_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_strt_iread_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_strt_iread_otw_dr(rpch->h, sec_param_otw, capability_otw,
                             args_digest_otw, args_otw, res_otw,
                             res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_strt_iread_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_stop_iread_dr(
  nasd_drive_handle_t           handle,
  nasd_key_t                    in_key,
  nasd_security_param_t        *sec_param,
  nasd_capability_t            *capability,
  nasd_p_stop_iread_dr_args_t  *args,
  nasd_p_stop_iread_dr_res_t   *res,
  error_status_t               *status)
{
  nasd_p_stop_iread_dr_args_otw_t args_otw;
  nasd_p_stop_iread_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_stop_iread_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_stop_iread_otw_dr(rpch->h, sec_param_otw, capability_otw,
                             args_digest_otw, args_otw, res_otw,
                             res_digest_otw, status);

    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_stop_iread_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_rshutdown_dr(
  nasd_drive_handle_t          handle,
  nasd_key_t                   in_key,
  nasd_security_param_t       *sec_param,
  nasd_capability_t           *capability,
  nasd_p_rshutdown_dr_args_t  *args,
  nasd_p_rshutdown_dr_res_t   *res,
  error_status_t              *status)
{
  nasd_p_rshutdown_dr_args_otw_t args_otw;
  nasd_p_rshutdown_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;
  NASD_DCE_OP_DECL

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  nasd_pack_args(handle, sec_param, capability, args,
                 sec_param_otw, capability_otw,
                 args_digest_otw, args_otw, sizeof(args_otw),
                 nasd_p_rshutdown_dr_args_t_marshall,
                 icv, in_key, NULL);

  TRY {
    nasd_p_rshutdown_otw_dr(rpch->h, sec_param_otw, capability_otw,
                            args_digest_otw, args_otw, res_otw,
                            res_digest_otw, status);
    sec_rc = nasd_unpack_res(handle,
                             sec_param, capability, res_otw, sizeof(res_otw),
                             res_digest_otw, res,
                             nasd_p_rshutdown_dr_res_t_unmarshall,
                             icv, in_key, NULL);
    if(sec_rc) {
      res->nasd_status = sec_rc;
    }
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_prpc_getinfo_dr(
  nasd_drive_handle_t       handle,
  nasd_p_getinfo_dr_res_t  *res,
  error_status_t           *status)
{
  nasd_p_getinfo_dr_res_otw_t res_otw;
  nasd_drive_handle_dce_t *rpch;

  rpch = (nasd_drive_handle_dce_t *)handle->rpc_specific_handle;

  TRY {
    nasd_p_getinfo_otw_dr(rpch->h, res_otw, status);
    nasd_p_getinfo_dr_res_t_unmarshall(res_otw, res);
  }
  CATCH_ALL {
    res->nasd_status = NASD_RPC_TRAP;
    exc_get_status(THIS_CATCH,(int *)status);
  } ENDTRY
}

void
nasd_cl_dce_error_string(
  nasd_drive_handle_t   handle,
  nasd_rpc_status_t     status,
  nasd_error_string_t   str,
  char                 *file,
  int                   line)
{
  int dce_ps;

  dce_error_inq_text(status, (unsigned char *)str, &dce_ps);
  if (dce_ps) {
    sprintf(str, "Unknown DCE status 0x%x", status);
  }
}

nasd_cl_p_rpcmod_tab_t nasd_cl_dce_udp_mod = {
  nasd_cl_dce_init,
  NASD_RPCMOD_INIT_FAIL,

  nasd_cl_dce_bind,
  nasd_cl_dce_unbind,

  nasd_cl_prpc_null_dr,
  nasd_cl_prpc_sync_dr,
  nasd_cl_prpc_part_creat_dr,
  nasd_cl_prpc_getattr_dr,
  NULL, /* write_simple */
  nasd_cl_prpc_range_write_dr,
  NULL, /* read_simple */
  nasd_cl_prpc_range_read_dr,
  NULL, /* tread_simple */
  nasd_cl_prpc_range_tread_dr,
  nasd_cl_prpc_flush_obj_dr,
  nasd_cl_prpc_eject_obj_dr,
  nasd_cl_prpc_remove_dr,
  nasd_cl_prpc_initialize_dr,
  nasd_cl_prpc_strt_iread_dr,
  nasd_cl_prpc_stop_iread_dr,
  nasd_cl_prpc_rshutdown_dr,
  nasd_cl_prpc_getinfo_dr,

  nasd_cl_prpc_create_dr__otw_provided,
  nasd_cl_prpc_setattr_dr__otw_provided,

  nasd_cl_dce_error_string,

  NASD_BIND_DCE_DIRECT_UDP,
  "DCE-UDP",
  sizeof(nasd_drive_handle_dce_t),

  NULL
};

nasd_cl_p_rpcmod_tab_t nasd_cl_dce_tcp_mod = {
  NULL,
  NASD_RPCMOD_INIT_FAIL,

  nasd_cl_dce_bind,
  nasd_cl_dce_unbind,

  nasd_cl_prpc_null_dr,
  nasd_cl_prpc_sync_dr,
  nasd_cl_prpc_part_creat_dr,
  nasd_cl_prpc_getattr_dr,
  NULL, /* write_simple */
  nasd_cl_prpc_range_write_dr,
  NULL, /* read_simple */
  nasd_cl_prpc_range_read_dr,
  NULL, /* tread_simple */
  nasd_cl_prpc_range_tread_dr,
  nasd_cl_prpc_flush_obj_dr,
  nasd_cl_prpc_eject_obj_dr,
  nasd_cl_prpc_remove_dr,
  nasd_cl_prpc_initialize_dr,
  nasd_cl_prpc_strt_iread_dr,
  nasd_cl_prpc_stop_iread_dr,
  nasd_cl_prpc_rshutdown_dr,
  nasd_cl_prpc_getinfo_dr,

  nasd_cl_prpc_create_dr__otw_provided,
  nasd_cl_prpc_setattr_dr__otw_provided,

  nasd_cl_dce_error_string,

  NASD_BIND_DCE_DIRECT_TCP,
  "DCE-TCP",
  sizeof(nasd_drive_handle_dce_t),

  NULL
};

void
nasd_cl_p_dce_register(
  int  counter_lock_held)
{
  nasd_cl_p_mod_register(&nasd_cl_dce_udp_mod, counter_lock_held);
  nasd_cl_p_mod_register(&nasd_cl_dce_tcp_mod, counter_lock_held);
}
#endif /* NASD_RPC_PACKAGE == NASD_RPC_PACKAGE_DCE */

/* Local Variables:  */
/* indent-tabs-mode: nil */
/* tab-width: 2 */
/* End: */
