#include <sys/time.h>
#include <unistd.h>
#include <sys/param.h>
#include <rpc/rpc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/signal.h>

#include "globalDefn.h"
#include "../commonIncludes/_msgq.h"
#include "../commonIncludes/_join.h"
#include "loadTable.c"

//#define PRINT

static struct timeval TIMEOUT = { 50, 0 };

int             retVal;
int             clntFlag = 1;
int             msgQueueId;  /*msg queueid for commn with user programs*/
int             timerMsgQueueId;    /*msg queueid for timer process */
NodeArr         tmpNodeArr;
int             monitorNode;  /* Node which is monitored by the timer */
extern int      timerPid;   /* process id of the timer */
extern IntArr   pidArr;   /* process ids of the registered programs */
NodeArr     	tmpArr;	/* receives replies of broadcast */
NodeArr		nodeArr;
Bool		initializationComplete = false; //This flag is set to true 
StrArr		*strArr;

//just for checking
int tmp;
int input_sattu ; 
int tmp_sattu;
//--------------------	


	//when the initialization of coordinator is complete

TimeStamp	timestamp; /* stores the load & time of load taken  | Added  by									      Satish */

int replySubscribe(NodeArr* receivedNodeArr, struct sockaddr_in *addr);

//int replySubscribe(int * tmp, struct sockaddr_in *addr); 

void* initializeFirstNode( StrArr* strArr);

/*
   boot_up_1()
  -------------
            Arguments :
                NodeArr to be initialized.

            NodeArr is initialized;
            A broadcast join is sent to all;
            Global variables are initialized;

    This function is invoked by boot process after starting the 
    coordinator.
    Performs necessary initializations 
 */

#ifdef NEW_VER_RPC

void* boot_up_1_svc(int* isFirstNode, struct svc_req *junk)
#else

