Chapter 12. File Transfer in OmniRPC

File Transfer using Filename

OmniRPC supports file transfer between client program and remote executable program. In file transfer mode, you should spcify filenames which you want to transfer files.

Write Remote Executable Program

For an easy example, we show a program which concatinates 2 files and use the IDL file as is.

Module testfile;

Globals { 
#include <math.h>
}

Define testfile(IN filename infile[2], OUT filename outfile[])
{
    FILE *infp, *outfp;
    char tmp[128];
    int i;

    fprintf(stderr, "STUB : infile[0] : %s\n", infile[0]);
    fprintf(stderr, "STUB : infile[1] : %s\n", infile[1]);


    if((outfp = fopen(*outfile, "w+")) == NULL){
        perror("fopen");
        exit(1);
    }
    for(i = 0; i < 2; i++){
        if((infp = fopen(infile[i], "r+")) == NULL){
            perror("fopen");
            exit(1);
        }

        while(fgets(tmp, sizeof(tmp), infp) != NULL){
            fprintf(outfp, "%s", tmp);
        }
        fclose(infp);
    }

    fclose(outfp);
    fprintf(stderr, "STUB : END\n");
    fflush(stderr);
}

In this source code, special identification filename is introduced for file transfer. Type of filename is string (which is a alias of char *). In this example, infile[2] is string typed array variable. At the execution time, OmniRPC remote executable create new filename before the procedure in remote program. So you can use infile as filename strings. But output variable of outfile in IDL file is filename pointer, that alias is char **.

We can generate a remote executable program from the IDL file by using omrpc-cc. So, let's convert using this command.

         % omrpc-cc testfile.idl
        

Write Client Program

#include <OmniRpc.h>
#include <stdio.h>

int main(int argc,char *argv[])
{

   char *infile[2] = {"a.txt", "b.txt"};
   char *outfile = "a.out";
   char tmp[128];
   FILE *fp;
   int i,j;
   int c = 0;

   OmniRpcInit(&argc,&argv);

   for(i = 0 ;i < 2; i++){
       if((fp = fopen(infile[i], "w+")) == NULL){
           perror("cannot open file");
           exit(1);
       }
       for(j =0; j < 128; j++)
           fprintf(fp, "%i\n",c++);
       fflush(fp);
       if(fclose(fp) != 0){
           perror("cannot close file");
       }
   }

   OmniRpcCall("testfile", infile, &outfile);

   fprintf(stderr, "TRANSFER FIN\n");
   fflush(stderr);

   if((fp = fopen(outfile, "r+")) == NULL){
       perror("cannot open file");
       exit(1);
   }
   while(fgets(tmp, sizeof(tmp), fp) != NULL){
       fprintf(stdout, "OUTPUT:%s", tmp);
   }

  OmniRpcFinalize();
}

We can generate a client program from the C file by using omrpc-cc. So, let's convert using this command.

         % omrpc-cc -o testfile testfile.c 
        

Execution of Program

Before you execute this example, you should prepaer 2 file (named a.txt and b.txt) in the same directory on which client program is.

You can execute the client program in the same manner without using the hosts.xml file.

% testfile --hostfile hosts.xml
        

After execution, you can see the file named "a.out" in the the same direcotry of client program.

Setting of WorkingDirectory

OmniRPC remote executable uses a temporary directory to store files. Default temporary directory is "/tmp", but you can use another directory by specifying the WorkingPath in hostfile. And your login id has write and read permission on that directory. We show an example of hostfile which specify temporary directory.

<OmniRpcConfig>
   <Host name="alice.hpcc.jp" user="foo" arch="i386" os="linux">
        <Agent invoker="globus" mxio="on" path="/usr/local/omrpc"/>
        <JobScheduler type="rr" maxjob="6" />
        <Registry path="/home/foo/app/stubs" />
        <WorkingPath path="/home/foo/tmp" />
   </Host>
</OmniRpcConfig>