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 
main(int argc,char * argv[])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 
do_compare(int rpc_rc,char * msg,struct data * buffer,char * ret_data)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 
usage_error(char * program_name)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