# HG changeset patch # User Madhusudan.C.S # Date 1263815499 -19800 # Node ID 47438813ede29f99099a82d107fdb235134f30a0 # Parent 30d751ac6d494078081553fbb0ab629d54fece30 Added support for handling binary files. The problem was I was using XDR strings for reading data, storing it and transferring to the client from the server. But since this is no better than null-terminated string, whenever data had \000 the data used to become corrupt from that point. So now I changed all data to be integer arrays so there is no question of corruption. diff -r 30d751ac6d49 -r 47438813ede2 ftp/Makefile --- a/ftp/Makefile Mon Jan 18 14:10:13 2010 +0530 +++ b/ftp/Makefile Mon Jan 18 17:21:39 2010 +0530 @@ -1,17 +1,29 @@ # Makefile: To build client and server for ftp implemented using RPC -all: stubs ftp_xdr.o ftps ftpc +all: stubs ftp_xdr.o server client + +debug: stubs ftp_xdr.o ftps-dbg ftpc-dbg server: ftps +server-dbg: ftps-dbg + client: ftpc +client-dbg: ftpc-dbg + ftps: ftp_svc.c ftps.c ftp_xdr.o ftp.h gcc ftp_svc.c ftps.c ftp_xdr.o -o ftps +ftps-dbg: ftp_svc.c ftps.c ftp_xdr.o ftp.h + gcc ftp_svc.c ftps.c ftp_xdr.o -o ftps-dbg -g + ftpc: ftpc.c ftp_clnt.c ftp_xdr.o ftp.h gcc ftpc.c ftp_clnt.c ftp_xdr.o -o ftpc +ftpc-dbg: ftpc.c ftp_clnt.c ftp_xdr.o ftp.h + gcc ftpc.c ftp_clnt.c ftp_xdr.o -o ftpc-dbg -g + ftp_xdr.o: ftp_xdr.c ftp.h gcc -c ftp_xdr.c @@ -19,4 +31,4 @@ rpcgen ftp.x clean: - rm ftp_xdr.o ftpc ftps ftp_clnt.c ftp_svc.c ftp_xdr.c ftp.h + rm ftp_xdr.o ftpc ftps ftp_clnt.c ftp_svc.c ftp_xdr.c ftp.h ftps-dbg ftpc-dbg diff -r 30d751ac6d49 -r 47438813ede2 ftp/ftp.x --- a/ftp/ftp.x Mon Jan 18 14:10:13 2010 +0530 +++ b/ftp/ftp.x Mon Jan 18 17:21:39 2010 +0530 @@ -14,7 +14,7 @@ * and the byte number at which to start reading the file from */ struct request { - filename name; + filename name; int start; }; @@ -28,7 +28,7 @@ * sent from the server to the client in the current * remote procedure call */ -typedef int filechunk; +typedef int filechunk[MAXLEN]; /* * Response sent by the server to the client as a response @@ -36,8 +36,8 @@ * the current call and number of bytes actually read */ struct chunkreceive { - filechunk data; - int bytes; + filechunk data; + int items; }; /* @@ -52,9 +52,9 @@ * number of bytes in the data */ struct chunksend { - filename name; + filename name; filechunk data; - int bytes; + int items; }; /* @@ -69,10 +69,10 @@ * or will return the error number if an error occured */ union readfile_res switch (int errno) { - case 0: - chunkreceive chunk; - default: - void; + case 0: + chunkreceive chunk; + default: + void; }; /* @@ -81,9 +81,9 @@ * the remote procedure signature */ program FTPPROG { - version FTPVER { - readfile_res retrieve_file(request *) = 1; - int send_file(chunksend *) = 2; - } = 1; + version FTPVER { + readfile_res retrieve_file(request *) = 1; + int send_file(chunksend *) = 2; + } = 1; } = 0x20000011; diff -r 30d751ac6d49 -r 47438813ede2 ftp/ftpc.c --- a/ftp/ftpc.c Mon Jan 18 14:10:13 2010 +0530 +++ b/ftp/ftpc.c Mon Jan 18 17:21:39 2010 +0530 @@ -12,15 +12,15 @@ int get_file(char *host, char *name) { CLIENT *clnt; - int total_bytes = 0, write_bytes; + int bytes = 0, write_items; readfile_res *result; - request req; - FILE *file; + request req; + FILE *file; /* - * Initialize the request with the file name - */ - req.name = name; + * Initialize the request with the file name + */ + req.name = name; /* * Create client handle used for calling FTPPROG on @@ -40,7 +40,7 @@ /* * Open the file for writing on the client machine */ - file = fopen(name, "w"); + file = fopen(name, "wb"); /* * Call the remote procedure retrieve_file on the server. @@ -49,12 +49,12 @@ * by the server. The loop terminates when the data returned * from the server is less than 1024 bytes */ - while (1) { - /* - * Specifies the byte position where the next read should be - * started in the server. - */ - req.start = total_bytes; + while (1) { + /* + * Specifies the byte position where the next read should be + * started in the server. + */ + req.start = bytes; result = retrieve_file_1(&req, clnt); if (result == NULL) { @@ -82,17 +82,17 @@ /* * Successfully got a chunk of the file. * Write into our local file and update the - * total bytes of data read till now. + * total bytes of data read till now. */ - write_bytes = fwrite(result->readfile_res_u.chunk.data, 1, result->readfile_res_u.chunk.bytes, file); - total_bytes += result->readfile_res_u.chunk.bytes; - if (result->readfile_res_u.chunk.bytes < MAXLEN) - break; - } + write_items = fwrite(result->readfile_res_u.chunk.data, sizeof(int), result->readfile_res_u.chunk.items, file); + bytes += result->readfile_res_u.chunk.items * (sizeof(int)); + if (result->readfile_res_u.chunk.items < MAXLEN) + break; + } - fclose(file); + fclose(file); - return 0; + return 0; } /* @@ -102,11 +102,10 @@ int put_file(char *host, char *name) { CLIENT *clnt; - char data[1024]; - int read_bytes; int *result; - chunksend chunk; - FILE *file; + filechunk data; + chunksend chunk; + FILE *file; /* * Create client handle used for calling FTPPROG on @@ -124,27 +123,24 @@ } /* - * Open the file that should be stored on the server - */ - file = fopen(name, "r"); + * Open the file that should be stored on the server + */ + file = fopen(name, "rb"); /* - * Initialize the chunk to be sent with the name - * of the file - */ - chunk.name = name; + * Initialize the chunk to be sent with the name + * of the file + */ + chunk.name = name; /* * Call the remote procedure readdir on the server - * in a loop sending only 1024 bytes of data in each - * iteration. The loop terminates once the data less - * than 1024 bytes is sent. + * in a loop sending only 1024 bytes of data in each + * iteration. The loop terminates once the data less + * than 1024 bytes is sent. */ - while (1) { - read_bytes = fread(data, 1, MAXLEN, file); - - chunk.data = data; - chunk.bytes = read_bytes; + while (1) { + chunk.items = fread(chunk.data, sizeof(int), MAXLEN, file); result = send_file_1(&chunk, clnt); if (result == NULL) { @@ -173,13 +169,13 @@ * Successfully got a chunk of the file. * Write into our local file. */ - if (read_bytes < MAXLEN) - break; - } + if (chunk.items < MAXLEN) + break; + } - fclose(file); + fclose(file); - return 0; + return 0; } /* @@ -188,21 +184,21 @@ */ int read_command(char *host) { - char command[MAXLEN]; + char command[MAXLEN]; - printf("> "); - fflush(stdin); - gets(command); + printf("> "); + fflush(stdin); + gets(command); if (strncmp(command, "get", 3) == 0) { - return get_file(host, command+4); - } else if(strncmp(command, "put", 3) == 0){ - return put_file(host, command+4); - } else if(strncmp(command, "exit", 4) == 0){ - exit(0); + return get_file(host, command+4); + } else if(strncmp(command, "put", 3) == 0){ + return put_file(host, command+4); + } else if(strncmp(command, "exit", 4) == 0){ + exit(0); } else { - return -1; - } + return -1; + } } int main(int argc, char *argv[]) @@ -216,9 +212,9 @@ /* * Command handling loop - */ + */ while(TRUE) { - result = read_command(argv[1]); + result = read_command(argv[1]); } return 0; diff -r 30d751ac6d49 -r 47438813ede2 ftp/ftps.c --- a/ftp/ftps.c Mon Jan 18 14:10:13 2010 +0530 +++ b/ftp/ftps.c Mon Jan 18 17:21:39 2010 +0530 @@ -6,46 +6,43 @@ readfile_res* retrieve_file_1_svc(request *req, struct svc_req *rqstp) { - FILE *file; - char data[1024]; - int bytes; - static readfile_res res; + FILE *file; + filechunk data; + static readfile_res res; - file = fopen(req->name, "r"); + file = fopen(req->name, "rb"); if (file == NULL) { - res.errno = errno; - return (&res); + res.errno = errno; + return (&res); } xdr_free((xdrproc_t)xdr_readfile_res, (char *)&res); fseek (file, req->start, SEEK_SET); - bytes = fread(data, 1, MAXLEN, file); - res.readfile_res_u.chunk.data = data; - res.readfile_res_u.chunk.bytes = bytes; + res.readfile_res_u.chunk.items = fread(res.readfile_res_u.chunk.data, sizeof(int), MAXLEN, file); - /* + /* * Return the result */ res.errno = 0; fclose(file); - return (&res); + return (&res); } int* send_file_1_svc(chunksend *rec, struct svc_req *rqstp) { - FILE *file; - int write_bytes; + FILE *file; + int write_items; static int result; - file = fopen(rec->name, "a"); - if (file == NULL) { - result = errno; - return &result; - } + file = fopen(rec->name, "ab"); + if (file == NULL) { + result = errno; + return &result; + } - write_bytes = fwrite(rec->data, 1, rec->bytes, file); - fclose(file); + write_items = fwrite(rec->data, sizeof(int), rec->items, file); + fclose(file); result = 0; return &result;