WIN32: More ifdef cleanups
[deb_libnfs.git] / examples / nfsclient-raw.c
CommitLineData
84004dbf
RS
1/*
2 Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2010
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
a8a1b858
M
22#ifdef WIN32
23#include "win32_compat.h"
24#else
25#include <poll.h>
26#endif
84004dbf 27#define SERVER "10.1.1.27"
f4b9cb0e 28#define EXPORT "/shared"
84004dbf
RS
29
30#include <stdio.h>
31#include <stdlib.h>
a62cb4b7 32#include <string.h>
763cd6e3
RS
33#include <netinet/in.h>
34#include "libnfs-zdr.h"
84004dbf
RS
35#include "libnfs.h"
36#include "libnfs-raw.h"
37#include "libnfs-raw-mount.h"
f4b9cb0e 38#include "libnfs-raw-nfs.h"
05a777d9 39#include "libnfs-raw-rquota.h"
84004dbf
RS
40
41struct client {
42 char *server;
43 char *export;
44 uint32_t mount_port;
05a777d9 45 uint32_t rquota_port;
84004dbf 46 int is_finished;
f4b9cb0e 47 struct nfs_fh3 rootfh;
84004dbf
RS
48};
49
05a777d9
RS
50void rquota_getquota_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data)
51{
52 struct client *client = private_data;
440a7dfc 53// GETQUOTA1res *res = data;
05a777d9
RS
54
55 if (status == RPC_STATUS_ERROR) {
56 printf("rquota/getquota call failed with \"%s\"\n", (char *)data);
57 exit(10);
58 }
59 if (status != RPC_STATUS_SUCCESS) {
60 printf("rquota/getquota call to server %s failed, status:%d\n", client->server, status);
61 exit(10);
62 }
63
64 printf("rquota responded ok\n");
65 client->is_finished = 1;
66}
67
68void rquota_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data)
69{
70 struct client *client = private_data;
71
72 if (status != RPC_STATUS_SUCCESS) {
73 printf("connection to RPC.RQUOTAD on server %s failed\n", client->server);
74 exit(10);
75 }
76
77 printf("Connected to RPC.RQUOTAD on %s:%d\n", client->server, client->rquota_port);
78 printf("Send GETQUOTA request for uid 100\n");
79 if (rpc_rquota1_getquota_async(rpc, rquota_getquota_cb, EXPORT, 100, client) != 0) {
80 printf("Failed to send fsinfo request\n");
81 exit(10);
82 }
83}
84
3847f8f6
RS
85void acl_getacl_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data)
86{
87 struct client *client = private_data;
88 GETACL3res *res = data;
89
90 printf("Got NFSACL/GETACL reply\n");
91
92 if (status == RPC_STATUS_SUCCESS) {
93 printf("Got an ACL : ACL status:%d\n", res->status);
94 if (res->status == NFS3_OK) {
95 int i;
96 printf("ACL MASK 0x%08x\n", res->GETACL3res_u.resok.mask);
97 printf("NUM ACE %d\n", res->GETACL3res_u.resok.ace_count);
98 for (i=0; i<res->GETACL3res_u.resok.ace.ace_len; i++) {
99 printf("Type:0x%08x\n", res->GETACL3res_u.resok.ace.ace_val[i].type);
100 printf("ID:%d\n", res->GETACL3res_u.resok.ace.ace_val[i].id);
101 printf("Perm:0x%08x\n", res->GETACL3res_u.resok.ace.ace_val[i].perm);
102 }
103 }
104 }
105
106 printf("Disconnect socket from nfs server\n");
107 if (rpc_disconnect(rpc, "normal disconnect") != 0) {
108 printf("Failed to disconnect socket to nfs\n");
109 exit(10);
110 }
111
112 printf("Connect to RPC.RQUOTAD on %s:%d\n", client->server, client->rquota_port);
113 if (rpc_connect_async(rpc, client->server, client->rquota_port, rquota_connect_cb, client) != 0) {
114 printf("Failed to start connection\n");
115 exit(10);
116 }
117}
118
119void acl_null_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data)
120{
121 struct client *client = private_data;
0118a5f0 122 GETACL3args args;
3847f8f6
RS
123
124 printf("Got NFSACL/NULL reply\n");
125 printf("Get ACL for root handle\n");
126
0118a5f0
RS
127 args.dir = client->rootfh;
128 args.mask = NFSACL_MASK_ACL_ENTRY|NFSACL_MASK_ACL_COUNT|NFSACL_MASK_ACL_DEFAULT_ENTRY|NFSACL_MASK_ACL_DEFAULT_COUNT;
129 if (rpc_nfsacl_getacl_async(rpc, acl_getacl_cb, &args, client) != 0) {
3847f8f6
RS
130 printf("Failed to send getacl request\n");
131 exit(10);
132 }
133
134}
135
7d0397cf 136void nfs_fsinfo_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data)
f4b9cb0e
RS
137{
138 struct client *client = private_data;
139 FSINFO3res *res = data;
140
141 if (status == RPC_STATUS_ERROR) {
142 printf("nfs/fsinfo call failed with \"%s\"\n", (char *)data);
143 exit(10);
144 }
145 if (status != RPC_STATUS_SUCCESS) {
146 printf("nfs/fsinfo call to server %s failed, status:%d\n", client->server, status);
147 exit(10);
148 }
149
150 printf("Got reply from server for NFS/FSINFO procedure.\n");
151 printf("Read Max:%d\n", (int)res->FSINFO3res_u.resok.rtmax);
152 printf("Write Max:%d\n", (int)res->FSINFO3res_u.resok.wtmax);
05a777d9 153
3847f8f6
RS
154 printf("Send NFSACL/NULL request\n");
155 if (rpc_nfsacl_null_async(rpc, acl_null_cb, client) != 0) {
156 printf("Failed to send acl/null request\n");
05a777d9
RS
157 exit(10);
158 }
f4b9cb0e
RS
159}
160
161
7d0397cf 162void nfs_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data)
f4b9cb0e
RS
163{
164 struct client *client = private_data;
165
166 if (status != RPC_STATUS_SUCCESS) {
167 printf("connection to RPC.MOUNTD on server %s failed\n", client->server);
168 exit(10);
169 }
170
05a777d9 171 printf("Connected to RPC.NFSD on %s:%d\n", client->server, client->mount_port);
f4b9cb0e
RS
172 printf("Send FSINFO request\n");
173 if (rpc_nfs_fsinfo_async(rpc, nfs_fsinfo_cb, &client->rootfh, client) != 0) {
174 printf("Failed to send fsinfo request\n");
175 exit(10);
176 }
177}
178
84004dbf
RS
179void mount_mnt_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
180{
181 struct client *client = private_data;
f4b9cb0e 182 mountres3 *mnt = data;
84004dbf
RS
183
184 if (status == RPC_STATUS_ERROR) {
185 printf("mount/mnt call failed with \"%s\"\n", (char *)data);
186 exit(10);
187 }
188 if (status != RPC_STATUS_SUCCESS) {
189 printf("mount/mnt call to server %s failed, status:%d\n", client->server, status);
190 exit(10);
191 }
192
193 printf("Got reply from server for MOUNT/MNT procedure.\n");
f4b9cb0e
RS
194 client->rootfh.data.data_len = mnt->mountres3_u.mountinfo.fhandle.fhandle3_len;
195 client->rootfh.data.data_val = malloc(client->rootfh.data.data_len);
196 memcpy(client->rootfh.data.data_val, mnt->mountres3_u.mountinfo.fhandle.fhandle3_val, client->rootfh.data.data_len);
197
198 printf("Disconnect socket from mountd server\n");
199 if (rpc_disconnect(rpc, "normal disconnect") != 0) {
200 printf("Failed to disconnect socket to mountd\n");
201 exit(10);
202 }
203
05a777d9 204 printf("Connect to RPC.NFSD on %s:%d\n", client->server, 2049);
f4b9cb0e
RS
205 if (rpc_connect_async(rpc, client->server, 2049, nfs_connect_cb, client) != 0) {
206 printf("Failed to start connection\n");
207 exit(10);
208 }
84004dbf
RS
209}
210
211
440a7dfc
RS
212
213void mount_export_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
84004dbf
RS
214{
215 struct client *client = private_data;
440a7dfc 216 exports export = *(exports *)data;
84004dbf
RS
217
218 if (status == RPC_STATUS_ERROR) {
219 printf("mount null call failed with \"%s\"\n", (char *)data);
220 exit(10);
221 }
222 if (status != RPC_STATUS_SUCCESS) {
223 printf("mount null call to server %s failed, status:%d\n", client->server, status);
224 exit(10);
225 }
226
440a7dfc
RS
227 printf("Got reply from server for MOUNT/EXPORT procedure.\n");
228 while (export != NULL) {
229 printf("Export: %s\n", export->ex_dir);
230 export = export->ex_next;
231 }
84004dbf
RS
232 printf("Send MOUNT/MNT command for %s\n", client->export);
233 if (rpc_mount_mnt_async(rpc, mount_mnt_cb, client->export, client) != 0) {
234 printf("Failed to send mnt request\n");
235 exit(10);
236 }
84004dbf
RS
237}
238
440a7dfc
RS
239void mount_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
240{
241 struct client *client = private_data;
242
243 if (status == RPC_STATUS_ERROR) {
244 printf("mount null call failed with \"%s\"\n", (char *)data);
245 exit(10);
246 }
247 if (status != RPC_STATUS_SUCCESS) {
248 printf("mount null call to server %s failed, status:%d\n", client->server, status);
249 exit(10);
250 }
251
252 printf("Got reply from server for MOUNT/NULL procedure.\n");
253 printf("Send MOUNT/EXPORT command\n");
254 if (rpc_mount_export_async(rpc, mount_export_cb, client) != 0) {
255 printf("Failed to send export request\n");
256 exit(10);
257 }
258}
259
7d0397cf 260void mount_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data)
84004dbf
RS
261{
262 struct client *client = private_data;
263
264 if (status != RPC_STATUS_SUCCESS) {
265 printf("connection to RPC.MOUNTD on server %s failed\n", client->server);
266 exit(10);
267 }
268
269 printf("Connected to RPC.MOUNTD on %s:%d\n", client->server, client->mount_port);
270 printf("Send NULL request to check if RPC.MOUNTD is actually running\n");
271 if (rpc_mount_null_async(rpc, mount_null_cb, client) != 0) {
272 printf("Failed to send null request\n");
273 exit(10);
274 }
275}
276
277
05a777d9 278void pmap_getport2_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
84004dbf
RS
279{
280 struct client *client = private_data;
84004dbf
RS
281
282 if (status == RPC_STATUS_ERROR) {
283 printf("portmapper getport call failed with \"%s\"\n", (char *)data);
284 exit(10);
285 }
286 if (status != RPC_STATUS_SUCCESS) {
287 printf("portmapper getport call to server %s failed, status:%d\n", client->server, status);
288 exit(10);
289 }
290
291 client->mount_port = *(uint32_t *)data;
05a777d9 292 printf("GETPORT returned RPC.MOUNTD is on port:%d\n", client->mount_port);
84004dbf 293 if (client->mount_port == 0) {
7d0397cf 294 printf("RPC.MOUNTD is not available on server : %s:%d\n", client->server, client->mount_port);
84004dbf
RS
295 exit(10);
296 }
297
298 printf("Disconnect socket from portmap server\n");
299 if (rpc_disconnect(rpc, "normal disconnect") != 0) {
300 printf("Failed to disconnect socket to portmapper\n");
301 exit(10);
302 }
303
304 printf("Connect to RPC.MOUNTD on %s:%d\n", client->server, client->mount_port);
305 if (rpc_connect_async(rpc, client->server, client->mount_port, mount_connect_cb, client) != 0) {
306 printf("Failed to start connection\n");
307 exit(10);
308 }
309}
310
05a777d9
RS
311void pmap_getport1_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
312{
313 struct client *client = private_data;
314
315 if (status == RPC_STATUS_ERROR) {
316 printf("portmapper getport call failed with \"%s\"\n", (char *)data);
317 exit(10);
318 }
319 if (status != RPC_STATUS_SUCCESS) {
320 printf("portmapper getport call to server %s failed, status:%d\n", client->server, status);
321 exit(10);
322 }
323
324 client->rquota_port = *(uint32_t *)data;
325 printf("GETPORT returned RPC.RQUOTAD on port:%d\n", client->rquota_port);
326 if (client->rquota_port == 0) {
327 printf("RPC.RQUOTAD is not available on server : %s:%d\n", client->server, client->rquota_port);
440a7dfc 328// exit(10);
05a777d9
RS
329 }
330
331 printf("Send getport request asking for MOUNT port\n");
5c6b1176 332 if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, IPPROTO_TCP, pmap_getport2_cb, client) != 0) {
05a777d9
RS
333 printf("Failed to send getport request\n");
334 exit(10);
335 }
336}
84004dbf
RS
337
338void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
339{
340 struct client *client = private_data;
341
342 if (status == RPC_STATUS_ERROR) {
343 printf("portmapper null call failed with \"%s\"\n", (char *)data);
344 exit(10);
345 }
346 if (status != RPC_STATUS_SUCCESS) {
347 printf("portmapper null call to server %s failed, status:%d\n", client->server, status);
348 exit(10);
349 }
350
351 printf("Got reply from server for PORTMAP/NULL procedure.\n");
352 printf("Send getport request asking for MOUNT port\n");
5c6b1176 353 if (rpc_pmap_getport_async(rpc, RQUOTA_PROGRAM, RQUOTA_V1, IPPROTO_TCP, pmap_getport1_cb, client) != 0) {
84004dbf
RS
354 printf("Failed to send getport request\n");
355 exit(10);
356 }
357}
358
7d0397cf 359void pmap_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data)
84004dbf
RS
360{
361 struct client *client = private_data;
362
363 printf("pmap_connect_cb status:%d.\n", status);
364 if (status != RPC_STATUS_SUCCESS) {
365 printf("connection to portmapper on server %s failed\n", client->server);
366 exit(10);
367 }
368
369 printf("Send NULL request to check if portmapper is actually running\n");
370 if (rpc_pmap_null_async(rpc, pmap_null_cb, client) != 0) {
371 printf("Failed to send null request\n");
372 exit(10);
373 }
374}
375
376
7d0397cf 377int main(int argc _U_, char *argv[] _U_)
84004dbf
RS
378{
379 struct rpc_context *rpc;
380 struct pollfd pfd;
84004dbf
RS
381 struct client client;
382
383 rpc = rpc_init_context();
384 if (rpc == NULL) {
385 printf("failed to init context\n");
386 exit(10);
387 }
388
389 client.server = SERVER;
390 client.export = EXPORT;
391 client.is_finished = 0;
392 if (rpc_connect_async(rpc, client.server, 111, pmap_connect_cb, &client) != 0) {
393 printf("Failed to start connection\n");
394 exit(10);
395 }
396
397 for (;;) {
398 pfd.fd = rpc_get_fd(rpc);
399 pfd.events = rpc_which_events(rpc);
400
401 if (poll(&pfd, 1, -1) < 0) {
402 printf("Poll failed");
403 exit(10);
404 }
405 if (rpc_service(rpc, pfd.revents) < 0) {
406 printf("rpc_service failed\n");
407 break;
408 }
409 if (client.is_finished) {
410 break;
411 }
412 }
413
414 rpc_destroy_context(rpc);
415 rpc=NULL;
416 printf("nfsclient finished\n");
417 return 0;
418}