/*
 * nasd_edrfs_client_colocate.c
 *
 * RPC-specific "colocation" for EDRFS clients and servers
 *
 * Author: Jim Zelenka
 */
/*
 * Copyright (c) of Carnegie Mellon University, 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>
#include <nasd/nasd_edrfs_client.h>
#include <nasd/nasd_edrfs_client_colocate.h>

#include <nasd/nasd_edrfs_rpc.h>
#include <nasd/nasd_edrfs_internal.h>
#include <nasd/nasd_edrfs_server_internal.h>

/* have I mentioned that this makes me sad? */
#ifdef NASD_EDRFS_RPC_NASD_RET
#undef NASD_EDRFS_RPC_NASD_RET
#define NASD_EDRFS_RPC_NASD_RET res->nasd_status
#endif /* NASD_EDRFS_RPC_NASD_RET */

/* Don't use __FILE__ here to avoid getting kernel-mangled names */
#define NASD_EDRFS_RPC_RETURN(_statval_) { \
  *op_status = _statval_; \
  return; \
}
#define DOBEGIN(_opname_) NASD_EDRFS_RPC_DOBEGIN(_opname_,"nasd_edrfs_client_switch.c")
#define DORETURN(_opname_) NASD_EDRFS_RPC_DORETURN(_opname_,"nasd_edrfs_client_switch.c")

nasd_status_t
nasd_edrfscli_colocate_bind(
  nasd_edrfs_handle_t   handle,
  char                 *server_name,
  char                 *portnum,
  int                   binding_type,
  void                 *binding_param,
  int                   binding_param_len)
{
  return(NASD_SUCCESS);
}

nasd_status_t
nasd_edrfscli_colocate_unbind(
  nasd_edrfs_handle_t  handle)
{
  return(NASD_SUCCESS);
}

void
nasd_edrfscli_colocate_null(
  nasd_edrfs_handle_t   handle,
  nasd_res_t           *res,
  nasd_rpc_status_t    *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(null);
  res->nasd_status = NASD_SUCCESS;
  *op_status = 0;
  DORETURN(null);
}

void
nasd_edrfscli_colocate_mount(
  nasd_edrfs_handle_t       handle,
  nasd_edrfs_mount_args_t  *args,
  nasd_edrfs_mount_res_t   *res,
  nasd_rpc_status_t        *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(mount);
  nasd_edrfs_real_mount(
    args->in_credential,
    (char *)args->in_dirpath,
    NASD_EDRFS_DRIVE_LIST_LEN,
    res->out_drivelist,
    &res->out_listlen,
    &res->out_cookie,
    &res->out_identifier,
    &res->nasd_status);
  *op_status = 0;
  DORETURN(mount);
}

void
nasd_edrfscli_colocate_fsstat(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_fsstat_args_t  *args,
  nasd_edrfs_fsstat_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(fsstat);

  nasd_edrfs_real_fsstat(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    &res->out_stat,
    &res->out_attribute,
    &res->nasd_status);

  DORETURN(fsstat);
}

void
nasd_edrfscli_colocate_fsinfo(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_fsinfo_args_t  *args,
  nasd_edrfs_fsinfo_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(fsinfo);

  nasd_edrfs_real_fsinfo(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    &res->out_info,
    &res->out_attribute,
    &res->nasd_status);

  DORETURN(fsinfo);
}

