#include "extnDefn.h"
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <rpc/rpc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

FILE *fptr;
int  retVal;
u_long progNum;

/*

         init_file_ptr_3()
         ---------------------
                 Arguments:
                        String fileName, iniitalize a file ptr;

This function is used to initialize posting a file. 
*/

#ifdef NEW_VER_RPC

int*
init_file_ptr_3_svc(String* fileName,  struct svc_req *Jlt1)

#else

int*
init_file_ptr_3(String* fileName)
     
#endif

{
   char  localName[1024];

   strcpy(localName, DIRNAME);
   strncat(localName, fileName->String_val, fileName->String_len);

   if ((fptr = fopen(localName, "w")) == NULL)
   {
        return NULL;
   }

   retVal = 1;
   return &retVal;
}

/*

        put_in_file_3()
        -----------------
            
              Arguments:

                    data, contents of the file;

This function puts data in the iniitalized file 
Used for posting a file.

*/

#ifdef NEW_VER_RPC

int*
put_in_file_3_svc(String* data,  struct svc_req *Jlt1)

#else

int*
put_in_file_3(String* data)

#endif

{
    
#ifdef PRINT

PrintInLogFile( "%d \n", data->String_len);

#endif

    
    retVal = fwrite(data->String_val, data->String_len, 1, fptr);
    fflush(fptr);

    return &retVal;
}


/*

      close_file_3()
      ------------------
                Arguments:
                    
                    String, filename to be closed;

This function closes the remote file.
Used to post a file.

*/

#ifdef NEW_VER_RPC

int*
close_file_3_svc(String* str,  struct svc_req *Jlt1)

#else

int*
close_file_3(String* str)

#endif

{
    retVal = fclose(fptr);

    return &retVal;
}


/*

   CompileFile()
   ------------------

            Arguments:
                RibInf, The Info of the rib whose server is to compiled;

This function compiles the Rib server. 

*/

void 
CompileFile( RibInf* ribInf)
{

    char     tp[250]; 
    int      i;
   
    strcpy(tp, DIRNAME);
    strcat( tp, "exeser ");
    strncat(tp, ribInf->FuncName.String_val,
            ribInf->FuncName.String_len);
    strcat(tp, " ");
    strcat(tp, DIRNAME);
    strcat(tp, " ARC");
    strncat(tp, ribInf->FuncName.String_val,
            ribInf->FuncName.String_len);

	//Added by Aruna 
	//printf("Compilation Path is ...%s....\n",tp);
#ifdef PRINT

    PrintInLogFile( "%s \n", tp);

#endif

    system(tp);
}
        
/*

   ExecuteFile()
   ----------------

        Arguments:
            RibInf, info of the RIB which is to be excuted;

This function starts the execution of a RIB server.

*/

