/****************************************/
/*	test_util.c			*/
/*	miscelleanous functions		*/
/****************************************/

#include "pvm_test.h"
#include "test_list.h"

/****************************************/
/*		Terminate		*/
/****************************************/

void term(code)
int	code;
{
if (code == HIGH_LEVEL)
	fprintf(outfile,"\n\n********************\n* PVM_tester exits *\n********************\n\n");
if (code == OK_LEVEL)
	fprintf(outfile,"\n\n--------------------\n|  PVM tester End  |\n--------------------\n\n");
	if(out45)fclose(out45);
	if(out46)fclose(out46);
	fclose(stderr);
	if (stdout != stderr)
		fclose(stdout);
	if (outfile != stdout)
		fclose(outfile);
fprintf(stderr,"PVM still running\n");
/*
	if (pvm_halt()<0)
		fprintf(outfile,"pvm_halt() : Unable to stop pvmd !!!\n");
*/
exit(1);
}


/****************************************/
/*	Input file Parsing		*/
/****************************************/

int input_parse(infile,name,number_of_hosts,myhostname,out)
FILE 	*infile;
char 	*name;
int  	*number_of_hosts;
char	*myhostname;
char	out[OUTFILE_MAX_LENGTH];
{
int  	i,value,flag,test_number,linecount=0;
char 	line[MAX_LINE_LENGTH];			/* Current line proc*/
char    temp_buf[32];
int	myhost_already_seen=0;

/*	File Open		*/
if((infile = fopen(name,"r")) == NULL)
	{
	fprintf(stderr, "fopen() : Unable to open %s for input: ",name);
	exit(1);
	}

/*	File parse		*/
while(fgets(line,MAX_LINE_LENGTH,infile) != NULL)
	{
	linecount++;
	if(line[0] != '#') 	/* We ignore the comments */
		{
		if(strncmp(line,HOST_PREFIX,strlen(HOST_PREFIX)) == 0)
			/***** Add an host to hostpool *****/
			{
			if ((strlen(line)-strlen(HOST_PREFIX))> MAX_HOST_NAME_LENGTH)
				{
				fprintf(stderr,"Host name too long on line %d\n",
						linecount);
				exit(1);
				}
			if ((strncmp(myhostname,(line+strlen(HOST_PREFIX)),
				strlen(line)-strlen(HOST_PREFIX)-1)!=0)||(myhost_already_seen == 1))
				{
			hostpool[*number_of_hosts] = (char *)malloc(strlen(line)-strlen(HOST_PREFIX)+1);
			strncpy(hostpool[*number_of_hosts],(line+strlen(HOST_PREFIX)),
						strlen(line)-strlen(HOST_PREFIX)-1);	
			hostpool[*number_of_hosts][strlen(line)-strlen(HOST_PREFIX)-1]='\0';
			(*number_of_hosts)++;
				}
			else	/* It is myhost */
				myhost_already_seen = 1;
			}
		else if(strncmp(line,"[",1) == 0)
			/***** Do we execute this test *****/
			{
			if((flag = parse_flag(line)) == -1)
				{
				fprintf(stderr,"Error in input file at line %d\n", 
						linecount);
				fclose(infile);
				exit(1);
				}
			if((test_number = parse_test_number(line,flag)) == -1)
				{
				fprintf(stderr,"Error in input file at line %d\n",
						linecount);
				fclose(infile);
				exit(1);
	      				 }
			if(test_number > NUMBER_OF_TESTS)
				{
				fprintf(stderr,"No such test at line %d\n",linecount);
				exit(1);
				}
			(*masters)[(test_number-1)].flag.perform=flag;
			}
		else if(strncmp(line,OUTFILE_PREFIX,strlen(OUTFILE_PREFIX)) == 0)
			/***** Set outfile *****/
			{
			if ((strlen(line)-strlen(OUTFILE_PREFIX)) > OUTFILE_MAX_LENGTH)
				{
				fprintf(stderr,"Outfile too long on line %d\n",
						linecount);
				exit(1);
				}
			strncpy(out,line+strlen(OUTFILE_PREFIX),
				strlen(line)-strlen(OUTFILE_PREFIX)-1);
			out[strlen(line)-strlen(OUTFILE_PREFIX)-1] = '\0';
			if (strcmp(out,"stdout") == 0)
				outfile = stdout;
			else
				if ((outfile = fopen(out,"w")) == NULL)
					{
					fprintf(stderr,"fopen() : Unable to open %s\n",out);
					exit(1);
					}
			}
		else if(strncmp(line,MAX_LENGTH_PREFIX,strlen(MAX_LENGTH_PREFIX)) == 0)
			/***** Set max_size *****/
			{
			if ((strlen(line)-strlen(MAX_LENGTH_PREFIX))>9)
				{
				fprintf(stderr,"Number to long in input file at line %d\n",linecount);
				exit(1);
				}
			for (i=strlen(MAX_LENGTH_PREFIX);i<strlen(line)-1;i++)
				{
				if ((line[i]<'0')||(line[i]>'9'))
					{
					fprintf(stderr,"Error in input file at line %d\n",linecount);
					exit(1);
					}
				temp_buf[i-strlen(MAX_LENGTH_PREFIX)]=line[i];
				}
			max_size = atoi(temp_buf);
			if (max_size>MAX_MESSAGE_LENGTH)
				{
				max_size = MAX_MESSAGE_LENGTH;
				fprintf(stderr,"\tMax Size of message too long, using %d by default\n",MAX_MESSAGE_LENGTH);
				}
			for (i=0;i<10;i++) temp_buf[i]=' ';
			}
		else if(strncmp(line,START_LENGTH_PREFIX,strlen(START_LENGTH_PREFIX)) == 0)
                        /***** Set start_size *****/
                        {
                        if ((strlen(line)-strlen(START_LENGTH_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(START_LENGTH_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(START_LENGTH_PREFIX)]=line[i];
                                }
                        start_size = atoi(temp_buf);
			if (start_size >MAX_MESSAGE_LENGTH)
				{
				start_size = MAX_MESSAGE_LENGTH;
				fprintf(stderr,"\tStart size of message too long, using %d by default\n",MAX_MESSAGE_LENGTH);
				}
			for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
		else if(strncmp(line,INCR_PREFIX,strlen(INCR_PREFIX)) == 0)
                        /***** Set incr *****/
                        {
                        if ((strlen(line)-strlen(INCR_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(INCR_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(INCR_PREFIX)]=line[i];
                                }
                        incr = atoi(temp_buf);
			for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
		else if(strncmp(line,NUM_PREFIX,strlen(NUM_PREFIX)) == 0)
                        /***** Set num_message *****/
                        {
                        if ((strlen(line)-strlen(NUM_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(NUM_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(NUM_PREFIX)]=line[i];
                                }
                        num_messages = atoi(temp_buf);
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
		else if(strncmp(line,LENGTH_PREFIX,strlen(LENGTH_PREFIX)) == 0)
                        /***** Set message_length *****/
                        {
                        if ((strlen(line)-strlen(LENGTH_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(LENGTH_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(LENGTH_PREFIX)]=line[i];
                                }
                        messages_length = atoi(temp_buf);
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
		 else if(strncmp(line,FUNNELING_PREFIX,strlen(FUNNELING_PREFIX)) == 0)
                        /***** set funneling  *****/
                        {
                        if ((strlen(line)-strlen(FUNNELING_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(FUNNELING_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(FUNNELING_PREFIX)]=line[i];
                                }
			value = atoi(temp_buf);
			for (i=79;i<107;i++)
				{
				(*masters)[i].num_req_hosts=value;
				(*masters)[i].flag.after_hosts=value;
				}
                        for (i=0;i<10;i++) temp_buf[i]=' ';
			}
		else if(strncmp(line,COMBOS_PREFIX,strlen(COMBOS_PREFIX)) == 0)
                        /***** set all_combos  *****/
                        {
                        if ((strlen(line)-strlen(COMBOS_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(COMBOS_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'1'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(COMBOS_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
			if ((value != 0)&&(value !=1))
				{
				fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
				exit(1);
				}
			all_combos = value;	
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
                else if(strncmp(line,ALL_TESTS_PREFIX,strlen(ALL_TESTS_PREFIX)) == 0)
                        /***** set all_tests  *****/
                        {
                        if ((strlen(line)-strlen(ALL_TESTS_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_TESTS_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_TESTS_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
			all_tests = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_MESSAGING_PREFIX,strlen(ALL_MESSAGING_PREFIX)) == 0)
                        /***** set all_messaging  *****/
                        {
                        if ((strlen(line)-strlen(ALL_MESSAGING_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_MESSAGING_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_MESSAGING_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_messaging = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_ROUTINE_PREFIX,strlen(ALL_ROUTINE_PREFIX)) == 0)
                        /***** set all_routine  *****/
                        {
                        if ((strlen(line)-strlen(ALL_ROUTINE_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_ROUTINE_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_ROUTINE_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_routine = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_FUNNEL_NODATA_PREFIX,strlen(ALL_FUNNEL_NODATA_PREFIX)) == 0)
                        /***** set all_funnel_nodata  *****/
                        {
                        if ((strlen(line)-strlen(ALL_FUNNEL_NODATA_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_FUNNEL_NODATA_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_FUNNEL_NODATA_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_funnel_nodata = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_FUNNEL_DATA_PREFIX,strlen(ALL_FUNNEL_DATA_PREFIX)) == 0)
                        /***** set all_funnel_data  *****/
                        {
                        if ((strlen(line)-strlen(ALL_FUNNEL_DATA_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_FUNNEL_DATA_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_FUNNEL_DATA_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_funnel_data = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
                else if(strncmp(line,ALL_HEAD_NODATA_PREFIX,strlen(ALL_HEAD_NODATA_PREFIX)) == 0)
                        /***** set all_head_nodata  *****/
                        {
                        if ((strlen(line)-strlen(ALL_HEAD_NODATA_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_HEAD_NODATA_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_HEAD_NODATA_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_head_nodata = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_HEAD_DATA_PREFIX,strlen(ALL_HEAD_DATA_PREFIX)) == 0)
                        /***** set all_head_data  *****/
                        {
                        if ((strlen(line)-strlen(ALL_HEAD_DATA_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_HEAD_DATA_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_HEAD_DATA_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_head_data = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
                else if(strncmp(line,ALL_TRIANGLE_NODATA_PREFIX,strlen(ALL_TRIANGLE_NODATA_PREFIX)) == 0)
                        /***** set all_triangle_nodata  *****/
                        {
                        if ((strlen(line)-strlen(ALL_TRIANGLE_NODATA_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_TRIANGLE_NODATA_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_TRIANGLE_NODATA_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_triangle_nodata = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_TRIANGLE_DATA_PREFIX,strlen(ALL_TRIANGLE_DATA_PREFIX)) == 0)
                        /***** set all_triangle_data  *****/
                        {
                        if ((strlen(line)-strlen(ALL_TRIANGLE_DATA_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_TRIANGLE_DATA_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_TRIANGLE_DATA_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_triangle_data = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

                else if(strncmp(line,ALL_PERF_PREFIX,strlen(ALL_PERF_PREFIX)) == 0)
                        /***** set all_perf  *****/
                        {
                        if ((strlen(line)-strlen(ALL_PERF_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(ALL_PERF_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(ALL_PERF_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        all_perf = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }

		else if(strncmp(line,TIMING_TOTAL_PREFIX,strlen(TIMING_TOTAL_PREFIX)) == 0)
                        /***** set timing_total  *****/
                        {
                        if ((strlen(line)-strlen(TIMING_TOTAL_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(TIMING_TOTAL_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(TIMING_TOTAL_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        timing_total = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }
		else if(strncmp(line,TIMING_AVERAGE_PREFIX,strlen(TIMING_AVERAGE_PREFIX)) == 0)
                        /***** set timing_AVERAGE  *****/
                        {
                        if ((strlen(line)-strlen(TIMING_AVERAGE_PREFIX))>9)
                                {
                                fprintf(stderr,"Number to long in input file at line %d\n",linecount);
                                exit(1);
                                }
                        for (i=strlen(TIMING_AVERAGE_PREFIX);i<strlen(line)-1;i++)
                                {
                                if ((line[i]<'0')||(line[i]>'9'))
                                        {
                                        fprintf(stderr,"Error in input file at line %d\n",linecount);
                                        exit(1);
                                        }
                                temp_buf[i-strlen(TIMING_AVERAGE_PREFIX)]=line[i];
                                }
                        value = atoi(temp_buf);
                        if ((value != 0)&&(value !=1))
                                {
                                fprintf(stderr,"Should be a 0 or a 1 at line %d\n",linecount);
                                exit(1);
                                }
                        timing_average = value;
                        for (i=0;i<10;i++) temp_buf[i]=' ';
                        }




					
		else
			/***** Error *****/
			{
			fprintf(stderr,"Error in input file at line %d\n",
				       linecount);
			fclose(infile);
			exit(1);
			}

		}
	}
if (outfile == NULL)
	outfile = stdout;
if (fclose(infile) == -1)
	{
	fprintf(stderr,"fclose() : Unable to close the input file \n");
	exit(1);
	}
}

/****************************************/
/*      Group Server init		*/
/****************************************/

int start_group_server()
{
int	info;
/* Start pvm group server */
fprintf(stderr,"Starting pvm group server.....\n");
if ((info = pvm_joingroup("Group_init")) != 0)
	{
	fprintf(stderr,
		"pvm_joingroup() : Failed with error %d. Impossible to start group server\n",info);
	return -1;
	}
return 1;
}


/****************************************/
/*      PVM 	Check host list		*/
/****************************************/

int check_hosts(num_hosts)
int 	num_hosts;
{
int 	info;
int 	*infos=(int *)malloc(sizeof(int)*num_hosts);
int 	i;

fprintf(stderr,"Building Virtual machine....\n");
if (num_hosts == 1)
	return 1;
if((info = pvm_addhosts(hostpool+1,num_hosts-1,infos)) < 0)
	{
	fprintf(outfile,"\tpvm_addhosts() :Failed with error %d\n",info);
	free(infos);
	return -1;
	}
if (info <num_hosts-1 )
	{
	for (i=0;i<num_hosts-1;i++)
			{
			if (*(infos+i) < 0)
			fprintf(outfile,"\tpvm_addhost() failed for host %s with error %d\n",
				hostpool[i+1],*(infos+i));
			}
	free(infos);
	return -1;
	}
if (wait_number_hosts(num_hosts-1) <0 )
	{
	free(infos);
	return -1;
	}
free(infos);
return 1;
}	/* At this point, all hosts are added */



	
/****************************************/
/*	Get arch for hostpool		*/
/****************************************/

int get_all_arch()     /* Remove all host but master pvmd's host */
{
struct pvmhostinfo 	*hostp;
int 			nhost;
int 			info;
int			narch;
int 			i;

fprintf(stderr,"Getting the ARCH ...\n");
if ((info = pvm_config(&nhost,&narch,&hostp)) < 0)
	{
printf("B\n");
	fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info);
	return -1;
	}
/* We start at 1 to avoid the master host 	*/
for(i=1;i<nhost;i++)
	{
	if (strcmp(hostp[i].hi_name,hostpool[i]) != 0)
		{
		fprintf(outfile,"\tIncoherent response from pvm_config compared to previous responses \n");
		return -1;
		}
	strcpy(hostarch[i]=(char *)malloc(strlen(hostp[i].hi_arch)+1),hostp[i].hi_arch);
	}
return 0;
}

/****************************************/
/*	Get number of diff arch		*/
/****************************************/

int get_num_diff_arch(num_hosts)
int 	num_hosts;
{
char	temp[MAX_HOST][25];
int 	result=0;
int 	trouve;
int 	i,j;

for (i=1;i<num_hosts;i++)
	{
	trouve = 0;
	for (j=0;j<result;j++)
		trouve = trouve || (strcmp(hostarch[i],temp[j]) == 0);
	if (!trouve)
		strcpy(temp[result++],hostarch[i]);
	}
for (i=0;i<result;i++)
	strcpy(diff_arch[i]=(char *)malloc(strlen(temp[i])+1),temp[i]);

return result;
}

/****************************************/
/*      PVM Remove all hosts		*/
/****************************************/

int remove_all_hosts()	/* Remove all host but master pvmd's host */
{
struct pvmhostinfo 	*hostp;
char			**list_of_names;
int 			error_test = 0;
int 			nhost;
int 			info;
int 			infos;
int			narch;
int 			i;

if ((info = pvm_config(&nhost,&narch,&hostp)) < 0)
	{
	fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info);
	return -1;
	}
/*printf("dans remove_all_host , je trouve %d hosts restant\n",nhost -1);*/
list_of_names = (char **)malloc(nhost*sizeof(char *));
for (i=1;i<nhost;i++)
	strcpy(list_of_names[i]=(char *)malloc(strlen(hostp[i].hi_name)+1),hostp[i].hi_name);

for (i=1;i<nhost;i++)
	{
/*	putc ('.',stderr);*/
	if ((info = pvm_delhosts(list_of_names+i,1,&infos)) < 1)
		{
		fprintf(outfile,"\tpvm_delhosts() : Failed with error %d on host %s\n",
					infos,list_of_names[i]);
		error_test= -1;
		}
	if (info == 1)
		{
		info = wait_number_hosts(nhost-i-1);
			if (info <0)
				error_test = -1;
		}
	}
free(list_of_names);
return error_test;
}


/****************************************/
/*      Check version			*/
/****************************************/

int check_version(num_hosts,myversion)
int 	num_hosts;
char	*myversion;
{
char	**version_table;

int 	i,tid,bufid,info;
int 	error_test=0;
char	**args=NULL;

version_table = (char **)malloc(num_hosts*sizeof(char *));
for (i=1;i<num_hosts;i++)
	version_table[i]=(char *)malloc(25*sizeof(char));

fprintf(stderr,"Checking the version...\n");

for (i=1; i<num_hosts;i++)
	{		       /* Spawn version_slave  */
	if ((info = pvm_spawn(VERSION_SLAVE,args,PvmTaskHost,hostpool[i],1,&tid)) <0 )
		{	
		fprintf(outfile,"\tpvm_spawn() : Failed with error %d\n for host %s",info,hostpool[i]);
		error_test = -1;
		continue;
		}
	info = timeout_wait_message(-1,VERSION_TAG,i);
	if (info < 0)
		{
		error_test = -1;
		continue;
		}
	bufid = pvm_recv(-1,VERSION_TAG);
	if (bufid <0)
		{       
		fprintf(outfile,"\tpvm_recv() : Failed with error %d\n",bufid);
		error_test = -1;
		continue;
		}
	info = pvm_upkstr(version_table[i]);
	if (info <0)
		{
		fprintf(outfile,"\tpvm_upkstr() : Failed with error %d\n",info);
		error_test = -1;
		}
	}
if (error_test == -1)
	return -1;
/* Now the table is complete */
for (i=1;i<num_hosts;i++)
	{
	if (strcmp(myversion,version_table[i]) != 0)
		{
		fprintf(outfile,"\tVersion Mismatch for host %s : version %s, master version :%s\n",
			hostpool[i],version_table[i],myversion);
		error_test = -1;
		}
	}
free(version_table);
return error_test;
}

/****************************************/
/*      Miscellenaous Printout		*/
/****************************************/

int print_out_misc(myversion,num_hosts,in,out)
char	*myversion;
int	num_hosts;
char	*in;
char	*out;
{
int 	i;

fprintf(outfile,"PVM %s\n",myversion);
fprintf(outfile,"------------------------------------\n");

fprintf(outfile,"host pool\n");

fprintf(outfile,"---------\n");
fprintf(outfile,"(%s) \t%s \t<--- Master host\n",hostarch[0],hostpool[0]);

for (i=1;i<num_hosts;i++)
	fprintf(outfile,"(%s) \t%s\n",hostarch[i],hostpool[i]);
fprintf(outfile,"\ninput file\t\toutput file\n");
fprintf(outfile,"----------\t\t-----------\n");
fprintf(outfile,"%s\t\t\t%s\n",in,out);
fprintf(outfile,"------------------------------------\n");
if (outfile != stdout)
	fprintf(stdout,"output file : %s\n",out);

}


/****************************************/
/*      Find Shuffle			*/	
/****************************************/

int find_shuffle(num_hosts,num_diff_arch,shuffle)
int 	num_hosts;
int 	num_diff_arch;
int 	shuffle[MAX_HOST];
{
int 	i,k;
int	info;
int	num_computed=1;
for (k=0;k<num_hosts;k++)
	shuffle[k]=0;
while(num_computed <num_hosts)
	for (i=0;i<num_diff_arch;i++)
		{
		info = look_for_new_arch(num_hosts,i,shuffle,num_computed);
		if (info >=0)
			shuffle[num_computed++]=info;
		}
return 1;
}

int	look_for_new_arch(num_hosts,arch,shuffle,num_computed)
int	num_hosts;
int	arch;
int	shuffle[MAX_HOST];
int	num_computed;
{
int	i,j;
int test = 0;

for (i=1;i<num_hosts;i++)
	{
	test =0;
	if (strcmp(hostarch[i],diff_arch[arch])==0)
		{
		for(j=1;j<num_computed;j++)
			if (shuffle[j]==i)
				test = 1;
		if (test == 0)
			return i;
		}
	}
return -1;
}

/****************************************/
/*      Allocate some hosts		*/
/****************************************/

int allocate(array,req,num_wanted)
int	array[MAX_HOST];
int	req;
int	*num_wanted;
{
int 	i,infos;
int	error_test=0;
int	count_zero=0;

for (i=0;i<req;i++)
	{
	if (array[i]==0)
		{
		count_zero++;
		continue;
		}
	if (pvm_addhosts(&hostpool[array[i]],1,&infos) < 1)
		{
		fprintf(outfile,"\tpvm_addhosts() : Failed to add host %s with error = %d\n",
			hostpool[array[i]],infos);
		error_test = -1;
		}
	}
if (error_test == -1)
	return -1;
*num_wanted = *num_wanted - count_zero+1;
if (wait_number_hosts(req-count_zero) <0 )
	return -1;

return error_test;
}
			

/****************************************/
/*      Unexpected host killed		*/
/****************************************/

int unexpected_host_killed(num_wanted)
int 	num_wanted;
{
int	info;
int	after;
int	narch;
struct	pvmhostinfo *hostp;

/*printf("J;entre dans unexpected host kill\n");*/
/*
for (i=0;i<num_hosts;i++)
	{
	printf("host %s\n --> %d\n",hostpool[i],pvm_mstat(hostpool[i]));
	}
*/
info = pvm_config(&after,&narch,&hostp);
if (info <0)
	{
	fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info);
	return -2;
	}
after--;	/* We suppress the master */
if (after != num_wanted)
	{
	fprintf(outfile,"\t%d hosts expected, %d found\n",num_wanted,after);
	return -1;
	}
return 1;
}


/****************************************/
/*      Print test result		*/
/****************************************/


void print_test_result(number)
int 	number;
{
int 	result = (*masters)[number].status;

if (result == 0)
	fprintf(outfile,"test#%d: NOT_YET_PROCESSED\n",number+1);
else if (result == 1)
	fprintf(outfile,"test#%d: PASSED\n",number+1);
else if (result == -1)
	fprintf(outfile,"test#%d: FAILED\n",number+1);
else if (result == -2)
	fprintf(outfile,"test#%d: NOT_COMPLETED\n",number+1);
else
	fprintf(outfile,"test#%d: UNDETERMINED  %d \n",number+1,result);

}

/****************************************/
/*      Wait for a number of hosts	*/
/****************************************/

int wait_number_hosts(number)
int	number;
{
int count = 0;
int info;
int actual_num;
int	narch;
struct	pvmhostinfo *hostp;

/*printf("wait for number = %d\n",number);*/
info = pvm_config(&actual_num,&narch,&hostp);
if (info < 0)
	      	{
	      	fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info);
	      	return -1;
		}
/*printf("actual count = %d\n",actual_num);*/
while((count <= TIMEOUT_ADD_DELETE)&&(actual_num != (number+1)))
		{
/*	     	putc ('.',stderr);*/
		if (info = pvm_config(&actual_num,&narch,&hostp) < 0)
			{
			fprintf(outfile,"\tpvm_config() : Failed with error %d\n",info);
			return -1;
			}
		sleep(1);
		count++;
		}
/*putc('\n',stderr);*/
if (actual_num != (number+1))
	{
	fprintf(outfile,"\tAdd/Del Timeout exceded.\n");
	return -2;
	}

/*printf("Finalement j'ai actual_number -1 =%d et je voulais %d\n",actual_num-1,number);*/

return 1;
}


/********************************/
/*      timeout_wait_message    */
/********************************/

int     timeout_wait_message(tid,tag,host_num)
int     tid;
int     tag;
int     host_num;
{
int info,count=0;

/*putc('.',stderr);*/
while (((info = pvm_probe(tid,tag)) == 0)&&(count <= TIMEOUT_MESSAGE))
	{
	if (info <0) break;
	sleep (1);
/*      	putc('.',stderr);*/
	count ++;
	}
/*putc('\n',stderr);*/
if (info == 0)
	{
	if (host_num == -1)
		fprintf(outfile,"\tMessage Timeout expired\n");
	else
		fprintf(outfile,"\tMessage Timeout expired from host %s\n",hostpool[host_num]);

	return -2;
	}
if (info > 0 ) return 1;
fprintf(outfile,"\tpvm_probe() : Failed with error %d\n",info);
return -1;
}


/********************************/
/*      timeout_wait_kill    	*/
/********************************/

int     timeout_wait_kill(tid,host_num)
int     tid;
int     host_num;
{
int info,count=0;

/*printf("Waiting for kill ...\n");*/
/*putc('.',stderr);*/
while (1)
	{
	info = pvm_pstat(tid);
	if (info <0) break;
	if (count > TIMEOUT_KILL) break;
	sleep (1);
	count ++;
	}
/*putc('\n',stderr);*/
if ((info !=PvmNoTask)&&(count < TIMEOUT_KILL))
	{
	if (host_num == -1)
		fprintf(outfile,"\tpvm_pstat() : Failed with error %d\n",info);
	else
		fprintf(outfile,"\tpvm_pstat() : Failed with error %d for host %s\n",
			info,hostpool[host_num]);
	return -1;
	}

if (count >= TIMEOUT_KILL)
	{
	if (host_num == -1)
		fprintf(outfile,"\tKill Timeout expired\n");
	else
		fprintf(outfile,"\tKill Timeout expired for host %s\n",
			hostpool[host_num]);
	return -2;
	}
if (info == PvmNoTask ) return 1;
fprintf(outfile,"\tpvm_pstat() : Failed with error %d\n",info);
return -1;
}


/*--------------------------------------*/
/*--------- Internal Stuff -------------*/
/*--------------------------------------*/

/*      parse_flag      */
int parse_flag(line)
char 	*line;
{
if (line[1] == ']') return 0;
else if (line[1] == 'x') return 1;
else return -1;
}

/*      parse_test_number       */
int parse_test_number(line,flag)
char 	*line;
int 	flag;
{
int 	j,i=0;
char 	result[NUMBER_TEST_DIGITS];
char  	c;

for(j=0;j<=NUMBER_TEST_DIGITS-1;j++) result[j]=' ';
result[NUMBER_TEST_DIGITS]='\0';

if (    (line[1+flag] != ']')||
	(line[2+flag] != 't')||
	(line[3+flag] != 'e')||
	(line[4+flag] != 's')||
	(line[5+flag] != 't')   )       return -1;

while( (c = line[6+i+flag]) != '\n')
		{
		if ((c!=' ')&&((isdigit(c) == 0))||(i>NUMBER_TEST_DIGITS)) return -1;
		result[i]=c;
		i++;
		}
return atoi(result);
}
