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