void
ExecuteFile( RibInf *ribInf)
{
    char     tp[250]; 
    char     tp1[250]; 

	//PrintInResult("I am in execute file ..............\n");
    strcpy( tp1, "chmod 700 ");
    strcat( tp1 , DIRNAME);
    //strcat( tp1, "bin/"); Aruna 
    strncat(tp1, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
    strcat( tp1, "_svc ");
	//PrintInResult("%s\n",tp1);
    system(tp1);
   
    strcpy (tp, DIRNAME);
    //strcat( tp, "bin/"); Aruna
    strncat(tp, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
    strcat( tp, "_svc ");
    strcat( tp, intToStr(progNum));
    strcat( tp, " &");
	//printf("Executable file path is ...%s\n",tp);
    system(tp);

    curProgramNum++;

    if( curProgramNum >= globNodeArr.NodeArr_val[globMyId].RangeEnd)
    {
        curProgramNum = globNodeArr.NodeArr_val[globMyId].RangeBegin;
    }
}

u_long
GetProgNum()
{
    return curProgramNum;
}


/*

        process_rib_3()
        -----------------

                Arguments:
                    RibInf, info of the which is sent for execution to
                    this node;

                Starts the server, compile if recquired;

This function starts an ARC function server locally.

*/



#ifdef NEW_VER_RPC

u_long*
process_rib_3_svc(RibInf* ribInf, struct svc_req* junk)

#else

u_long*
process_rib_3(RibInf* ribInf)

#endif

{
	//PrintInResult("I am in process RIB \n");

    if( ribInf->NodeId == -1)
    {
         ribInf->NodeId = globMyId;
    }

    if( strcmp(globNodeArr.NodeArr_val[ ribInf->NodeId].ArchType.String_val, 
                globNodeArr.NodeArr_val[ globMyId].ArchType.String_val ))
    {
        CompileFile( ribInf);
    }
    progNum = GetProgNum();

#ifdef PRINT
    
PrintInLogFile( "\nProgram No:%x \n", progNum);

#endif

	//PrintInResult("Before executing exeser \n");
    ExecuteFile( ribInf);
    return &progNum;
}


/*

        cleanup_3()
        ---------------
               Arguments:
                    RibInf, info of the RIB which is terminated;

        invoke the function to remove the remote files posted for 
        RIB execution by the user program.

*/
                
#ifdef NEW_VER_RPC

void*
cleanup_3_svc(RibInf* ribInf, struct svc_req* junk)

#else

void*
cleanup_3(RibInf* ribInf)

#endif
{

    int clntFlag = 1;
    CLIENT* cl;
    static struct timeval timeout = {0, 0} ;

    if( ribInf->NodeId != globMyId)
    {
        if ((cl = clnt_create( globNodeArr.NodeArr_val[ribInf->NodeId].IPaddress.String_val,
               COORDINATOR, SERVER,"tcp")) == NULL)
        {
                clnt_pcreateerror(
                   globNodeArr.NodeArr_val[ribInf->NodeId].IPaddress.String_val );
                clntFlag = 0;
        }

#ifdef PRINT

        PrintInLogFile("%d %d \n", ribInf->NodeId, globMyId); 
#endif

        ribInf->NodeId = globMyId;

        if(clntFlag)
        {
            clnt_call(cl, REMOVE_FILES, xdr_RibInf, ribInf, 
                    xdr_void, NULL, timeout);
        }
    }
}
        
/*

        remove_files_3()
        ---------------
               Arguments:
                    RibInf, info of the RIB which is terminated;

        remove the remote files posted for RIB execution.

*/

#ifdef NEW_VER_RPC

void*
remove_files_3_svc(RibInf* ribInf, struct svc_req* junk)

#else

void*
remove_files_3(RibInf* ribInf)

#endif
{
    char    tp1[500];
    char    tp[100];

	//PrintInResult("I am in remove file .....................\n");
    if(strcmp(globNodeArr.NodeArr_val[ ribInf->NodeId].FileSys.String_val, 
                globNodeArr.NodeArr_val[ globMyId].FileSys.String_val ))
    {
        if( strcmp(globNodeArr.NodeArr_val[ ribInf->NodeId].ArchType.String_val, 
                globNodeArr.NodeArr_val[ globMyId].ArchType.String_val ))
        {
            strcpy( tp1, "rm ");
            strcat( tp1 , DIRNAME);
            //strcat( tp1, "src/");
            strncat(tp1, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
            strcat( tp1, ".x ");

            strcat( tp1 , DIRNAME);
            //strcat( tp1, "src/");
            strncat(tp1, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
            strcat( tp1, "_proc.c ");

            strcat( tp1 , DIRNAME);
            //strcat( tp1, "src/");
            strncat(tp1, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
            strcat( tp1, "_svc.c ");

            strcat( tp1 , DIRNAME);
            //strcat( tp1, "src/");
            strncat(tp1, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
            strcat( tp1, "_xdr.c ");

            strcat( tp1 , DIRNAME);
            //strcat( tp1, "src/");
            strncat(tp1, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
            strcat( tp1, "_clnt.c ");

            system(tp1);
        }
            
        strcpy( tp, "rm ");
        strcat( tp , DIRNAME);
        //strcat( tp, "bin/");
        strncat(tp, ribInf->FuncName.String_val, ribInf->FuncName.String_len);
        strcat( tp, "_svc ");
        system(tp);
    }
}


