ftp/ftpc.c
changeset 0 30d751ac6d49
child 1 47438813ede2
equal deleted inserted replaced
-1:000000000000 0:30d751ac6d49
       
     1 #include <rpc/rpc.h>
       
     2 #include <stdio.h>
       
     3 #include <string.h>
       
     4 #include "ftp.h"
       
     5 
       
     6 extern __thread int errno;
       
     7 
       
     8 /*
       
     9  * Gets the requested file from the server by calling the
       
    10  * remote procedure in a loop
       
    11  */
       
    12 int get_file(char *host, char *name)
       
    13 {
       
    14     CLIENT *clnt;
       
    15 	int total_bytes = 0, write_bytes;
       
    16     readfile_res *result;
       
    17 	request req;
       
    18 	FILE *file;
       
    19 
       
    20     /*
       
    21 	 * Initialize the request with the file name 
       
    22 	 */
       
    23 	req.name = name;
       
    24 
       
    25     /*
       
    26      * Create client handle used for calling FTPPROG on
       
    27      * the server designated on the command line. Use
       
    28      * the tcp protocol when contacting the server.
       
    29      */
       
    30     clnt = clnt_create(host, FTPPROG, FTPVER, "tcp");
       
    31     if (clnt == NULL) {
       
    32         /*
       
    33          * Couldn't establish connection with server.
       
    34          * Print error message and stop.
       
    35          */
       
    36          clnt_pcreateerror(host);
       
    37          exit(1);
       
    38     }
       
    39 
       
    40 	/*
       
    41 	 * Open the file for writing on the client machine
       
    42 	 */
       
    43     file = fopen(name, "w");
       
    44 
       
    45     /*
       
    46      * Call the remote procedure retrieve_file on the server.
       
    47 	 * During each iteration of the loop remote procedure is
       
    48 	 * called and only 1024 bytes of data is read and returned
       
    49 	 * by the server. The loop terminates when the data returned
       
    50 	 * from the server is less than 1024 bytes
       
    51      */
       
    52 	while (1) {
       
    53 		/*
       
    54 		 * Specifies the byte position where the next read should be
       
    55 		 * started in the server.
       
    56 		 */
       
    57 		req.start = total_bytes;
       
    58 
       
    59         result = retrieve_file_1(&req, clnt);
       
    60         if (result == NULL) {
       
    61             /*
       
    62              * An RPC error occurred while calling the server.
       
    63              * Print error message and stop.
       
    64              */
       
    65             clnt_perror(clnt, host);
       
    66             exit(1);
       
    67         }
       
    68 
       
    69         /*
       
    70          * We successfully called the remote procedure.
       
    71          */
       
    72         if (result->errno != 0) {
       
    73             /*
       
    74              * A remote system error occurred.
       
    75              * Print error message and stop.
       
    76              */
       
    77             errno = result->errno;
       
    78             perror(name);
       
    79             exit(1);
       
    80         }
       
    81 
       
    82         /*
       
    83          * Successfully got a chunk of the file.
       
    84          * Write into our local file and update the
       
    85 		 * total bytes of data read till now.
       
    86          */
       
    87 		write_bytes = fwrite(result->readfile_res_u.chunk.data, 1, result->readfile_res_u.chunk.bytes, file);
       
    88 		total_bytes += result->readfile_res_u.chunk.bytes;
       
    89 		if (result->readfile_res_u.chunk.bytes < MAXLEN) 
       
    90 		    break;
       
    91 	}
       
    92 
       
    93 	fclose(file);
       
    94 
       
    95 	return 0;
       
    96 }
       
    97 
       
    98 /*
       
    99  * Stores the file on the server by calling the remote
       
   100  * procedure in a loop
       
   101  */
       
   102 int put_file(char *host, char *name)
       
   103 {
       
   104     CLIENT *clnt;
       
   105     char data[1024];
       
   106 	int read_bytes;
       
   107     int *result;
       
   108 	chunksend chunk;
       
   109 	FILE *file;
       
   110 
       
   111     /*
       
   112      * Create client handle used for calling FTPPROG on
       
   113      * the server designated on the command line. Use
       
   114      * the tcp protocol when contacting the server.
       
   115      */
       
   116     clnt = clnt_create(host, FTPPROG, FTPVER, "tcp");
       
   117     if (clnt == NULL) {
       
   118         /*
       
   119          * Couldn't establish connection with server.
       
   120          * Print error message and stop.
       
   121          */
       
   122          clnt_pcreateerror(host);
       
   123          exit(1);
       
   124     }
       
   125 
       
   126     /*
       
   127 	 * Open the file that should be stored on the server
       
   128 	 */
       
   129     file = fopen(name, "r");
       
   130 
       
   131     /*
       
   132 	 * Initialize the chunk to be sent with the name
       
   133 	 * of the file
       
   134 	 */ 
       
   135 	chunk.name = name;
       
   136 
       
   137     /*
       
   138      * Call the remote procedure readdir on the server
       
   139 	 * in a loop sending only 1024 bytes of data in each
       
   140 	 * iteration. The loop terminates once the data less
       
   141 	 * than 1024 bytes is sent.
       
   142      */
       
   143 	while (1) {
       
   144 		read_bytes = fread(data, 1, MAXLEN, file);
       
   145 
       
   146         chunk.data = data;
       
   147 		chunk.bytes = read_bytes;
       
   148         result = send_file_1(&chunk, clnt);
       
   149 
       
   150         if (result == NULL) {
       
   151             /*
       
   152              * An RPC error occurred while calling the server.
       
   153              * Print error message and stop.
       
   154              */
       
   155             clnt_perror(clnt, host);
       
   156             exit(1);
       
   157         }
       
   158 
       
   159         /*
       
   160          * Okay, we successfully called the remote procedure.
       
   161          */
       
   162         if (*result != 0) {
       
   163             /*
       
   164              * A remote system error occurred.
       
   165              * Print error message and stop.
       
   166              */
       
   167             errno = *result;
       
   168             perror(name);
       
   169             exit(1);
       
   170         }
       
   171 
       
   172         /*
       
   173          * Successfully got a chunk of the file.
       
   174          * Write into our local file.
       
   175          */
       
   176 		if (read_bytes < MAXLEN) 
       
   177 		    break;
       
   178 	}
       
   179 
       
   180 	fclose(file);
       
   181 
       
   182 	return 0;
       
   183 }
       
   184 
       
   185 /*
       
   186  * Handles commands read on the command line and calls
       
   187  * the appropriate function to handle the command
       
   188  */
       
   189 int read_command(char *host)
       
   190 {
       
   191 	char command[MAXLEN];
       
   192 
       
   193 	printf("> ");
       
   194 	fflush(stdin);
       
   195 	gets(command);
       
   196 
       
   197     if (strncmp(command, "get", 3) == 0) {
       
   198 		return get_file(host, command+4);
       
   199 	} else if(strncmp(command, "put", 3) == 0){
       
   200 		return put_file(host, command+4);
       
   201 	} else if(strncmp(command, "exit", 4) == 0){
       
   202 		exit(0);
       
   203     } else {
       
   204 		return -1;
       
   205 	}
       
   206 }
       
   207 
       
   208 int main(int argc, char *argv[])
       
   209 {
       
   210    int result;
       
   211 
       
   212    if (argc != 2) {
       
   213         fprintf(stderr, "usage: %s host\n", argv[0]);
       
   214         exit(1);
       
   215    }
       
   216 
       
   217    /*
       
   218     * Command handling loop
       
   219 	*/
       
   220    while(TRUE) {
       
   221 	   result = read_command(argv[1]);
       
   222    }
       
   223 
       
   224    return 0;
       
   225 }
       
   226