#include <stdio.h>
#include <rpc/rpc.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#include <sunwindow/notify.h>
#include <signal.h>

#include "stdfm_rpc.h"
#include "fm_commands.h"

#define Success 0
#define Failure -1

static struct timeval fiveSeconds = { 5, 0 };
static struct timeval halfMinute = { 30, 0 };
static FmRpcNiceErrorT nice;

/*
I call RPC's.
*/

/*
Utilities.
*/

static bool_t localCall(proc, inproc, in, outproc, out, total_timeout)
struct timeval total_timeout;
char *in, *out;
xdrproc_t inproc, outproc;
{
struct hostent *hp;
int addrlen, sock = RPC_ANYSOCK;
CLIENT *client;
enum clnt_stat clnt_stat;
struct sockaddr_in server_addr;

hp = gethostbyname("localhost");
if (! hp)
	return (FALSE);

addrlen = sizeof(struct sockaddr_in);
bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr, hp->h_length);
server_addr.sin_family = AF_INET;
server_addr.sin_port = 0;

client = clntudp_create(&server_addr, FM_RPC_PROG, FM_RPC_VERS, total_timeout, &sock); 
if (! client)
	return (FALSE);
	
clnt_stat = clnt_call(client, proc, inproc, in, outproc, out, total_timeout);
if (clnt_stat != RPC_SUCCESS) {
	clnt_perror(client, "");
	return (FALSE);
}

close(sock);
clnt_destroy(client);
return (TRUE);
}

static freeReturn(returnp, freer)
char *returnp;
xdrproc_t freer; 
{
XDR anXdrStream;

xdrmem_create(&anXdrStream, returnp, 8 * 1024, XDR_FREE);
freer(&anXdrStream, returnp);
}

/*
RPC's.
*/

static void doFmCommands(doc, codes, num) 
unsigned int doc;
int *codes;
unsigned int num;
{
FmRpcCommandsArgT arg;

arg.doc = doc; 
arg.commands.FmRpcCommandsT_len = num;
arg.commands.FmRpcCommandsT_val = codes;
bzero(&nice, sizeof(nice));
if (localCall(FM_RPC_COMMANDS, xdr_FmRpcCommandsArgT, &arg, xdr_FmRpcNiceErrorT, &nice, halfMinute)) {
	if (nice.code != Success)
		;
	freeReturn(&nice, xdr_FmRpcNiceErrorT);
}
}

int CloseDoc(doc)
unsigned int doc;
{
int codes[12];

codes[0] = KBD_CLOSEWIN;
doFmCommands(doc, codes, 1);
}

int OpenDoc(doc)
char *doc;
{ 
FmRpcOpenDocArgT arg;
FmRpcOpenDocReturnT openDocReturn;
int handle;

arg.doc = doc;
bzero(&openDocReturn, sizeof(openDocReturn));
handle = -1;
if (localCall(FM_RPC_OPEN_DOC, xdr_FmRpcOpenDocArgT, &arg, xdr_FmRpcOpenDocReturnT, &openDocReturn, halfMinute)) {
	if (openDocReturn.nice.code != Success) {
	}
	else handle = openDocReturn.doc;
	freeReturn(&openDocReturn, xdr_FmRpcOpenDocReturnT);
}
return (handle);
}

int Import(file) 
char *file;
{
FmRpcImportArgT arg;

arg.doc = NULL; 
arg.file = file; 
arg.isCurrentDoc = 1;
arg.isCopy = 0;
bzero(&nice, sizeof(nice));
if (localCall(FM_RPC_IMPORT, xdr_FmRpcImportArgT, &arg, xdr_FmRpcNiceErrorT, &nice, halfMinute)) {
	if (nice.code != Success) {
		freeReturn(&nice, xdr_FmRpcNiceErrorT);
		return (-1);
	}
	freeReturn(&nice, xdr_FmRpcNiceErrorT);
	return (0);
}
return (-1);
}