void
nasd_edrfscli_colocate_lookup_otw_provided(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_lookup_args_t  *args,
  nasd_edrfs_lookup_res_t   *res,
  nasd_otw_base_t           *args_otw_p,
  nasd_otw_base_t           *res_otw_p,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(lookup);

  nasd_edrfs_real_lookup(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    (char *)args->in_dirpath,
    &res->out_cookie,
    &res->out_identifier,
    &res->out_attribute,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(lookup);
}

void
nasd_edrfscli_colocate_lookup(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_lookup_args_t  *args,
  nasd_edrfs_lookup_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(lookup);

  nasd_edrfs_real_lookup(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    (char *)args->in_dirpath,
    &res->out_cookie,
    &res->out_identifier,
    &res->out_attribute,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(lookup);
}

void
nasd_edrfscli_colocate_readdir(
  nasd_edrfs_handle_t         handle,
  nasd_edrfs_readdir_args_t  *args,
  nasd_edrfs_dirent_t        *out_entries,
  nasd_edrfs_readdir_res_t   *res,
  nasd_rpc_status_t          *op_status)
{
  nasd_edrfs_readdir_pipe_state_t state;
  nasd_procpipe_t procpipe;
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(readdir);

  state.dir_buf = out_entries;
  state.dir_buf_ents = args->in_count;
  state.dir_buf_ents_filled = 0;
  state.partial_buf_offset = 0;

  procpipe.state = &state;
  procpipe.push = nasd_copipe_readdir_push;
  procpipe.pull = NULL;
  res->out_count = 0;

  nasd_edrfs_real_readdir(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    args->in_marker,
    args->in_markerv,
    args->in_count,
    &res->out_marker,
    &res->out_markerv,
    &res->out_count,
    &res->out_eof,
    &procpipe,
    &res->post_attribute,
    &res->nasd_status);

  if (res->nasd_status == NASD_SUCCESS) {
    if (state.partial_buf_offset != 0) {
      res->nasd_status = NASD_BAD_TRANSFER_STATE;
    }
  }

  DORETURN(readdir);
}

void
nasd_edrfscli_colocate_access(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_access_args_t  *args,
  nasd_edrfs_access_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(access);

  nasd_edrfs_real_access(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    args->in_access,
    &res->out_access,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(access);
}

void
nasd_edrfscli_colocate_setattr(
  nasd_edrfs_handle_t         handle,
  nasd_edrfs_setattr_args_t  *args,
  nasd_edrfs_setattr_res_t   *res,
  nasd_rpc_status_t          *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(setattr);

  nasd_edrfs_real_setattr(
    args->in_cookie,
    args->in_identifier,
    args->in_credential,
    args->in_attribute,
    args->in_fieldmask,
    args->in_guard,
    &res->out_attribute,
    &res->nasd_status);

  DORETURN(setattr);
}

void
nasd_edrfscli_colocate_create_otw_provided(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_create_args_t  *args,
  nasd_edrfs_create_res_t   *res,
  nasd_otw_base_t           *args_otw_p,
  nasd_otw_base_t           *res_otw_p,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(create);

  nasd_edrfs_real_create(
    args->in_cookie,
    args->in_directory,
    args->in_credential,
    (char *)args->in_dirpath,
    args->in_attribute,
    args->in_fieldmask,
    &res->out_cookie,
    &res->out_identifier,
    &res->out_attribute,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(create);
}

void
nasd_edrfscli_colocate_create(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_create_args_t  *args,
  nasd_edrfs_create_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(create);

  nasd_edrfs_real_create(
    args->in_cookie,
    args->in_directory,
    args->in_credential,
    (char *)args->in_dirpath,
    args->in_attribute,
    args->in_fieldmask,
    &res->out_cookie,
    &res->out_identifier,
    &res->out_attribute,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(create);
}

void
nasd_edrfscli_colocate_symlink(
  nasd_edrfs_handle_t         handle,
  nasd_edrfs_symlink_args_t  *args,
  nasd_edrfs_symlink_res_t   *res,
  nasd_rpc_status_t          *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(symlink);

  nasd_edrfs_real_symlink(
    args->in_cookie,
    args->in_directory,
    args->in_credential,
    (char *)args->in_dirpath,
    (char *)args->in_symlink,
    args->in_attribute,
    &res->out_cookie,
    &res->out_identifier,
    &res->out_attribute,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(symlink);
}

void
nasd_edrfscli_colocate_remove(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_remove_args_t  *args,
  nasd_edrfs_remove_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(remove);

  nasd_edrfs_real_remove(
    args->in_cookie,
    args->in_directory,
    args->in_credential,
    (char *)args->in_dirpath,
    &res->nasd_status);

  DORETURN(remove);
}

void
nasd_edrfscli_colocate_mkdir(
  nasd_edrfs_handle_t       handle,
  nasd_edrfs_mkdir_args_t  *args,
  nasd_edrfs_mkdir_res_t   *res,
  nasd_rpc_status_t        *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(mkdir);

  nasd_edrfs_real_mkdir(
    args->in_cookie,
    args->in_directory,
    args->in_credential,
    (char *)args->in_dirpath,
    args->in_attribute,
    args->in_fieldmask,
    &res->out_cookie,
    &res->out_identifier,
    &res->out_attribute,
    &res->post_attribute,
    &res->nasd_status);

  DORETURN(mkdir);
}

void
nasd_edrfscli_colocate_rmdir(
  nasd_edrfs_handle_t       handle,
  nasd_edrfs_rmdir_args_t  *args,
  nasd_edrfs_rmdir_res_t   *res,
  nasd_rpc_status_t        *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(rmdir);

  nasd_edrfs_real_rmdir(
    args->in_cookie,
    args->in_directory,
    args->in_credential,
    (char *)args->in_dirpath,
    &res->nasd_status);

  DORETURN(rmdir);
}

void
nasd_edrfscli_colocate_newcookie(
  nasd_edrfs_handle_t           handle,
  nasd_edrfs_newcookie_args_t  *args,
  nasd_edrfs_newcookie_res_t   *res,
  nasd_rpc_status_t            *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(newcookie);

  nasd_edrfs_real_newcookie(
    args->in_identifier,
    args->in_credential,
    &res->out_cookie,
    &res->nasd_status);
  
  DORETURN(newcookie);
}

void
nasd_edrfscli_colocate_rename(
  nasd_edrfs_handle_t        handle,
  nasd_edrfs_rename_args_t  *args,
  nasd_edrfs_rename_res_t   *res,
  nasd_rpc_status_t         *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(rename);

  nasd_edrfs_real_rename(
    args->in_cookie,
    args->in_from_directory,
    args->in_credential,
    (char *)args->in_from_path,
    args->in_to_directory,
    (char *)args->in_to_path,
    &res->post_from_attribute,
    &res->post_to_attribute,
    &res->nasd_status);

  DORETURN(rename);
}

void
nasd_edrfscli_colocate_getstats(
  nasd_edrfs_handle_t         handle,
  nasd_edrfs_getstats_res_t  *res,
  nasd_rpc_status_t          *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(getstats);

  nasd_edrfs_real_getstats(
    &res->out_opstats,
    &res->out_cachestats,
    &res->out_opdepths,
    &res->nasd_status);

  DORETURN(getstats);
}

void
nasd_edrfscli_colocate_resetstats(
  nasd_edrfs_handle_t   handle,
  nasd_res_t           *res,
  nasd_rpc_status_t    *op_status)
{
  NASD_EDRFS_RPC_OP_STATS_DECL

  DOBEGIN(resetstats);

  nasd_edrfs_real_resetstats(
    &res->nasd_status);

  DORETURN(resetstats);
}

void
nasd_edrfscli_colocate_error_string(
  nasd_edrfs_handle_t     handle,
  nasd_rpc_status_t       status,
  nasd_error_string_t     str,
  char                   *file,
  int                     line)
{
  switch(status) {
    case 0:
      sprintf(str, "Success");
      return;
    default:
      sprintf(str, "%d:%u", handle->type, status);
  }
}

nasd_edrfscli_rpcmod_tab_t nasd_edrfscli_colocate_mod = {
  NULL,
  NASD_RPCMOD_INIT_FAIL,

  nasd_edrfscli_colocate_bind,
  nasd_edrfscli_colocate_unbind,

  nasd_edrfscli_colocate_null,
  nasd_edrfscli_colocate_mount,
  nasd_edrfscli_colocate_fsstat,
  nasd_edrfscli_colocate_fsinfo,
  nasd_edrfscli_colocate_lookup,
  nasd_edrfscli_colocate_readdir,
  nasd_edrfscli_colocate_access,
  nasd_edrfscli_colocate_setattr,
  nasd_edrfscli_colocate_create,
  nasd_edrfscli_colocate_symlink,
  nasd_edrfscli_colocate_remove,
  nasd_edrfscli_colocate_mkdir,
  nasd_edrfscli_colocate_rmdir,
  nasd_edrfscli_colocate_newcookie,
  nasd_edrfscli_colocate_rename,
  nasd_edrfscli_colocate_getstats,
  nasd_edrfscli_colocate_resetstats,

  nasd_edrfscli_colocate_lookup_otw_provided,
  nasd_edrfscli_colocate_create_otw_provided,

  nasd_edrfscli_colocate_error_string,

  NASD_BIND_COLOCATE,
  "Colocated",
  0,

  NULL
};

void
nasd_edrfscli_colocate_register(
  int  counter_lock_held)
{
  nasd_edrfscli_mod_register(&nasd_edrfscli_colocate_mod, counter_lock_held);
}


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