/*****************************************************************************
 *
 * FILE:	postal_xmlrpc_client.c
 * DESCRIPTION:	Postal: XML-RPC client
 * DATE:	Tue, Aug 28 2007
 * UPDATED:	Tue, Sep  4 2007
 * AUTHOR:	Kouichi ABE (WALL) / °¤Éô¹¯°ì
 * E-MAIL:	kouichi@MysticWALL.COM
 * URL:		http://www.MysticWALL.COM/
 * COPYRIGHT:	(c) 2007 °¤Éô¹¯°ì¡¿Kouichi ABE (WALL), All rights reserved.
 * LICENSE:
 *
 *  Copyright (c) 2007 Kouichi ABE (WALL) <kouichi@MysticWALL.COM>,
 *  All rights reserved.
 *  
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 *   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 *   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *   SUCH DAMAGE.
 *
 * $Id: postal_xmlrpc_client.c,v 1.2 2007/09/04 09:21:04 kouichi Exp $
 *
 *****************************************************************************/

#if	HAVE_CONFIG_H
#include "config.h"
#endif	/* HAVE_CONFIG_H */

#include <stdio.h>
#if	HAVE_STDLIB_H
#include <stdlib.h>
#endif	/* HAVE_STDLIB_H */
#if	HAVE_UNISTD_H
#include <unistd.h>
#endif	/* HAVE_UNISTD_H */
#if	HAVE_STRING_H
#include <string.h>
#endif	/* HAVE_STRING_H */
#include <sxmlrpc.h>
#include "postal_xmlrpc.h"

/******************************************************************************
 *
 *	Program and Copyright
 *
 *****************************************************************************/
const char	Program[]   = "postal_xmlrpc_client";
const char	Copyright[] =
	"Copyright (c) 2007 Kouichi ABE (WALL), All rights reserved.";

/******************************************************************************
 *
 *	Macros and structures definition
 *
 *****************************************************************************/
/*
 * Numeric release version identifier:
 * MNNFFPPS: major minor fix patch status
 * The status nibble has one of the values 0 for development,
 * 1 to e for betas 1 to 14, and f for release.
 * The patch level is exactly that.
 */
#define	POSTAL_VERSION_NUMBER	0x10001000L
#define	POSTAL_VERSION		"Postal-XMLRPC-Client/1.0.1"
#define	POSTAL_VERSION_TEXT	POSTAL_VERSION " (2007/09/04)"
#define	POSTAL_VERSION_TEXT_LONG \
	"Postal-XMLRPC-Client 1.0.1, Tue, Sep  4 2007"

/*****************************************************************************/

#define	RESPONSE_MEMBER_NUM	(3)

/******************************************************************************
 *
 *	Lobal functions declaration
 *
 *****************************************************************************/
static void	version(void);
static void	usage(void);
static int	postal(sxmlrpc_t * sxRPC, sxmlrpc_value_t * postcode);

/******************************************************************************
 *
 *	Lobal variable definition
 *
 *****************************************************************************/
static void
version(void)
{
  fprintf(stderr, "%s\n%s\n\n", POSTAL_VERSION_TEXT, Copyright);
  exit(64);
}

static void
usage(void)
{
  fprintf(stderr, "usage: %s [-a <ipaddr>][-p <port>] <postcode>\n", Program);
  fprintf(stderr, "\n    [ example ]\n");
  fprintf(stderr, "        %s 1008798\n", Program);
  fprintf(stderr, "        %s -a 192.168.1.23 1008798\n", Program);
  fprintf(stderr, "        %s -a 192.168.1.23 -p 8080 1008798\n\n", Program);
  exit(64);
}

static int
postal(sxRPC, postcode)
	sxmlrpc_t *		sxRPC;
	sxmlrpc_value_t *	postcode;
{
  int			status;
  sxmlrpc_param_t	p;

  sxmlrpc_set_param(&p, *postcode);

  status = sxmlrpc_call(sxRPC, METHOD_NAME, &p, 1);
  if (status == 0) {
    switch (sxRPC->method) {
      case SXMLRPC_METHOD_RESPONSE: {
	  sxmlrpc_value_t *	v;

	  v = sxmlrpc_get_response_value(sxRPC);
	  if (sxmlrpc_get_value_type(v) == SXMLRPC_VALUE_STRUCT) {
	    int	n;

	    n = sxmlrpc_get_struct_size(v);
	    if (n >= 2) {
	      sxmlrpc_member_t *	mval;

	      mval = sxmlrpc_get_struct_member(v);
	      fprintf(stdout, "%s: %s",
		      sxmlrpc_get_value_string(&mval[0].value),
		      sxmlrpc_get_value_string(&mval[1].value));
	      if (n == 3) {
		fprintf(stdout, " %s",
			sxmlrpc_get_value_string(&mval[2].value));
	      }
	      fputs("\n", stdout);
	    }
	  }
	}
	break;
      case SXMLRPC_METHOD_RESPONSE_FAULT:
	fprintf(stdout, "fault: %d: %s\n",
		sxmlrpc_get_fault_code(sxRPC),
		sxmlrpc_get_fault_string(sxRPC));
	break;
      default:
	fprintf(stdout, "error: %d\n", sxRPC->method);
	break;
    }
    sxmlrpc_flush(sxRPC);
  }

  return status;
}

int
main(argc, argv)
	int	argc;
	char *	argv[];
{
  register int	ch;
  const char *	hostname = HOSTNAME;
  const char *	servname = SERVNAME;
  sxmlrpc_t *	sxRPC;
  int		status = -1;

  while ((ch = getopt(argc, argv, "a:p:hv?")) != -1) {
    switch (ch) {
      case 'a': hostname = optarg; break;
      case 'p': servname = optarg; break;
      case 'v': version();
      case 'h':
      default:
	usage();
    }
  }
  argc -= optind;
  argv += optind;
  if (argc == 0) {
    usage();
  }

  sxRPC = sxmlrpc_new(hostname, servname, REQUEST_URI);
  if (sxRPC != NULL) {
    sxmlrpc_value_t	val;

    sxmlrpc_set_value_string(&val, argv[0]);
    status = postal(sxRPC, &val);

    sxmlrpc_free(sxRPC);
  }

  return status;
}