void* boot_up_1(int* isFirstNode)
#endif
{
    CLIENT* cl; 
   // StrArr	*strArr;
    Node   node;

    char   buff[ MAXHOSTNAMELEN ];
    struct hostent *name;
    struct in_addr  in;
    int    i, stat;
    char   id;
    char   tp[50];

/* 	Added by Satish	for computing the Load	*/

	FILE *fp;
	char *tok;
	char W[250];

/*	End		*/

/*	strArr = (StrArr *) malloc( sizeof( StrArr));
	strArr->StrArr_len = 7; //  7 entries in the file
        strArr->StrArr_val = (String *) malloc( strArr->StrArr_len *
    		             sizeof(String));
*/	
	strArr = loadTable( NULL); // get all details of current machine
	                            // stored in a local file called "/kernel/src/node_inf_file".
	for( i = 0; i < strArr->StrArr_len; i++)
	{
             printf( "strArr after loadtable %s \n", strArr->StrArr_val[i].String_val);
    	}
	

	printf("The name of node is %s\n", strArr->StrArr_val->String_val);
	if (*isFirstNode == 1)   { // Indicates that this is the first node.
		initializeFirstNode( strArr);
	}
	
	else {

	#ifdef PRINT
	        PrintInLogFile("Initialize.c: Just before broadcast the subscribe request \n");
	#endif
		printf("Initialize.c: Just before broadcast the subscribe request\n");
		
	       
  /*  		tmpArr.NodeArr_len =  DEFAULT_NUMBER_OF_NODES;    // default value is 30
    		tmpArr.NodeArr_val = (Node*) ecalloc(tmpArr.NodeArr_len
                                                 , sizeof(Node));
  */		
		//problem here...chk out with sir.....	
	
       
		if( (stat = clnt_broadcast(COORDINATOR, INITIALIZE , BROADCAST_SUBSCRIBE ,
					xdr_StrArr, strArr, xdr_NodeArr, &tmpArr, replySubscribe)) == 0)
/*		input_sattu = 1; 
		if( (stat = clnt_broadcast(COORDINATOR, INITIALIZE , BROADCAST_SATTU,
					xdr_StrArr, strArr, xdr_int, &tmp_sattu, replySubscribe)) == 0) 
*/
//		if( (stat = clnt_broadcast(COORDINATOR, INITIALIZE , BROADCAST_SUBSCRIBE ,
//						xdr_StrArr, strArr, xdr_NodeArr, &tmpArr, NULL)) == 0) 
		{
			printf("broadcast success\n");
	//		printf("The value of received nodeID is %d\n", tmpArr.NodeArr_val[0].NodeId);
		}
		else
		{
			printf("Broadcast failed: BroadcastSubscribe\n");
		}
	// 	clnt_perror(cl, strArr);	
		printf("Initialize.c: Just after broadcast the subscribe request %d\n", stat);
		
		
//		printf("Sleeping for 30\n");	
	//	sleep(30); //this sleep is because as the clnt_broadcast is done the coordinator on the
		  // server fails....so maually we have to start it again before the clnt_call below.	
	
		
		//printf("sdafasdf %d\n", tmpArr.NodeArr_val[0].NodeId);
		
		#ifdef PRINT
			PrintInLogFile("Initialize.c: Just after broadcast the subscribe request \n");
		
		#endif
	
	}



//	nodeArr will be created only when replySubsribe is called. It is the exact copy of globalnodeArr.

/*	for(i=0;i<nodeArr.NodeArr_len;i++) {
		printf("Node Id %d \n",nodeArr.NodeArr_val[i].NodeId);
		printf("Node name %s \n",nodeArr.NodeArr_val[i].Name.String_val);
		printf("Node IP %s \n",nodeArr.NodeArr_val[i].IPaddress.String_val);
	}
*/	
	
	
    	
	
	
	globNodeArr.NodeArr_len =  DEFAULT_NUMBER_OF_NODES;    // default value is 30
    	globNodeArr.NodeArr_val = (Node*) ecalloc(globNodeArr.NodeArr_len
                                                 , sizeof(Node));

    	printf("setting all nodeid's of glodNodeArr to -1\n");
    	for(i = 0; i < globNodeArr.NodeArr_len; i++) {
	    globNodeArr.NodeArr_val[i].NodeId = -1;
    	}

    	globLastIndex  = 0;
    	globMyId       = -1;
    	globHighestSeq = 0;
    	globLastMe     = false;

    
	GetHostNameAndIPadd( buff, NULL);

    
	//for(i = 0; i < nodeArr->NodeArr_len; i++) {
	//if (nodeArr->NodeArr_val[i].NodeId == -1) {
	
	
	/*just for checking -------------------------------------------
	if (*isFirstNode != 1)   { // Indicates that this is the first node.
	printf("Not the first Node\n");
	nodeArr.NodeArr_len = 30;
	nodeArr.NodeArr_val = (Node *) malloc ( 30 * sizeof(Node));
	nodeArr.NodeArr_val[0].NodeId= 0;
	nodeArr.NodeArr_val[0].Name.String_val = "sahyadri"; 	
	nodeArr.NodeArr_val[0].Name.String_len = 8; 	
	nodeArr.NodeArr_val[0].IPaddress.String_val = "10.105.24.5"; 	
	nodeArr.NodeArr_val[0].IPaddress.String_len = "sahyadri"; 	
	nodeArr.NodeArr_val[0].Name.String_val = "sahyadri"; 	
	nodeArr.NodeArr_val[0].Name.String_val = "sahyadri"; 	
	}	
    	//--------------------------------------------------------------*/

	
       for(i = 0; i < nodeArr.NodeArr_len; i++) {
        if (nodeArr.NodeArr_val[i].NodeId == -1) {
            globLastIndex = i;
//	    printf("The value of Globallastindexis %d\n", globLastIndex);
            break;
        }


	//Copy(&(globNodeArr.NodeArr_val[i]), &(nodeArr->NodeArr_val[i]));
        //if ( !strcmp(nodeArr->NodeArr_val[i].Name.String_val, buff)) {

//	printf("hiiiiiiiii\n");

	printf("Copy here %d\n", i);

//	printf("nodeArr.NodeArr_val[i].Name %s %d\n", nodeArr.NodeArr_val[i].Name.String_val, i);
        
	Copy(&(globNodeArr.NodeArr_val[i]), &(nodeArr.NodeArr_val[i]));
	
/*	printf("nodeArr.NodeArr_val[i].Name %s %d\n", nodeArr.NodeArr_val[i].Name.String_val, i);
	printf("globNodeArr.NodeArr_val[i].Name %s \n\n", globNodeArr.NodeArr_val[i].Name.String_val);
	printf("nodeArr.NodeArr_val[i].Ipaddress %s \n", nodeArr.NodeArr_val[i].IPaddress.String_val);
	printf("globNodeArr.NodeArr_val[i].Ipaddress %s \n", globNodeArr.NodeArr_val[i].IPaddress.String_val);
	printf("hiiiiiiiii\n\n");
  */      
	if ( !strcmp(nodeArr.NodeArr_val[i].Name.String_val, buff)) {
             globMyId = i;
	    printf("The value of GlobalMyid %d\n", globMyId);
        }
    }

    for(i = 0; i < globLastIndex; i++) {
			//Skip those nodes which satisfy the following values of id's
			//	-1	Means these nodes do not exist ( since the size of node-array is larger 
			//	than the number of nodes some entries in the node-array are empty !! )
			//	-2  Means entry for these nodes exist but they are currently down.
			//	Also skip the entry of one-self.
        if ((globNodeArr.NodeArr_val[i].NodeId == globMyId) 
               || ( globNodeArr.NodeArr_val[i].NodeId == -1 )
               || ( globNodeArr.NodeArr_val[i].NodeId == -2 )) {

            continue;
        }

		printf("In initialize.c : boot_up is trying to make a connection to remote coordinator \n");
		//Create a client handle to other servers	
        if ((cl = clnt_create( globNodeArr.NodeArr_val[i].IPaddress.String_val,
               COORDINATOR, INITIALIZE,"tcp")) == NULL) {
               clnt_pcreateerror(
               globNodeArr.NodeArr_val[i].IPaddress.String_val );
				//There is an error and hence set the flag.
               clntFlag = 0;
        }

		// Check the flag the flag to find if there was any error.
		// If so then return
        if( !clntFlag) {
            clntFlag = 1;
            continue;
        }
		//Call a broadcast_join_1_svc() call on each of the other co-ordinators.
	printf("hi\n"); 

	
	printf("In initialize.c : globNodeArr.NodeArr_val[ globMyId ].Name.String_val  %s\n", globNodeArr.NodeArr_val[ globMyId ].Name.String_val);
        	
	//error here 
	if (clnt_call(cl,BROADCAST_JOIN,(xdrproc_t) xdr_Node,
                   (char*) &( globNodeArr.NodeArr_val[ globMyId ]),
                    (xdrproc_t) xdr_int, (char*)&retVal, TIMEOUT) != RPC_SUCCESS) {

                clnt_perror(cl, globNodeArr.NodeArr_val[i].IPaddress.String_val);
                retVal = CLIENT_CONNECTION_FAIL;
		printf("Within boot_up : The call on the join function of remote coordinator FAILED %d\n", retVal);
                return &retVal;
        }

	printf("Sleeping for 30\n");	
//	sleep(30); // the server again fails

	
        if ( globHighestSeq < retVal) {
            globHighestSeq = retVal;
        }

        clnt_destroy(cl);
    }

#ifdef PRINT

PrintInLogFile("HighestSeqNum = %d %d \n", globLastIndex, globMyId);

#endif

	printf("HighestSeqNum = %d %d", globLastIndex, globMyId);

/*	 Added by Satish */

	timestamp.load[0] = malloc(5 * sizeof(char));
	timestamp.load[1] = malloc(5 * sizeof(char));
	timestamp.load[2] = malloc(5 * sizeof(char));

	system("w > SMN_W");
	fp = fopen ("SMN_W","r");
	fscanf(fp,"%[^\n]",W);
	tok = strtok(W," ,:\t");
	while((tok = strtok(NULL," ,:\t")) != NULL) {
		if(!strcmp(tok,"average"))
			break;
	}
	timestamp.load[0] = strtok(NULL," ,:\t");
	timestamp.load[1] = strtok(NULL," ,\t");
	timestamp.load[2] = strtok(NULL," \t");
	
	printf("\n Load: %s : %s : %s\n",
	timestamp.load[0],timestamp.load[1],timestamp.load[2]);		

	timestamp.NodeId = globLastIndex;
	gettimeofday(&(timestamp.Tv),NULL);
	fclose(fp);
	system("rm -f SMN_W");

	PrintInLogFile("\nId = %d, Load: %s : %s : %s\n",timestamp.NodeId,
	timestamp.load[0],timestamp.load[1],timestamp.load[2]);

/* 	End   */
    
	//If this co-ordinator is the last one in the node list then set the 
	//global variable globLastMe = True.
    //if ( (globLastIndex != 0) && (globLastIndex - 1 == globMyId) ) 
    
	
	if (globLastIndex - 1 == globMyId) { // Changed by Ameeeeeeeeeeeet, added the abave line
		printf("Within  boot_up : I am setting globLastMe to TRUE: 
						globLastIndex = %d ,globMyId = %d\n",globLastIndex,globMyId);
        globLastMe = true;
    	}
    
	else {
		printf("Within  boot_up : I am setting globLastMe to FALSE :
						globLastIndex = %d ,globMyId = %d\n",globLastIndex,globMyId);
        globLastMe = false;
    	}

    
	curProgramNum = globNodeArr.NodeArr_val[ globMyId].RangeBegin;

    
	if( (msgQueueId = msgget(MKEY1, PERMS | IPC_CREAT)) < 0) {
        printf(" server can't get message queue 1 \n");
    
	}

    
	if( (timerMsgQueueId = msgget(MKEY2, PERMS | IPC_CREAT)) < 0) {
        printf(" server can't get the handle to message queue 1 \n");
    
	}

    for( i = globMyId + 1; i < globLastIndex; i++) {
        if( globNodeArr.NodeArr_val[i].NodeId >= 0) {
            break;
        }
    }

    if( i == globLastIndex) {
        for( i = 0; i < globMyId; i++) {
            if( globNodeArr.NodeArr_val[i].NodeId >= 0) {
                break;
            }
        }
    }
    strcpy( tp, "monitor ");
    printf("The value of globmyid is %d\n", globMyId);
    printf("The value of is i %d\n", i);
    printf("\n");
    printf("\n");
    if( i == globMyId) {
        strcat( tp, " SINGLE_NODE  -1 &");
        monitorNode = -1;
    }
    else {
        strcat(tp, " ");
        strncat(tp, globNodeArr.NodeArr_val[i].IPaddress.String_val,
                globNodeArr.NodeArr_val[i].IPaddress.String_len);
     printf("The value of i before starting monitor process is %d\n", i);
  //   	strncat(tp, globNodeArr.NodeArr_val[i].Name.String_val,
    //            globNodeArr.NodeArr_val[i].Name.String_len);
        printf(" monitor string : %s\n ", globNodeArr.NodeArr_val[i].Name.String_val);
	strcat( tp, " ");
        strcat ( tp, (char *)intToStr(i));
        strcat( tp, " &");
	printf("The value of string to start the monitor is %s\n", tp);
        monitorNode = i;
    }

    system( tp);
	printf("The value of string to start the monitor is %s\n", tp);
	printf("Monitor process STARTED .........\n ");

    pidArr.IntArr_len = MAX_PROGRAMS;
    pidArr.IntArr_val = (int *) malloc(pidArr.IntArr_len * sizeof(int));

    for( i = 0; i < pidArr.IntArr_len; i++) {
        pidArr.IntArr_val[i] = -1;
    }
  /*  printf("At the end of boot_up_1 %s %d %d\n", 
					globNodeArr.NodeArr_val[globMyId].ArchType.String_val, 
            curProgramNum, monitorNode);
*/ //  commenetd by sattu
#ifdef PRINT

  /*  PrintInLogFile("At the end of boot_up_1 %s %d %d\n", 
					globNodeArr.NodeArr_val[globMyId].ArchType.String_val, 
            curProgramNum, monitorNode);
*/ //commented by sattu
#endif

    retVal = 1;
	//Set this flag to true indicating that the initializatio of coordinator is 
	//now complete.
	initializationComplete = true;
    return &retVal;
}



// It has been proved by ddd that ther's problem with broadcast_subscribe segmentation here

/*
    broadcast_subscribe_1() :
    -----------------------
     Arguments : array of strings
                    Contains info regarding the invoker.
     
                Return the nodeArr if last node;
                    else dummy Arr;

*/

#ifdef NEW_VER_RPC

NodeArr* broadcast_subscribe_1_svc(StrArr* strArr, struct svc_req *junk)

#else

NodeArr* broadcast_subscribe_1(StrArr* strArr)

#endif
{
    CLIENT *cl;
    Node    node;
    int     i;
    char    buff[ MAXHOSTNAMELEN ];
    int     com;

	printf("Entering broadcast_subscribe...%d \n",initializationComplete );
	
	printf("value of global array when just entered broadcast_s:  globNodeArr.NodeArr_val[0].NodeId) %d\n",  globNodeArr.NodeArr_val[2].NodeId);
	
	
	printf("The name of strARR is %s\n", strArr->StrArr_val[4].String_val);
	printf("The length of strARR is %d\n",strArr->StrArr_val[4].String_len ); 
	
	
	//	sleep(10);	//added by sattu

	//If this function is called without the initialization of this
	//coordinator being done, then RETURN;
	if ( !initializationComplete ) {
		printf("Returning the broadcast_subscribe...initialization incomplete. \n" );
		return NULL;	
	}
	
    	if (strArr->StrArr_len != 7)      /* Just to check !! */ {
		printf("Returning the broadcast_subscribe...Array length problem. \n" );
        	return NULL;
    	}
    
    
    	GetHostNameAndIPadd(buff, NULL);
    
   // printf("in broadcast_subscribe:  just after gethostname and ipaddr \n");
  //  sleep(10);
    
    	strArr->StrArr_val[0].String_val[strArr->StrArr_val[0].String_len] = '\0';
    	strArr->StrArr_val[1].String_val[strArr->StrArr_val[1].String_len-1] = '\0';
    	strArr->StrArr_val[2].String_val[strArr->StrArr_val[2].String_len-1] = '\0';
    	strArr->StrArr_val[3].String_val[strArr->StrArr_val[3].String_len-1] = '\0';
    	strArr->StrArr_val[4].String_val[strArr->StrArr_val[4].String_len-1] = '\0';
    	strArr->StrArr_val[5].String_val[strArr->StrArr_val[5].String_len-1] = '\0';
    	strArr->StrArr_val[6].String_val[strArr->StrArr_val[6].String_len-1] = '\0';
    
#ifdef PRINT

PrintInLogFile("Within broadcastsubscribe : My name is %s and I got from %d %s \n ", buff,
                 strArr->StrArr_val[0].String_len,
                 strArr->StrArr_val[0].String_val); 

#endif

	printf("Within broadcastsubscribe : My name is %s , And I have got : \n
					Length is %d and Id %s \n", buff,
                 strArr->StrArr_val[0].String_len,
                 strArr->StrArr_val[0].String_val); 

    
    	SetNodeNull(&node);
    
   	CreateNode(&node, -1, strArr->StrArr_val[0].String_val,
                            strArr->StrArr_val[1].String_val,
                            (strArr->StrArr_val[2].String_val),
                            strArr->StrArr_val[3].String_val,
                            atoi(strArr->StrArr_val[4].String_val),
                            atol(strArr->StrArr_val[5].String_val),
                            atol(strArr->StrArr_val[6].String_val)
                            );

       // commented by sattu instead of assigning values we try a diff method.....

/*	node.NodeId = -1;
	PutInString(&(node.Name), strArr->StrArr_val[0].String_val);
	PutInString(&(node.IPaddress), strArr->StrArr_val[1].String_val);
	PutInString(&(node.ArchType), strArr->StrArr_val[2].String_val);
	PutInString(&(node.FileSys), strArr->StrArr_val[3].String_val);
	node.Capacity = atol(strArr->StrArr_val[4].String_val);
	node.RangeBegin = atol(strArr->StrArr_val[5].String_val);
	node.RangeEnd = atol(strArr->StrArr_val[6].String_val);
*/
	//If the server is the last one in the ARC ring ..
    if (globLastMe) {
		printf("I am the last node \n");
	
	printf("The value of globLastIndex %d\n", globLastIndex);
		
        for(i = 0; i < globLastIndex; i++) 
	{
            if (strcmp(globNodeArr.NodeArr_val[i].Name.String_val,
                            strArr->StrArr_val[0].String_val) == 0) 
	    	{
		printf("Entering If \n");
                break;   	   // if this happens - NodeId should be -2
            	}                  // As we are checking that node was already
		printf(" Not Entering If \n");
        }                          // present but failed and has come up again

        if (i < globLastIndex) {
            printf("in if(i < globLastIndex ) \n"); 
            node.NodeId = i;
	    printf("Copy here \n");
            Copy(&(globNodeArr.NodeArr_val[i]), &node);
	    printf("the value of globalNodeArr is NodeId: %d\n", globNodeArr.NodeArr_val[i].NodeId);
            if( i > globMyId) {

		    printf("Within  subscribe if(i > globmyid) : I am setting globLastMe to FALSE : globLastIndex = %d ,globMyId = %d\n",globLastIndex,globMyId);
                    globLastMe = false;
            }
        }
        
	else {
            printf("in else( (i > = globLastIndex) \n"); 
	    node.NodeId   = globLastIndex;
	    printf("Copy here \n");
            Copy(&(globNodeArr.NodeArr_val[globLastIndex]), &node);
	    
	    printf("Within  subscribe : I am setting globLastMe to FALSE :
				globLastIndex = %d ,globMyId = %d\n",globLastIndex,globMyId);

	    globLastMe = false;
            globLastIndex++;

	}

  /*    PrintInLogFile("returning globNodeArr \n");  */


		printf("initialize.c: value of NodeId field of Node is %d \n", globNodeArr.NodeArr_val[1].NodeId);
		printf("initialize.c: Name of Node is %s \n", globNodeArr.NodeArr_val[1].Name.String_val);
		printf("initialize.c:  IP of Node is %s \n", globNodeArr.NodeArr_val[1].IPaddress.String_val);
	        printf(" And hence I am sending the genuine list of machine  \n");

    		printf("returning globArr \n"); 
	//	sleep(20);

        return &globNodeArr;
    
    }
		printf("I am NOT the last node \n");
		printf(" And hence I am sending NULL\n");
     		tmpNodeArr.NodeArr_len =  globNodeArr.NodeArr_len;
     		tmpNodeArr.NodeArr_val = (Node*) ecalloc(globNodeArr.NodeArr_len, sizeof(Node));

    	for(i = 0; i < globNodeArr.NodeArr_len; i++) {
        	tmpNodeArr.NodeArr_val[i].NodeId = -3;
    	}
 
	/*   PrintInLogFile("returning tmpArr \n"); */
    
	printf("returning tmpArr \n"); 
    
	return &tmpNodeArr;
}

/*

    broadcast_join_1()
    ---------------------

        Arguments :
                Node which is to be added in the NodeArr;
                Contains info about the new joiner ;

         Add in the last;
         If max id, update last;
         If the joining node has to be monitored, update MonitorNode;

    This function  broadcasts the join request to all the other machines.
    These machines update their NodeArr and other states accordingly.

 */

#ifdef NEW_VER_RPC

int* broadcast_join_1_svc(Node* node, struct svc_req *junk)

#else
    
int* broadcast_join_1(Node* node)

#endif    

{
    int         newMonitorNode;
    int         len;
    int         i;
    TimerMesg   msg;

	//If this function is called without the initialization of this
	//coordinator being done, then RETURN;
	printf("Entering broadcast join \n");
	
	if ( !initializationComplete ) {
		return NULL;	
	}

	printf("Copy here \n");
    	Copy(&(globNodeArr.NodeArr_val[ node->NodeId ]), node);
    
    if (node->NodeId == globLastIndex) {
        globLastIndex++;
    }

    newMonitorNode = -2;

	//If this monitor was not monitoring any node, then it means that this 
	//was the only coordinator. Hence it will now start monitoring the
	//new incoming node.
    if( monitorNode == -1) {
        newMonitorNode = node->NodeId;
    }
    else {
        for( i = globMyId + 1; i < globLastIndex; i++) {
            if( globNodeArr.NodeArr_val[i].NodeId >= 0) {
                break;
            }
        }

        if( i == globLastIndex) {
            for( i = 0; i < globMyId ; i++) {
                if( globNodeArr.NodeArr_val[i].NodeId >= 0) {
                    break;
                }
            }
        }

        if( i == globMyId) {
            newMonitorNode = -1;
        }
        else {
            newMonitorNode = i;
        }
    }

#ifdef PRINT

PrintInLogFile( " Monitor Node =%d   NewMonitorNode=%d \n", monitorNode, newMonitorNode);

#endif

    if( (newMonitorNode != monitorNode) && ( newMonitorNode != -2)) {
         while( timerPid < 0);
         msg.mtype = timerPid;
         msg.nodeId = newMonitorNode;
         strncpy( msg.ipaddr, globNodeArr.NodeArr_val[newMonitorNode].IPaddress.String_val,
                 globNodeArr.NodeArr_val[newMonitorNode].IPaddress.String_len);
         msg.ipaddr[globNodeArr.NodeArr_val[newMonitorNode].IPaddress.String_len]
                    = '\0';
         len = sizeof(int) + 1 +
            globNodeArr.NodeArr_val[newMonitorNode].IPaddress.String_len;

         if(msgsnd( timerMsgQueueId, (char *)&msg.mtype, len, 0) != 0) {
            PrintInLogFile(" server can't send message queue 1 \n");
            printf(" server can't send message queue 1 \n");
         }

printf( " msg queue ->>> %d %s \n", msg.mtype, msg.ipaddr);
#ifdef PRINT

PrintInLogFile( " msg queue ->>> %d %s \n", msg.mtype, msg.ipaddr);

#endif

         monitorNode = newMonitorNode;
         kill( timerPid, SIGUSR1);
    }
    

#ifdef PRINT

PrintInLogFile( " returning %d %d \n", monitorNode, newMonitorNode);

#endif

    printf( " Monitor Node =%d   \n", monitorNode);

    retVal = globHighestSeq;
    printf("In broadcast join: The value returned is %d\n", retVal);
    return &retVal;
}

/**
 * This function is called by this bootUp procedure when it receives the response to its 
 * broadcast from other co-ordinators.
 * One of the functions of this functions is to set a flag that indicates that this host
 * is not the first one in the network, (since it has received the reply from some other
 * co-ordinator.
 */ 
// first arg gives result from server, second server id


/*int replySubscribe(int * tmp, struct sockaddr_in *addr) {
	printf("In new replySubscribe: Value of parameter is %d\n", *tmp);
	return 1;
}
*/

int replySubscribe(NodeArr* receivedNodeArr, struct sockaddr_in *addr) {
    
    char temparray[100];
    char temparray1[100];
    char temparray2[100];
    char temparray3[100];
    int     i , j;
    char    buff[ MAXHOSTNAMELEN ];
    char    ipAddress[212];
    struct  hostent *name;
    struct  in_addr  in;
    NodeArr tempArr;

	printf(" Intialize.c: Entering the method replySubscribe\n");
	//			sleep(20);   //added by sattu....
//	printf("Initialize.c : Within replySubscribe : The length of the node array is %d:\n",receivedNodeArr->NodeArr_len);
//	printf("Initialize.c : Within replySubscribe : The value of the node id is %d:\n",receivedNodeArr->NodeArr_val[1].NodeId);
//	printf("Initialize.c : Within replySubscribe : The name of the node  is %s:\n",receivedNodeArr->NodeArr_val[1].Name.String_val);
//	printf("Initialize.c : Within replySubscribe : The ip of the node  is %s:\n",receivedNodeArr->NodeArr_val[1].IPaddress.String_val);

	//	printf("Initialize.c : Within replySubscribe1 : The id-value of server is %ul:\n", addr->sin_addr.s_addr);

		/** 
		 * The value of node-id as -3 indicates that the response has been obtained from the 
		 *  server that is not the last node. In that case, we must wait to receive 
		   more replies till we get the response from the last node.
		 *  For the responses from the node that are not the last ones, 
		 *  the node-arr received in the argument is dummy array and hence 
		 *  it can be ignored.
		 */ 
    if(receivedNodeArr->NodeArr_val[0].NodeId == -3)   { 
			//The return value of 0 indicates that the host must wait for 
			//more replies.
			printf("Within replySubscribe : A dummy reply received.\n");
			return WAIT_FOR_MORE_REPLIES; 
	}
  	
		/** 
		 * Else it means that response has been obtained from a node 
		 * that is the last.
		 * The node-arr received as the argument contains the enitire 
		 * global-node array and its entries can be copied onto 
		 * some local node-arr.
		 */
    else {
        nodeArr.NodeArr_len = receivedNodeArr->NodeArr_len;
	printf("size of NodeArray = %d \n",nodeArr.NodeArr_len);
	tempArr.NodeArr_len = receivedNodeArr->NodeArr_len;
   
	     tempArr.NodeArr_val = (Node *) malloc ( 30 * sizeof(Node));
	//     tempArr.NodeArr_val = (Node *) malloc ( (tempArr.NodeArr_len) * sizeof(Node));
//    	tempArr.NodeArr_val = (Node*) ecalloc(tempArr.NodeArr_len
   //                                              , sizeof(Node));
	
	
	for(j = 0; j < receivedNodeArr->NodeArr_len; j++) {
	
       	        tempArr.NodeArr_val[j].NodeId= receivedNodeArr->NodeArr_val[j].NodeId;
	    	printf("Node ID of receivedNodeAr: %d \n", receivedNodeArr->NodeArr_val[j].NodeId);
	    	printf("Node ID of tempArr: %d \n", tempArr.NodeArr_val[j].NodeId);
       	        
		tempArr.NodeArr_val[j].Name = receivedNodeArr->NodeArr_val[j].Name;
	    	printf("Node name of receivedNodeAr: %s \n", receivedNodeArr->NodeArr_val[j].Name.String_val);
	    	printf("Node name of tempArr: %s \n", tempArr.NodeArr_val[j].Name.String_val);
		
		tempArr.NodeArr_val[j].IPaddress = receivedNodeArr->NodeArr_val[j].IPaddress;
	    	printf("Node ip of receivedNodeArr: %s \n", receivedNodeArr->NodeArr_val[j].IPaddress.String_val);
	    	printf("Node ip of tempArr: %s \n", tempArr.NodeArr_val[j].IPaddress.String_val);
		
		tempArr.NodeArr_val[j].ArchType = receivedNodeArr->NodeArr_val[j].ArchType;
	    	printf("Node archtype of receivedNodeArr: %s \n", receivedNodeArr->NodeArr_val[j].ArchType.String_val);
	    	printf("Node archtype of tempArr: %s \n", tempArr.NodeArr_val[j].ArchType.String_val);
		
		tempArr.NodeArr_val[j].FileSys = receivedNodeArr->NodeArr_val[j].FileSys;
	    	printf("Node filesys of receivedNodeArr : %s \n", receivedNodeArr->NodeArr_val[j].FileSys.String_val);
	    	printf("Node filesys of tempArr: %s \n", tempArr.NodeArr_val[j].FileSys.String_val);
		
		tempArr.NodeArr_val[j].Capacity = receivedNodeArr->NodeArr_val[j].Capacity;
	    	printf("Node capacity of  receivedNodeArr : %d \n", receivedNodeArr->NodeArr_val[j].Capacity);
	    	printf("Node capacity of tempArr: %d \n", tempArr.NodeArr_val[j].Capacity);
		
		tempArr.NodeArr_val[j].RangeBegin = receivedNodeArr->NodeArr_val[j].RangeBegin;
	    	printf("Node rangebegin of receivedNodeArr: %ul  \n", receivedNodeArr->NodeArr_val[j].RangeBegin);
	    	printf("Node rangebegin of tempArr: %ul  \n", tempArr.NodeArr_val[j].RangeBegin);
		
		tempArr.NodeArr_val[j].RangeEnd = receivedNodeArr->NodeArr_val[j].RangeEnd;
	    	printf("Node rangeend of receivedNodeArr: %ul \n\n", receivedNodeArr->NodeArr_val[j].RangeEnd);
	    	printf("Node rangeend of tempArr: %ul \n\n", tempArr.NodeArr_val[j].RangeEnd);

	}
			
        nodeArr.NodeArr_val = (Node *) malloc (	30 * sizeof(Node));
      //  nodeArr.NodeArr_val = (Node *) malloc (	(nodeArr.NodeArr_len) * sizeof(Node));
   // 	nodeArr.NodeArr_val = (Node*) ecalloc(nodeArr.NodeArr_len
       //                                          , sizeof(Node));

			/**
			 * Copy the list and information about the nodes received into some local array.
			 */ 
        for(i = 0; i < receivedNodeArr->NodeArr_len; i++) {
            if (receivedNodeArr->NodeArr_val[i].NodeId == -1) {
	    	printf("The value of i is %d\n" , i);
		printf("receivedNodeArr->NodeArr_val[i].NodeId == -1\n");
                nodeArr.NodeArr_val[i].NodeId = -1;
                break;
            }

//           Copy( &( nodeArr.NodeArr_val[i]) , &( tempArr.NodeArr_val[i] ) );
	  //  This copy statement took the hell out of me ..........15 days to find out  
	    printf("Copy here \n");
//           Copy(&(nodeArr.NodeArr_val[i]), &(receivedNodeArr->NodeArr_val[i]));
	//   sleep(5);
	       
	       sprintf(temparray, "%s",receivedNodeArr->NodeArr_val[i].Name.String_val);
	    printf("Copy here \n");
	       sprintf(temparray1, "%s",receivedNodeArr->NodeArr_val[i].IPaddress.String_val);
	       sprintf(temparray2, "%s",receivedNodeArr->NodeArr_val[i].ArchType.String_val);
	       sprintf(temparray3, "%s",receivedNodeArr->NodeArr_val[i].FileSys.String_val);
	     
	       nodeArr.NodeArr_val[i].NodeId = receivedNodeArr->NodeArr_val[i].NodeId;
	   //  nodeArr.NodeArr_val[i].Name = receivedNodeArr->NodeArr_val[i].Name;
	     
	     nodeArr.NodeArr_val[i].Name.String_len = receivedNodeArr->NodeArr_val[i].Name.String_len; 
	    printf("Copy here \n");
	     nodeArr.NodeArr_val[i].Name.String_val = (char *)strdup(temparray);
	     
	     nodeArr.NodeArr_val[i].IPaddress.String_len = receivedNodeArr->NodeArr_val[i].IPaddress.String_len; 
	     nodeArr.NodeArr_val[i].IPaddress.String_val = (char *)strdup(temparray1);

	     nodeArr.NodeArr_val[i].ArchType.String_len = receivedNodeArr->NodeArr_val[i].ArchType.String_len;
	     nodeArr.NodeArr_val[i].ArchType.String_val = (char *)strdup(temparray2);
	     
	     nodeArr.NodeArr_val[i].FileSys.String_len = receivedNodeArr->NodeArr_val[i].FileSys.String_len;
	     nodeArr.NodeArr_val[i].FileSys.String_val = (char *)strdup(temparray3);
//	     nodeArr.NodeArr_val[i].IPaddress = receivedNodeArr->NodeArr_val[i].IPaddress;
//	     nodeArr.NodeArr_val[i].ArchType = receivedNodeArr->NodeArr_val[i].ArchType;
//	     nodeArr.NodeArr_val[i].FileSys = receivedNodeArr->NodeArr_val[i].FileSys;
	  
	     nodeArr.NodeArr_val[i].Capacity= receivedNodeArr->NodeArr_val[i].Capacity;
	     nodeArr.NodeArr_val[i].RangeBegin= receivedNodeArr->NodeArr_val[i].RangeBegin;
	     nodeArr.NodeArr_val[i].RangeEnd= receivedNodeArr->NodeArr_val[i].RangeEnd;

	    
	    printf("The value of i is %d\n" , i);
	    printf("Node name of receivedNodeArr: %s \n", receivedNodeArr->NodeArr_val[i].Name.String_val);
//	    printf("Node name of temparray: %s \n", temparray); 
//	    printf("Node name of temparray1: IPaddrr %s \n", temparray1); 
	    printf("Node name of nodeArr: %s \n", nodeArr.NodeArr_val[i].Name.String_val);
	    printf("node Ip of recievedNodeArr = %s \n",receivedNodeArr->NodeArr_val[i].IPaddress.String_val);
	    printf("node Ip of nodeArr = %s \n", nodeArr.NodeArr_val[i].IPaddress.String_val);
	    printf("node Id of recievedNodeArr = %d \n",receivedNodeArr->NodeArr_val[i].NodeId);
	    printf("node Id of nodeArr = %d \n",nodeArr.NodeArr_val[i].NodeId);
        }
		
			printf("Initialize.c: Within replySubscribe : Reply from last node received.\n");

		/*	#ifdef PRINT
				PrintInLogFile( " returning replySub.. \n");
			#endif*/
	printf("Initialize.c : Within replySubscribe : The length of the node array is %d:\n",nodeArr.NodeArr_len);
	printf("Initialize.c : Within replySubscribe : The value of the node id is %d:\n",nodeArr.NodeArr_val[1].NodeId);
	printf("Initialize.c : Within replySubscribe : The name of the node  is %s:\n",nodeArr.NodeArr_val[1].Name.String_val);
	printf("Initialize.c : Within replySubscribe : The ip of the node  is %s:\n",nodeArr.NodeArr_val[1].IPaddress.String_val);
	
		printf( "Initialize.c:  returning replySub.. \n");
		free(tempArr.NodeArr_val);			
		//	sleep(20);
		
		//	printf("value of DO_NOT_WAIT_FOR_MORE_REPLIES is %d\n", DO_NOT_WAIT_FOR_MORE_REPLIES);	
			// The return value of 1 indicates that the host 
			// should no longer wait for further responses.
        return   DO_NOT_WAIT_FOR_MORE_REPLIES;
    }
}

/** This function method is called when the host machine is 
 * the first ARC node in the network.
 *  The purpose of this method is to initialize a node array 
 *  consisting of two nodes  :
 *  First node-entry contains all the information about the 
 *  host-machine and its node-id is "zero".
 *  Second node-entry is similar to the first-node entry expect that its 
 * node-id field is -1.
*/ 
void* initializeFirstNode( StrArr* strArr) {

    Node node;

	printf("Entering the function initializeFirstNode \n");
	//Since this is the first node to boot up let the global variable 
	//"globLastMe" be true.
	printf("Within initializeFirstNode : Setting globLastMe = TRUE\n");
	globLastMe = true;
		//Create a node whose id is "zero" and that contains 
		//all the information about the host machine.
    CreateNode(&node, 0, strArr->StrArr_val[0].String_val,
                            strArr->StrArr_val[1].String_val, 
                            (strArr->StrArr_val[2].String_val), 
                            strArr->StrArr_val[3].String_val,
                            atoi(strArr->StrArr_val[4].String_val), 
                            atol(strArr->StrArr_val[5].String_val),
                            atol(strArr->StrArr_val[6].String_val)
                            );
	
    nodeArr.NodeArr_len = 2;
    nodeArr.NodeArr_val = (Node *) malloc (2 * sizeof(Node));

		//Copy the newly created node in the node-array.
	    printf("Copy here \n");
    Copy(&(nodeArr.NodeArr_val[0]), &node);

		//Create second node whose id is -1 and this also contains 
		//all the information about the host machine.
    CreateNode(&node, -1, strArr->StrArr_val[0].String_val,
                            strArr->StrArr_val[1].String_val, 
                            strArr->StrArr_val[2].String_val, 
                            strArr->StrArr_val[3].String_val,
                            atoi(strArr->StrArr_val[4].String_val), 
                            atol(strArr->StrArr_val[5].String_val),
                            atol(strArr->StrArr_val[6].String_val)
                            );
		//Copy the second node in the second location in the node array.
	    printf("Copy here \n");
    Copy(&(nodeArr.NodeArr_val[1]), &node);

	#ifdef PRINT
		PrintInLogFile("Yes at right position %d  \n", nodeArr.NodeArr_val[0].NodeId);
	#endif
	printf("Leaving the function initializeFirstNode \n");
}



//added by sattu
//for checking the clnt_broadcast routine
#ifdef NEW_VER_RPC

int *broadcast_sattu_1_svc(StrArr* strArr, struct svc_req *junk)

#else

	int *broadcast_sattu_1(StrArr* strArr)
#endif
{	

    CLIENT *cl;
    Node    node;
    int     i;
    char    buff[ MAXHOSTNAMELEN ];
    int     com;
    int     *tmp1;

//	printf("Entering broadcast_subscribe...%d \n",initializationComplete );
	
//	printf("value of global array when just entered broadcast_s:  globNodeArr.NodeArr_val[0].NodeId) %d\n",  globNodeArr.NodeArr_val[2].NodeId);
	
	
//	printf("The name of strARR is %s\n", strArr->StrArr_val[4].String_val);
//	printf("The length of strARR is %d\n",strArr->StrArr_val[4].String_len ); 
	
	
	//	sleep(10);	//added by sattu

	//If this function is called without the initialization of this
	//coordinator being done, then RETURN;
	if ( !initializationComplete ) {
		printf("Returning the broadcast_subscribe...initialization incomplete. \n" );
		return NULL;	
	}
	
    	if (strArr->StrArr_len != 7)  { //     Just to check !!  {
		printf("Returning the broadcast_subscribe...Array length problem. \n" );
        	return NULL;
    	}
    
    
    	GetHostNameAndIPadd(buff, NULL);
    
   // printf("in broadcast_subscribe:  just after gethostname and ipaddr \n");
  //  sleep(10);
    
    	strArr->StrArr_val[0].String_val[strArr->StrArr_val[0].String_len] = '\0';
	printf("Arun likes debugging %d\n",strArr->StrArr_val[1].String_len );  
  	strArr->StrArr_val[1].String_val[strArr->StrArr_val[1].String_len-1] = '\0';
    	strArr->StrArr_val[2].String_val[strArr->StrArr_val[2].String_len-1] = '\0';
    	strArr->StrArr_val[3].String_val[strArr->StrArr_val[3].String_len-1] = '\0';
    	strArr->StrArr_val[4].String_val[strArr->StrArr_val[4].String_len-1] = '\0';
    	strArr->StrArr_val[5].String_val[strArr->StrArr_val[5].String_len-1] = '\0';
    	strArr->StrArr_val[6].String_val[strArr->StrArr_val[6].String_len-1] = '\0';
    
/*#ifdef PRINT

	PrintInLogFile("Within broadcastsubscribe : My name is %s and I got from %d %s \n ", buff,
                 strArr->StrArr_val[0].String_len,
                 strArr->StrArr_val[0].String_val); 

#endif

	printf("Within broadcastsubscribe : My name is %s , And I have got : \n
					Length is %d and Id %s \n", buff,
                 strArr->StrArr_val[0].String_len,
                 strArr->StrArr_val[0].String_val); 
*/
    
    	SetNodeNull(&node);
    
   /*	CreateNode(&node, -1, strArr->StrArr_val[0].String_val,
                            strArr->StrArr_val[1].String_val,
                            (strArr->StrArr_val[2].String_val),
                            strArr->StrArr_val[3].String_val,
                            atoi(strArr->StrArr_val[4].String_val),
                            atol(strArr->StrArr_val[5].String_val),
                            atol(strArr->StrArr_val[6].String_val)
                            );

   */    // commented by sattu instead of assigning values we try a diff method.....

/*	node.NodeId = -1;
	PutInString(&(node.Name), strArr->StrArr_val[0].String_val);
	PutInString(&(node.IPaddress), strArr->StrArr_val[1].String_val);
	PutInString(&(node.ArchType), strArr->StrArr_val[2].String_val);
	PutInString(&(node.FileSys), strArr->StrArr_val[3].String_val);
	node.Capacity = atol(strArr->StrArr_val[4].String_val);
	node.RangeBegin = atol(strArr->StrArr_val[5].String_val);
	node.RangeEnd = atol(strArr->StrArr_val[6].String_val);

	//If the server is the last one in the ARC ring ..
    if (globLastMe) {
		printf("I am the last node \n");
	
	printf("The value of globLastIndex %d\n", globLastIndex);
		
        for(i = 0; i < globLastIndex; i++) 
	{
            if (strcmp(globNodeArr.NodeArr_val[i].Name.String_val,
                            strArr->StrArr_val[0].String_val) == 0) 
	    	{
		printf("Entering If \n");
                break;   	   // if this happens - NodeId should be -2
            	}                  // As we are checking that node was already
		printf(" Not Entering If \n");
        }                          // present but failed and has come up again

        if (i < globLastIndex) {
            printf("in if(i < globLastIndex ) \n"); 
            node.NodeId = i;
	    printf("Copy here \n");
            Copy(&(globNodeArr.NodeArr_val[i]), &node);
	    printf("the value of globalNodeArr is NodeId: %d\n", globNodeArr.NodeArr_val[i].NodeId);
            if( i > globMyId) {

		    printf("Within  subscribe if(i > globmyid) : I am setting globLastMe to FALSE : globLastIndex = %d ,globMyId = %d\n",globLastIndex,globMyId);
                    globLastMe = false;
            }
        }
        
	else {
            printf("in else( (i > = globLastIndex) \n"); 
	    node.NodeId   = globLastIndex;
	    printf("Copy here \n");
         //   Copy(&(globNodeArr.NodeArr_val[globLastIndex]), &node);
	    
	    printf("Within  subscribe : I am setting globLastMe to FALSE :
				globLastIndex = %d ,globMyId = %d\n",globLastIndex,globMyId);

	    globLastMe = false;
            globLastIndex++;

	}

 */ /*    PrintInLogFile("returning globNodeArr \n");  */


	/*	printf("initialize.c: value of NodeId field of Node is %d \n", globNodeArr.NodeArr_val[1].NodeId);
		printf("initialize.c: Name of Node is %s \n", globNodeArr.NodeArr_val[1].Name.String_val);
		printf("initialize.c:  IP of Node is %s \n", globNodeArr.NodeArr_val[1].IPaddress.String_val);
	        printf(" And hence I am sending the genuine list of machine  \n");

    		printf("returning tmp \n"); 
	//	sleep(20);

 */   //    return &globNodeArr; //
	printf("Arun wants it here\n");
	tmp1 = (int *) malloc(sizeof(int));
	*tmp1 = 10;
	return tmp1;
    
 //   }
//	tmp = *i + 1;
/*	printf("\n");
	printf("The name of strARR is %s\n", strArr->StrArr_val[0].String_val);
	printf("The ip of strARR is %s\n", strArr->StrArr_val[1].String_val);
	tmp = 1;
	return &tmp;*/
}	

	

