ftp/ftpc.c
changeset 0 30d751ac6d49
child 1 47438813ede2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ftp/ftpc.c	Mon Jan 18 14:10:13 2010 +0530
@@ -0,0 +1,226 @@
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <string.h>
+#include "ftp.h"
+
+extern __thread int errno;
+
+/*
+ * Gets the requested file from the server by calling the
+ * remote procedure in a loop
+ */
+int get_file(char *host, char *name)
+{
+    CLIENT *clnt;
+	int total_bytes = 0, write_bytes;
+    readfile_res *result;
+	request req;
+	FILE *file;
+
+    /*
+	 * Initialize the request with the file name 
+	 */
+	req.name = name;
+
+    /*
+     * Create client handle used for calling FTPPROG on
+     * the server designated on the command line. Use
+     * the tcp protocol when contacting the server.
+     */
+    clnt = clnt_create(host, FTPPROG, FTPVER, "tcp");
+    if (clnt == NULL) {
+        /*
+         * Couldn't establish connection with server.
+         * Print error message and stop.
+         */
+         clnt_pcreateerror(host);
+         exit(1);
+    }
+
+	/*
+	 * Open the file for writing on the client machine
+	 */
+    file = fopen(name, "w");
+
+    /*
+     * Call the remote procedure retrieve_file on the server.
+	 * During each iteration of the loop remote procedure is
+	 * called and only 1024 bytes of data is read and returned
+	 * 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;
+
+        result = retrieve_file_1(&req, clnt);
+        if (result == NULL) {
+            /*
+             * An RPC error occurred while calling the server.
+             * Print error message and stop.
+             */
+            clnt_perror(clnt, host);
+            exit(1);
+        }
+
+        /*
+         * We successfully called the remote procedure.
+         */
+        if (result->errno != 0) {
+            /*
+             * A remote system error occurred.
+             * Print error message and stop.
+             */
+            errno = result->errno;
+            perror(name);
+            exit(1);
+        }
+
+        /*
+         * Successfully got a chunk of the file.
+         * Write into our local file and update the
+		 * 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;
+	}
+
+	fclose(file);
+
+	return 0;
+}
+
+/*
+ * Stores the file on the server by calling the remote
+ * procedure in a loop
+ */
+int put_file(char *host, char *name)
+{
+    CLIENT *clnt;
+    char data[1024];
+	int read_bytes;
+    int *result;
+	chunksend chunk;
+	FILE *file;
+
+    /*
+     * Create client handle used for calling FTPPROG on
+     * the server designated on the command line. Use
+     * the tcp protocol when contacting the server.
+     */
+    clnt = clnt_create(host, FTPPROG, FTPVER, "tcp");
+    if (clnt == NULL) {
+        /*
+         * Couldn't establish connection with server.
+         * Print error message and stop.
+         */
+         clnt_pcreateerror(host);
+         exit(1);
+    }
+
+    /*
+	 * Open the file that should be stored on the server
+	 */
+    file = fopen(name, "r");
+
+    /*
+	 * 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.
+     */
+	while (1) {
+		read_bytes = fread(data, 1, MAXLEN, file);
+
+        chunk.data = data;
+		chunk.bytes = read_bytes;
+        result = send_file_1(&chunk, clnt);
+
+        if (result == NULL) {
+            /*
+             * An RPC error occurred while calling the server.
+             * Print error message and stop.
+             */
+            clnt_perror(clnt, host);
+            exit(1);
+        }
+
+        /*
+         * Okay, we successfully called the remote procedure.
+         */
+        if (*result != 0) {
+            /*
+             * A remote system error occurred.
+             * Print error message and stop.
+             */
+            errno = *result;
+            perror(name);
+            exit(1);
+        }
+
+        /*
+         * Successfully got a chunk of the file.
+         * Write into our local file.
+         */
+		if (read_bytes < MAXLEN) 
+		    break;
+	}
+
+	fclose(file);
+
+	return 0;
+}
+
+/*
+ * Handles commands read on the command line and calls
+ * the appropriate function to handle the command
+ */
+int read_command(char *host)
+{
+	char command[MAXLEN];
+
+	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);
+    } else {
+		return -1;
+	}
+}
+
+int main(int argc, char *argv[])
+{
+   int result;
+
+   if (argc != 2) {
+        fprintf(stderr, "usage: %s host\n", argv[0]);
+        exit(1);
+   }
+
+   /*
+    * Command handling loop
+	*/
+   while(TRUE) {
+	   result = read_command(argv[1]);
+   }
+
+   return 0;
+}
+