/*
 * Copyright (C) 1992 WIlfried Koch, Palanterstr. 46, D-5000 Koen 41 (Germany)
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 * Initial version.
 */
#include "rrloops.h"
#include <signal.h>

RRArgList *RRArgs;
rpc_square svc;
static int TransportID=0;
RRConnection Conn;
int ServeAndExit=FALSE;
void rpc_server(exestring)
	char *exestring;
{
	signal(SIGQUIT,RRUnRegisterService);
	signal(SIGINT,RRUnRegisterService);
	signal(SIGSTOP,RRUnRegisterService);
	signal(SIGTERM,RRUnRegisterService);
	signal(SIGHUP,RRUnRegisterService);
	signal(SIGTSTP,RRUnRegisterService);

	signal(SIGBUS,RRUnRegisterServiceCore);
        signal(SIGSEGV,RRUnRegisterServiceCore);



	RRSanity(&RRProg);
        GetMyHostname(&MyHostname);
	fprintf(stderr,"started with %s\n",exestring++);
	Conn.clientname=NULL;
	switch(*exestring) {
		case 't':
			if(!exestring[1]){
				TransportID=0;
			} else {
				TransportID=atoi(&exestring[1]);
			}
			while(isdigit(*exestring)){
				exestring++;
			}
			break;

		case '0':  case '1':  case '2':  case '3':  case '4':
		case '5':  case '6':  case '7':  case '8':  case '9':
			TransportID=1;
			ServeAndExit=TRUE;
			signal(SIGPIPE,RRUnRegisterService);
			RegisterPMService();
			Conn.progname=RRProg.name;
			ResolvePMExeString(exestring,&Conn);
			ConnectionInfo(&Conn,stderr);
			rrinitservice_1(&Conn,NULL);
			break;
		case 0:
			TransportID=2;
		default:
		;
	}
	exestring++;

	if(!TransportID){
		fprintf(stderr," add a valid TransportID behind t, implemented is 1 (Portmapper) \n");
		fprintf(stderr," 						  2 (Portmapper) \n\n");
		fprintf(stderr," NOTE: even numbers start the server, odds must be followed by clients");
		fprintf(stderr," address in order to inform it\n");
		exit(1);
	}

	switch(*exestring) {
		case '.':
		      switch (TransportID) {
				case PORTMAPPER_TCPIP_ON_PORTMAPPER_TCPIP:
					ResolvePMExeString(&exestring[1],&Conn);
					RegisterPMService();
					ServiceInfo(stderr);
					break;
			}
		case 0:
			switch(TransportID){

				case PORTMAPPER_TCPIP_PORTMAPPER_TCPIP:
				RegisterPMService();
				ServiceInfo(stderr);
				RunService();
				break;
			}	
	}
	while(TRUE){
		if(!RunService())
			continue;
		else {
        		fprintf(stderr, "Service returned\n");
			if(ServeAndExit){
				RRUnRegisterService();
        			exit(1);
			} else {
				;
			}
		}
	}
}
	
	
int 
RRMarshall (argp)
       RRArg *argp;
{
       RRArgList *new;
       new= (RRArgList*) calloc(1,sizeof(RRArgList));
       if(!new){
            return (FALSE);
       }
       new->rrarg=(RRArg*) calloc(1, RRProg.argsize);
       if(!new->rrarg){
             free(new);
             return (FALSE);
       }
       bcopy(argp,new->rrarg,RRProg.argsize);
       new->next=RRArgs;
       RRArgs=new;
       return (TRUE);
}
int *
rrblocked_1(argp, rqstp)
       void *argp;
       struct svc_req *rqstp;
{
       static int res;
       res=TRUE;
       return (&res);
}

void RRFreeArgs()
{
	fprintf(stderr,"\n RRID %d freed\n",RRArgs->rrarg->RRID);
	/*rrfree_1(&(RRArgs->rrarg->RRID),NULL);*/
	free(Conn.clientname);
}

int *
rrfree_1(argp,rqstp)
       unsigned long *argp;
       struct svc_req *rqstp;
{
       static int res;
	RRArgList *currrarg,*prevrrarg;
	res=FALSE;
	currrarg=RRArgs;
	prevrrarg=NULL;
	while(currrarg){
		if(currrarg->rrarg->RRID==*argp){
			xdr_free(RRProg.RRxdr_fnct,&currrarg->rrarg);
			if(prevrrarg)
				prevrrarg->next=currrarg->next;
			else
				RRArgs=NULL;
			free(currrarg);
			res=TRUE;
			return(&res);
		}
		prevrrarg=currrarg;
		currrarg=currrarg->next;
	}
	return (&res);
}
char **
rrinfo_1(argp, rqstp)
       void *argp;
       struct svc_req *rqstp;
{
       static char *res;
       RRArgList *currrarg;
       currrarg=RRArgs;
       while(currrarg){
       }
       res="jawoll";
       return (&res);
}
int *
RRRequest(request)
	RRreq *request;
{
	static int ArgOk;
	RRArgList *currrarg;
		ArgOk=FALSE;
		currrarg=RRArgs;
		while(currrarg){
			if(currrarg->rrarg->RRID==request->RRID){
                       	        ArgOk=TRUE;
                                break;
			}
			currrarg=currrarg->next;
		}
		Conn.clientname=(nm)strsave(request->connect.clientname);
		if(ArgOk){
			fprintf(stderr," Square %d\n",request->sequence);
		}
		return &ArgOk;
}
void RenderSquare(request)
	 RRreq *request;
{
	int ArgOk;
	static RRArgList *currrarg;
	int status;
	ArgOk=FALSE;
	currrarg=RRArgs;
	while(currrarg){
		if(currrarg->rrarg->RRID==request->RRID){
			ArgOk=TRUE;
			break;
		}
		currrarg=currrarg->next;
	}
	if(ArgOk) {
		svc.pixels.pixels_val=
			(rpc_Pixel*)calloc((request->maxx-request->minx+1) *
					   (request->maxy-request->miny+1),
					    sizeof(rpc_Pixel));
                svc.pixels.pixels_len=NULL;
		ByteCopy(request,&svc.req,sizeof(RRreq));
		fprintf(stderr,"\n");
                (RRProg.RR_fnct) (currrarg->rrarg,&svc);
		svc.pixels.pixels_val-=svc.pixels.pixels_len;
		svc.pixels.pixels_len*=(sizeof(rpc_Pixel));
		ConnectionInfo(&request->connect,stderr);
		status=RRSendSquare(&svc);
 		free(svc.pixels.pixels_val);
		svc.pixels.pixels_len=NULL;
	}
}

