#include <stdio.h>
#include <stdlib.h>
#include <rpc/rpc.h>
#include <netconfig.h>
#include "sortHomework4.h"
#include <sys/socket.h>

SVCXPRT *xprt;

u_long
gettransient(proto, vers, portnum)
        int proto;
        u_long vers;
        u_short portnum;
{
        static u_long prognum = 0x40000000;
 

        while (!pmap_set(prognum++, vers, proto, portnum))
                continue;
        return (prognum - 1);
}

int
callback(struct svc_req *rqstp, SVCXPRT *transp)
{
  int i;
  static int_array sort_data;

  switch (rqstp->rq_proc) {
  case 0:
    if (!svc_sendreply(transp, xdr_void, 0)) {
      fprintf(stderr, "err: sendreply\n");
      return (1);
    }
    return (0);

  case 1:
    printf( "Client got callback\n");

    if (!svc_getargs(transp, xdr_int_array, &sort_data)) {
      svcerr_decode(transp);
      return (1);
    }

    if (!svc_sendreply(transp, xdr_void, 0)) {
      fprintf(stderr, "err: sendreply");
      return (1);
    }

    printf("\nProcessed data is:\n");
    for (i=0; i<sort_data.int_array_len; i++) {
      printf("%d: %d\n", i, sort_data.int_array_val[i]);
    }
    
    /* destroy client */
    svc_destroy(xprt);
    
    return 0;
  }
}

int
main(int argc, char *argv[])
{
  int i;
  struct cb_msg msg;
  u_long x;
  int_array data;
  char hostname[256];
  char *server;
  int ans;

  /* check/get parameters */
  if (argc<2) {
    printf("usage: sortClientHomework4 <server>\n");
    return 1;
  }
  server = argv[1];

  /* init data */
  data.int_array_len = 5;
  data.int_array_val = (int *)malloc(data.int_array_len*sizeof(int));

  for (i=0; i<data.int_array_len; i++) {
    data.int_array_val[i] = -i;
  }

  if ((xprt = svcudp_create(RPC_ANYSOCK)) == NULL) {
    fprintf(stderr, "err: svcudp_create\n");
    return 1;
  }

  if ((x = gettransient(IPPROTO_UDP, 1, xprt->xp_port)) == 0) {
    fprintf(stderr, "err: transnum failed\n");
    return 1;
  }

  printf("Original data is:\n");
  for (i=0; i<data.int_array_len; i++) {
    printf("%d: %d\n", i, data.int_array_val[i]);
  }

  svc_register(xprt, x, 1, callback, 0);
  gethostname(hostname, sizeof(hostname));
  msg.hostname = hostname;
  msg.returnprog = x;
  msg.data = data;
  ans = callrpc(server, SORTPROG, SORTVERS, SORTNUM,
		xdr_cb_msg, &msg, xdr_void, 0);

  if ((enum clnt_stat) ans != RPC_SUCCESS) {
    fprintf(stderr, "call: ");
    clnt_perrno(ans);
    fprintf(stderr, "\n");
  }
  printf("Call returned\n");


  /* free data */
  free(data.int_array_val);

  printf("Waiting for callback on %ld\n", x);
  svc_run();
}

