PORTMAP: Add v3 GETTIME support
[deb_libnfs.git] / examples / portmap-client.c
1 /*
2 Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2014
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /* Example program using the lowlevel raw interface.
19 * This allow accurate control of the exact commands that are being used.
20 */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #ifdef WIN32
26 #include "win32_compat.h"
27 #endif
28
29 #ifdef HAVE_POLL_H
30 #include <poll.h>
31 #endif
32
33 #ifdef HAVE_NETINET_IN_H
34 #include <netinet/in.h>
35 #endif
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <time.h>
41 #include "libnfs-zdr.h"
42 #include "libnfs.h"
43 #include "libnfs-raw.h"
44 #include "libnfs-raw-mount.h"
45 #include "libnfs-raw-nfs.h"
46 #include "libnfs-raw-portmap.h"
47 #include "libnfs-raw-rquota.h"
48
49 struct client {
50 int is_finished;
51 };
52
53 void pmap2_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
54 {
55 struct client *client = private_data;
56 struct pmap2_dump_result *dr = data;
57 struct pmap2_mapping_list *list = dr->list;
58
59 if (status == RPC_STATUS_ERROR) {
60 printf("PORTMAP2/DUMP call failed with \"%s\"\n", (char *)data);
61 exit(10);
62 }
63 if (status != RPC_STATUS_SUCCESS) {
64 printf("PORTMAP2/DUMP call failed, status:%d\n", status);
65 exit(10);
66 }
67
68 printf("PORTMAP2/DUMP:\n");
69 while (list) {
70 printf(" Prog:%d Vers:%d Protocol:%d Port:%d\n",
71 list->map.prog,
72 list->map.vers,
73 list->map.prot,
74 list->map.port);
75 list = list->next;
76 }
77 client->is_finished = 1;
78 }
79
80 void pmap3_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
81 {
82 struct client *client = private_data;
83 struct pmap3_dump_result *dr = data;
84 struct pmap3_mapping_list *list = dr->list;
85
86 if (status == RPC_STATUS_ERROR) {
87 printf("PORTMAP3/DUMP call failed with \"%s\"\n", (char *)data);
88 exit(10);
89 }
90 if (status != RPC_STATUS_SUCCESS) {
91 printf("PORTMAP3/DUMP call failed, status:%d\n", status);
92 exit(10);
93 }
94
95 printf("PORTMAP3/DUMP:\n");
96 while (list) {
97 printf(" Prog:%d Vers:%d Netid:%s Addr:%s Owner:%s\n",
98 list->map.prog,
99 list->map.vers,
100 list->map.netid,
101 list->map.addr,
102 list->map.owner);
103 list = list->next;
104 }
105 client->is_finished = 1;
106 }
107
108 void pmap3_getaddr_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
109 {
110 struct client *client = private_data;
111 struct pmap3_getaddr_result *gar = data;
112
113 if (status == RPC_STATUS_ERROR) {
114 printf("PORTMAP3/GETADDR call failed with \"%s\"\n", (char *)data);
115 exit(10);
116 }
117 if (status != RPC_STATUS_SUCCESS) {
118 printf("PORTMAP3/GETADDR call failed, status:%d\n", status);
119 exit(10);
120 }
121
122 printf("PORTMAP3/GETADDR:\n");
123 printf(" Addr:%s\n", gar->addr);
124
125 client->is_finished = 1;
126 }
127
128 void pmap3_gettime_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
129 {
130 struct client *client = private_data;
131 time_t t = *(uint32_t *)data;
132
133 if (status == RPC_STATUS_ERROR) {
134 printf("PORTMAP3/GETTIME call failed with \"%s\"\n", (char *)data);
135 exit(10);
136 }
137 if (status != RPC_STATUS_SUCCESS) {
138 printf("PORTMAP3/GETTIME call failed, status:%d\n", status);
139 exit(10);
140 }
141
142 printf("PORTMAP3/GETTIME:\n");
143 printf(" Time:%d %s\n", (int)t, ctime(&t));
144
145 client->is_finished = 1;
146 }
147
148 void pmap2_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
149 {
150 struct client *client = private_data;
151
152 if (status == RPC_STATUS_ERROR) {
153 printf("PORTMAP2/NULL call failed with \"%s\"\n", (char *)data);
154 exit(10);
155 }
156 if (status != RPC_STATUS_SUCCESS) {
157 printf("PORTMAP2/NULL call failed, status:%d\n", status);
158 exit(10);
159 }
160
161 printf("PORTMAP2/NULL responded and server is alive\n");
162 client->is_finished = 1;
163 }
164
165 void pmap3_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
166 {
167 struct client *client = private_data;
168
169 if (status == RPC_STATUS_ERROR) {
170 printf("PORTMAP3/NULL call failed with \"%s\"\n", (char *)data);
171 exit(10);
172 }
173 if (status != RPC_STATUS_SUCCESS) {
174 printf("PORTMAP3/NULL call failed, status:%d\n", status);
175 exit(10);
176 }
177
178 printf("PORTMAP3/NULL responded and server is alive\n");
179 client->is_finished = 1;
180 }
181
182 void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
183 {
184 struct client *client = private_data;
185
186 if (status == RPC_STATUS_ERROR) {
187 printf("PORTMAP/NULL call failed with \"%s\"\n", (char *)data);
188 exit(10);
189 }
190 if (status != RPC_STATUS_SUCCESS) {
191 printf("PORTMAP/NULL call failed, status:%d\n", status);
192 exit(10);
193 }
194
195 client->is_finished = 1;
196 }
197
198 void pmap_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data)
199 {
200 struct client *client = private_data;
201
202 if (status != RPC_STATUS_SUCCESS) {
203 printf("connection to portmapper failed\n");
204 exit(10);
205 }
206
207 if (rpc_pmap2_null_async(rpc, pmap_null_cb, client) != 0) {
208 printf("Failed to send null request\n");
209 exit(10);
210 }
211 }
212
213
214 static void wait_until_finished(struct rpc_context *rpc, struct client *client)
215 {
216 struct pollfd pfd;
217
218 client->is_finished = 0;
219 for (;;) {
220 pfd.fd = rpc_get_fd(rpc);
221 pfd.events = rpc_which_events(rpc);
222
223 if (poll(&pfd, 1, -1) < 0) {
224 printf("Poll failed");
225 exit(10);
226 }
227 if (rpc_service(rpc, pfd.revents) < 0) {
228 printf("rpc_service failed\n");
229 break;
230 }
231 if (client->is_finished) {
232 break;
233 }
234 }
235 }
236
237 int main(int argc _U_, char *argv[] _U_)
238 {
239 struct rpc_context *rpc;
240 struct client client;
241 char *server = NULL;
242 int i;
243 int null2 = 0;
244 int dump2 = 0;
245 int null3 = 0;
246 int getaddr3 = 0;
247 int dump3 = 0;
248 int gettime3 = 0;
249 int command_found = 0;
250
251 int getaddr3prog, getaddr3vers;
252 char *getaddr3netid;
253
254 rpc = rpc_init_context();
255 if (rpc == NULL) {
256 printf("failed to init context\n");
257 exit(10);
258 }
259
260 for (i = 1; i < argc; i++) {
261 if (!strcmp(argv[i], "dump2")) {
262 dump2 = 1;
263 command_found++;
264 } else if (!strcmp(argv[i], "null2")) {
265 null2 = 1;
266 command_found++;
267 } else if (!strcmp(argv[i], "dump3")) {
268 dump3 = 1;
269 command_found++;
270 } else if (!strcmp(argv[i], "gettime3")) {
271 gettime3 = 1;
272 command_found++;
273 } else if (!strcmp(argv[i], "getaddr3")) {
274 getaddr3 = 1;
275 getaddr3prog = atoi(argv[++i]);
276 getaddr3vers = atoi(argv[++i]);
277 getaddr3netid = argv[++i];
278 command_found++;
279 } else if (!strcmp(argv[i], "null3")) {
280 null3 = 1;
281 command_found++;
282 } else {
283 server = argv[i];
284 }
285 }
286 if (command_found == 0 || server == NULL) {
287 fprintf(stderr, "Usage: portmap-client <command*> <server>\n");
288 exit(10);
289 }
290
291 if (rpc_connect_async(rpc, server, 111, pmap_connect_cb, &client) != 0) {
292 printf("Failed to start connection\n");
293 exit(10);
294 }
295 wait_until_finished(rpc, &client);
296
297 if (null2) {
298 if (rpc_pmap2_null_async(rpc, pmap2_null_cb, &client) != 0) {
299 printf("Failed to send NULL2 request\n");
300 exit(10);
301 }
302 wait_until_finished(rpc, &client);
303 }
304 if (dump2) {
305 if (rpc_pmap2_dump_async(rpc, pmap2_dump_cb, &client) != 0) {
306 printf("Failed to send DUMP2 request\n");
307 exit(10);
308 }
309 wait_until_finished(rpc, &client);
310 }
311 if (null3) {
312 if (rpc_pmap3_null_async(rpc, pmap3_null_cb, &client) != 0) {
313 printf("Failed to send NULL3 request\n");
314 exit(10);
315 }
316 wait_until_finished(rpc, &client);
317 }
318 if (dump3) {
319 if (rpc_pmap3_dump_async(rpc, pmap3_dump_cb, &client) != 0) {
320 printf("Failed to send DUMP3 request\n");
321 exit(10);
322 }
323 wait_until_finished(rpc, &client);
324 }
325 if (gettime3) {
326 if (rpc_pmap3_gettime_async(rpc, pmap3_gettime_cb, &client) != 0) {
327 printf("Failed to send GETTIME3 request\n");
328 exit(10);
329 }
330 wait_until_finished(rpc, &client);
331 }
332 if (getaddr3) {
333 struct pmap3_mapping map;
334
335 map.prog=getaddr3prog;
336 map.vers=getaddr3vers;
337 map.netid=getaddr3netid;
338 map.addr="";
339 map.owner="";
340 if (rpc_pmap3_getaddr_async(rpc, &map, pmap3_getaddr_cb, &client) != 0) {
341 printf("Failed to send GETADDR3 request\n");
342 exit(10);
343 }
344 wait_until_finished(rpc, &client);
345 }
346
347
348 rpc_destroy_context(rpc);
349 rpc=NULL;
350 return 0;
351 }