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