1 #include <stdio.h> 2 #include <rpc/rpc.h> 3 #include <netdb.h> 4 #include <sys/socket.h> 5 #include <errno.h> 6 #include <fcntl.h> 7 #include <sys/ioctl.h> 8 #include <sys/stat.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include "librpc01.h" 13 14 int program = 2000333; 15 int version = 10; 16 char *server = NULL; 17 char *file_name = NULL; 18 char host_name[100]; 19 long host_address; 20 21 void do_compare(int, char *, struct data *, char *); 22 void usage_error(char *program_name); 23 24 int main(int argc, char *argv[]) 25 { 26 struct hostent *hp; 27 struct data buffer, *return_buffer; 28 int i, n, rc; 29 FILE *fp; 30 struct stat stat_buffer; 31 char *p; 32 CLIENT *clnt; 33 struct sockaddr_in server_sin; 34 int sock; 35 struct timeval timeout; 36 37 for (i = 1; i < argc; i++) { 38 if (!strcmp(argv[i], "-s")) { 39 if (++i >= argc) { 40 fprintf(stderr, "-s requires a host name\n"); 41 usage_error(argv[0]); 42 } 43 server = argv[i]; 44 continue; 45 } 46 47 if (!strcmp(argv[i], "-f")) { 48 if (++i >= argc) { 49 fprintf(stderr, "-h requires a file name\n"); 50 usage_error(argv[0]); 51 } 52 file_name = argv[i]; 53 continue; 54 } 55 56 if (!strcmp(argv[i], "-p")) { 57 if (++i >= argc) { 58 fprintf(stderr, "-p requires an argument\n"); 59 usage_error(argv[0]); 60 } 61 n = sscanf(argv[i], "%d", &program); 62 if (n != 1) { 63 fprintf(stderr, 64 "-p requires an numeric argument\n"); 65 usage_error(argv[0]); 66 } 67 continue; 68 } 69 70 if (!strcmp(argv[i], "-v")) { 71 if (++i >= argc) { 72 fprintf(stderr, "-v requires an argument\n"); 73 usage_error(argv[0]); 74 } 75 n = sscanf(argv[i], "%d", &version); 76 if (n != 1) { 77 fprintf(stderr, 78 "-v requires an numeric argument\n"); 79 usage_error(argv[0]); 80 } 81 continue; 82 } 83 } 84 85 if (!server) { 86 fprintf(stderr, "server not given\n"); 87 usage_error(argv[0]); 88 } 89 hp = gethostbyname(server); 90 if (hp == NULL) { 91 fprintf(stderr, "server %s unknown\n", server); 92 usage_error(argv[0]); 93 } 94 memset(&server_sin, 0x00, sizeof(server_sin)); 95 server_sin.sin_family = AF_INET; 96 memcpy(&server_sin.sin_addr, hp->h_addr, sizeof(hp->h_addr)); 97 98 if (!file_name) { 99 fprintf(stderr, "file name not given\n"); 100 usage_error(argv[0]); 101 } 102 103 gethostname(host_name, 100); 104 if ((hp = gethostbyname(host_name)) != NULL) 105 host_address = (long)*((int *)hp->h_addr_list[0]); 106 buffer.address = host_address; 107 buffer.request_id = getpid(); 108 109 fp = fopen(file_name, "r"); 110 if (!fp) { 111 fprintf(stderr, "Can not open %s\n", file_name); 112 usage_error(argv[0]); 113 } 114 if (stat(file_name, &stat_buffer)) 115 fprintf(stderr, "stat() failed for %s, errno %d\n", file_name, 116 errno); 117 buffer.data_length = stat_buffer.st_size; 118 if (buffer.data_length > 2187) { 119 fprintf(stderr, "file too large (2187 max)\n"); 120 usage_error(argv[0]); 121 } 122 123 buffer.data = malloc(buffer.data_length); 124 for (i = 0, p = buffer.data; i < buffer.data_length; i++, p++) 125 *p = getc(fp); 126 fclose(fp); 127 128 rc = callrpc(server, program, version, 1, (xdrproc_t)xdr_send_data, 129 (char *)&buffer, (xdrproc_t)xdr_receive_data, 130 (char *)&return_buffer); 131 do_compare(rc, "callrpc", &buffer, return_buffer->data); 132 133 server_sin.sin_port = 0; 134 sock = RPC_ANYSOCK; 135 timeout.tv_usec = 0; 136 timeout.tv_sec = 10; 137 clnt = clntudp_create(&server_sin, program, version, timeout, &sock); 138 if (clnt == NULL) { 139 fprintf(stderr, "clntudp_create failed\n"); 140 exit(1); 141 } 142 timeout.tv_usec = 0; 143 timeout.tv_sec = 30; 144 rc = (int)clnt_call(clnt, 1, (xdrproc_t)xdr_send_data, 145 (char *)&buffer, (xdrproc_t)xdr_receive_data, 146 (char *)&return_buffer, timeout); 147 clnt_destroy(clnt); 148 do_compare(rc, "udp transport", &buffer, return_buffer->data); 149 150 server_sin.sin_port = 0; 151 sock = RPC_ANYSOCK; 152 clnt = clnttcp_create(&server_sin, program, version, &sock, 0, 0); 153 if (clnt == NULL) { 154 fprintf(stderr, "clntudp_create failed\n"); 155 exit(1); 156 } 157 timeout.tv_usec = 0; 158 timeout.tv_sec = 30; 159 rc = (int)clnt_call(clnt, 1, (xdrproc_t)xdr_send_data, 160 (char *)&buffer, (xdrproc_t)xdr_receive_data, 161 (char *)&return_buffer, timeout); 162 clnt_destroy(clnt); 163 do_compare(rc, "tcp transport", &buffer, return_buffer->data); 164 165 exit(0); 166 } 167 168 void do_compare(int rpc_rc, char *msg, struct data *buffer, char *ret_data) 169 { 170 int rc; 171 172 if (rpc_rc) { 173 printf("RPC call with %s returned %d: ", msg, rpc_rc); 174 clnt_perrno(rpc_rc); 175 printf("\n"); 176 exit(1); 177 } 178 rc = memcmp(buffer->data, ret_data, buffer->data_length); 179 if (rc) { 180 printf("Data compare for %s returned %d\n", msg, rc); 181 exit(1); 182 } 183 } 184 185 void usage_error(char *program_name) 186 { 187 fprintf(stderr, 188 "Usage: %s -s server -f file [-p program-number] [-v version]\n", 189 program_name); 190 exit(2); 191 } 192