After working on the code until 10 am, I managed to write the code. Here is the code itself, who can interested in it can copy and run it (hope helps anybody interested in the subject). To compile the program just run "make" from command line. I got help from the codes from my theacher
You must have rpcbind running on your machine.
I know it is ugly yo paste all the code, but I have nowhere to upload!
Code:
/* exercise.x */
#define VERSION_NUMBER 1
const MAXLEN = 32;
typedef string strtype<MAXLEN>;
/* I had some errors with original timeval! */
struct mytimeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
struct struct_t {
struct mytimeval tv;
strtype str;
};
/**************************************
* Since only one argument is allowed
* I pack the data in a struct
**************************************/
struct dataPack_t {
struct struct_t data;
int fd;
};
program MYRPC_PROG {
version MYRPC_VERSION {
int OPENREMOTE(string) = 1;
int STOREREMOTE(dataPack_t) = 2;
int CLOSEREMOTE(int) = 3;
} = VERSION_NUMBER;
} = 777777777;
Code:
/**********************************************
* exerciseservice.c
* This file includes function implementations
* Will be used by the server process.
***********************************************/
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <rpc/rpc.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "exercise.h"
/* Returns valid fd on success and zero on failure */
int *
openremote_1_svc (char **file_name, struct svc_req *rqstp)
{
int fd;
static int ret;
if ((fd=open(*file_name, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR))<0)
{
perror("open");
ret = 0;
return &ret;
}
ret = fd;
return &ret;
}
/* Returns one on success and zero on failure */
int *
storeremote_1_svc (struct dataPack_t *dp, struct svc_req *rqstp)
{
char tmp[256];
static int ret;
sprintf(tmp,"%ld\n%ld\n%s\n\n", dp->data.tv.tv_sec, dp->data.tv.tv_usec, dp->data.str);
if (write(dp->fd, tmp, strlen(tmp))<0)
{
perror("write");
ret = 0;
return &ret;
}
ret = 1;
return &ret;
}
/* Returns one on success and zero on failure */
int *
closeremote_1_svc (int *my_file, struct svc_req *rqstp)
{
static int ret;
if (close(*my_file)<0)
{
perror("close");
ret = 0;
return &ret;
}
else
{
ret = 1;
return &ret;
}
}
Code:
/* exerciseclient.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <rpc/rpc.h>
#include "exercise.h"
int main(int argc, char *argv[])
{
CLIENT *cl;
char *server, *filename;
struct dataPack_t dp;
struct timeval tv;
int *fdp;
int *ret;
int i;
if (argc!=3)
{
fprintf(stderr,"Usage : %s hostname filename\n",argv[0]);
exit(0);
}
server = argv[1];
filename = argv[2];
/********************************************
* Create client handle that will be used
* for MYRPC. We tell the RPC package to use
* "tcp" protocol when contacting the server.
********************************************/
cl = clnt_create(server, MYRPC_PROG, MYRPC_VERSION, "tcp");
if (cl == (CLIENT *)NULL)
{
clnt_pcreateerror(server);
exit(1);
}
/**********************************
* Remote open
**********************************/
fdp = openremote_1 (&filename, cl);
if (*fdp == 0)
{
fprintf(stderr,"Cannot open remote file!\n");
exit(1);
}
dp.data.str = malloc(32);
for (i=0; i<25; i++)
{
/*********************************
* usleep() for a while to get
* a different timeval value.
*********************************/
usleep(rand()%1000000);
if (gettimeofday(&tv,NULL)<0)
{
perror("gettimeofday");
exit(1);
}
dp.data.tv.tv_sec = tv.tv_sec;
dp.data.tv.tv_usec = tv.tv_usec;
/********************************
* Generate a random string
*********************************/
dp.data.str = tempnam("/tmp","rand_");
dp.fd = *fdp;
printf("%ld\n%ld\n%s\n\n",dp.data.tv.tv_sec, dp.data.tv.tv_usec, dp.data.str);
/********************************
* Remote write
********************************/
ret = storeremote_1 (&dp, cl);
if (*ret == 0)
{
fprintf(stderr,"Cannot write data into remote file!\n");
exit(1);
}
}
/******************************
* Remote close
******************************/
ret = closeremote_1 (fdp, cl);
if (*ret == 0)
{
fprintf(stderr,"Cannot close remote file!\n");
exit(1);
}
return 0;
}
Makefile
Code:
.c.o:
gcc -c -Wall $<
all: client server
client: exerciseclient.o exercise_clnt.o exercise_xdr.o
gcc -o client exerciseclient.o exercise_clnt.o exercise_xdr.o
server: exerciseservice.o exercise_svc.o exercise_xdr.o
gcc -o server exerciseservice.o exercise_svc.o exercise_xdr.o
exercise_clnt.o: exercise_clnt.c
gcc -o exercise_clnt.o -c exercise_clnt.c
exercise_xdr.o: exercise_xdr.c
gcc -o exercise_xdr.o -c exercise_xdr.c
exercise_svc.o: exercise_svc.c
gcc -o exercise_svc.o -c exercise_svc.c
exercise.h: exercise.x
rpcgen -C exercise.x
clean :
rm server client *.o exercise_svc.c exercise_xdr.c exercise_clnt.c exercise.h
exerciseclient.c: exercise.h
exerciseservice.c: exercise.h