2 Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2010
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.
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.
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/>.
18 /* Example program using the lowlevel raw interface.
19 * This allow accurate control of the exact commands that are being used.
26 #include "win32_compat.h"
28 #define SERVER "10.1.1.27"
29 #define EXPORT "/shared"
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
42 #include "libnfs-zdr.h"
44 #include "libnfs-raw.h"
45 #include "libnfs-raw-mount.h"
46 #include "libnfs-raw-nfs.h"
47 #include "libnfs-raw-portmap.h"
48 #include "libnfs-raw-rquota.h"
56 struct nfs_fh3 rootfh
;
59 void rquota_getquota_cb(struct rpc_context
*rpc _U_
, int status
, void *data
, void *private_data
)
61 struct client
*client
= private_data
;
62 // GETQUOTA1res *res = data;
64 if (status
== RPC_STATUS_ERROR
) {
65 printf("rquota/getquota call failed with \"%s\"\n", (char *)data
);
68 if (status
!= RPC_STATUS_SUCCESS
) {
69 printf("rquota/getquota call to server %s failed, status:%d\n", client
->server
, status
);
73 printf("rquota responded ok\n");
74 client
->is_finished
= 1;
77 void rquota_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
79 struct client
*client
= private_data
;
81 if (status
!= RPC_STATUS_SUCCESS
) {
82 printf("connection to RPC.RQUOTAD on server %s failed\n", client
->server
);
86 printf("Connected to RPC.RQUOTAD on %s:%d\n", client
->server
, client
->rquota_port
);
87 printf("Send GETQUOTA request for uid 100\n");
88 if (rpc_rquota1_getquota_async(rpc
, rquota_getquota_cb
, EXPORT
, 100, client
) != 0) {
89 printf("Failed to send getquota request\n");
94 void acl_getacl_cb(struct rpc_context
*rpc _U_
, int status
, void *data
, void *private_data
)
96 struct client
*client
= private_data
;
97 GETACL3res
*res
= data
;
99 printf("Got NFSACL/GETACL reply\n");
101 if (status
== RPC_STATUS_SUCCESS
) {
102 printf("Got an ACL : ACL status:%d\n", res
->status
);
103 if (res
->status
== NFS3_OK
) {
105 printf("ACL MASK 0x%08x\n", res
->GETACL3res_u
.resok
.mask
);
106 printf("NUM ACE %d\n", res
->GETACL3res_u
.resok
.ace_count
);
107 for (i
=0; i
<res
->GETACL3res_u
.resok
.ace
.ace_len
; i
++) {
108 printf("Type:0x%08x\n", res
->GETACL3res_u
.resok
.ace
.ace_val
[i
].type
);
109 printf("ID:%d\n", res
->GETACL3res_u
.resok
.ace
.ace_val
[i
].id
);
110 printf("Perm:0x%08x\n", res
->GETACL3res_u
.resok
.ace
.ace_val
[i
].perm
);
115 printf("Disconnect socket from nfs server\n");
116 if (rpc_disconnect(rpc
, "normal disconnect") != 0) {
117 printf("Failed to disconnect socket to nfs\n");
121 printf("Connect to RPC.RQUOTAD on %s:%d\n", client
->server
, client
->rquota_port
);
122 if (rpc_connect_async(rpc
, client
->server
, client
->rquota_port
, rquota_connect_cb
, client
) != 0) {
123 printf("Failed to start connection\n");
128 void acl_null_cb(struct rpc_context
*rpc _U_
, int status
, void *data
, void *private_data
)
130 struct client
*client
= private_data
;
133 printf("Got NFSACL/NULL reply\n");
134 printf("Get ACL for root handle\n");
136 args
.dir
= client
->rootfh
;
137 args
.mask
= NFSACL_MASK_ACL_ENTRY
|NFSACL_MASK_ACL_COUNT
|NFSACL_MASK_ACL_DEFAULT_ENTRY
|NFSACL_MASK_ACL_DEFAULT_COUNT
;
138 if (rpc_nfsacl_getacl_async(rpc
, acl_getacl_cb
, &args
, client
) != 0) {
139 printf("Failed to send getacl request\n");
145 void nfs_fsinfo_cb(struct rpc_context
*rpc _U_
, int status
, void *data
, void *private_data
)
147 struct client
*client
= private_data
;
148 FSINFO3res
*res
= data
;
150 if (status
== RPC_STATUS_ERROR
) {
151 printf("nfs/fsinfo call failed with \"%s\"\n", (char *)data
);
154 if (status
!= RPC_STATUS_SUCCESS
) {
155 printf("nfs/fsinfo call to server %s failed, status:%d\n", client
->server
, status
);
159 printf("Got reply from server for NFS/FSINFO procedure.\n");
160 printf("Read Max:%d\n", (int)res
->FSINFO3res_u
.resok
.rtmax
);
161 printf("Write Max:%d\n", (int)res
->FSINFO3res_u
.resok
.wtmax
);
163 printf("Send NFSACL/NULL request\n");
164 if (rpc_nfsacl_null_async(rpc
, acl_null_cb
, client
) != 0) {
165 printf("Failed to send acl/null request\n");
171 void nfs_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
173 struct client
*client
= private_data
;
174 struct FSINFO3args args
;
176 if (status
!= RPC_STATUS_SUCCESS
) {
177 printf("connection to RPC.MOUNTD on server %s failed\n", client
->server
);
181 printf("Connected to RPC.NFSD on %s:%d\n", client
->server
, client
->mount_port
);
182 printf("Send FSINFO request\n");
183 args
.fsroot
= client
->rootfh
;
184 if (rpc_nfs3_fsinfo_async(rpc
, nfs_fsinfo_cb
, &args
, client
) != 0) {
185 printf("Failed to send fsinfo request\n");
190 void mount_mnt_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
192 struct client
*client
= private_data
;
193 mountres3
*mnt
= data
;
195 if (status
== RPC_STATUS_ERROR
) {
196 printf("mount/mnt call failed with \"%s\"\n", (char *)data
);
199 if (status
!= RPC_STATUS_SUCCESS
) {
200 printf("mount/mnt call to server %s failed, status:%d\n", client
->server
, status
);
204 printf("Got reply from server for MOUNT/MNT procedure.\n");
205 client
->rootfh
.data
.data_len
= mnt
->mountres3_u
.mountinfo
.fhandle
.fhandle3_len
;
206 client
->rootfh
.data
.data_val
= malloc(client
->rootfh
.data
.data_len
);
207 memcpy(client
->rootfh
.data
.data_val
, mnt
->mountres3_u
.mountinfo
.fhandle
.fhandle3_val
, client
->rootfh
.data
.data_len
);
209 printf("Disconnect socket from mountd server\n");
210 if (rpc_disconnect(rpc
, "normal disconnect") != 0) {
211 printf("Failed to disconnect socket to mountd\n");
215 printf("Connect to RPC.NFSD on %s:%d\n", client
->server
, 2049);
216 if (rpc_connect_async(rpc
, client
->server
, 2049, nfs_connect_cb
, client
) != 0) {
217 printf("Failed to start connection\n");
224 void mount_export_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
226 struct client
*client
= private_data
;
227 exports export
= *(exports
*)data
;
229 if (status
== RPC_STATUS_ERROR
) {
230 printf("mount null call failed with \"%s\"\n", (char *)data
);
233 if (status
!= RPC_STATUS_SUCCESS
) {
234 printf("mount null call to server %s failed, status:%d\n", client
->server
, status
);
238 printf("Got reply from server for MOUNT/EXPORT procedure.\n");
239 while (export
!= NULL
) {
240 printf("Export: %s\n", export
->ex_dir
);
241 export
= export
->ex_next
;
243 printf("Send MOUNT/MNT command for %s\n", client
->export
);
244 if (rpc_mount_mnt_async(rpc
, mount_mnt_cb
, client
->export
, client
) != 0) {
245 printf("Failed to send mnt request\n");
250 void mount_null_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
252 struct client
*client
= private_data
;
254 if (status
== RPC_STATUS_ERROR
) {
255 printf("mount null call failed with \"%s\"\n", (char *)data
);
258 if (status
!= RPC_STATUS_SUCCESS
) {
259 printf("mount null call to server %s failed, status:%d\n", client
->server
, status
);
263 printf("Got reply from server for MOUNT/NULL procedure.\n");
264 printf("Send MOUNT/EXPORT command\n");
265 if (rpc_mount_export_async(rpc
, mount_export_cb
, client
) != 0) {
266 printf("Failed to send export request\n");
271 void mount_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
273 struct client
*client
= private_data
;
275 if (status
!= RPC_STATUS_SUCCESS
) {
276 printf("connection to RPC.MOUNTD on server %s failed\n", client
->server
);
280 printf("Connected to RPC.MOUNTD on %s:%d\n", client
->server
, client
->mount_port
);
281 printf("Send NULL request to check if RPC.MOUNTD is actually running\n");
282 if (rpc_mount_null_async(rpc
, mount_null_cb
, client
) != 0) {
283 printf("Failed to send null request\n");
289 void pmap_getport2_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
291 struct client
*client
= private_data
;
293 if (status
== RPC_STATUS_ERROR
) {
294 printf("portmapper getport call failed with \"%s\"\n", (char *)data
);
297 if (status
!= RPC_STATUS_SUCCESS
) {
298 printf("portmapper getport call to server %s failed, status:%d\n", client
->server
, status
);
302 client
->mount_port
= *(uint32_t *)data
;
303 printf("GETPORT returned RPC.MOUNTD is on port:%d\n", client
->mount_port
);
304 if (client
->mount_port
== 0) {
305 printf("RPC.MOUNTD is not available on server : %s:%d\n", client
->server
, client
->mount_port
);
309 printf("Disconnect socket from portmap server\n");
310 if (rpc_disconnect(rpc
, "normal disconnect") != 0) {
311 printf("Failed to disconnect socket to portmapper\n");
315 printf("Connect to RPC.MOUNTD on %s:%d\n", client
->server
, client
->mount_port
);
316 if (rpc_connect_async(rpc
, client
->server
, client
->mount_port
, mount_connect_cb
, client
) != 0) {
317 printf("Failed to start connection\n");
322 void pmap_getport1_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
324 struct client
*client
= private_data
;
326 if (status
== RPC_STATUS_ERROR
) {
327 printf("portmapper getport call failed with \"%s\"\n", (char *)data
);
330 if (status
!= RPC_STATUS_SUCCESS
) {
331 printf("portmapper getport call to server %s failed, status:%d\n", client
->server
, status
);
335 client
->rquota_port
= *(uint32_t *)data
;
336 printf("GETPORT returned RPC.RQUOTAD on port:%d\n", client
->rquota_port
);
337 if (client
->rquota_port
== 0) {
338 printf("RPC.RQUOTAD is not available on server : %s:%d\n", client
->server
, client
->rquota_port
);
342 printf("Send getport request asking for MOUNT port\n");
343 if (rpc_pmap2_getport_async(rpc
, MOUNT_PROGRAM
, MOUNT_V3
, IPPROTO_TCP
, pmap_getport2_cb
, client
) != 0) {
344 printf("Failed to send getport request\n");
349 void pmap_dump_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
351 struct client
*client
= private_data
;
352 struct pmap2_dump_result
*dr
= data
;
353 struct pmap2_mapping_list
*list
= dr
->list
;
355 if (status
== RPC_STATUS_ERROR
) {
356 printf("portmapper null call failed with \"%s\"\n", (char *)data
);
359 if (status
!= RPC_STATUS_SUCCESS
) {
360 printf("portmapper null call to server %s failed, status:%d\n", client
->server
, status
);
364 printf("Got reply from server for PORTMAP/DUMP procedure.\n");
366 printf("Prog:%d Vers:%d Protocol:%d Port:%d\n",
374 printf("Send getport request asking for MOUNT port\n");
375 if (rpc_pmap2_getport_async(rpc
, RQUOTA_PROGRAM
, RQUOTA_V1
, IPPROTO_TCP
, pmap_getport1_cb
, client
) != 0) {
376 printf("Failed to send getport request\n");
381 void pmap_null_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
383 struct client
*client
= private_data
;
385 if (status
== RPC_STATUS_ERROR
) {
386 printf("portmapper null call failed with \"%s\"\n", (char *)data
);
389 if (status
!= RPC_STATUS_SUCCESS
) {
390 printf("portmapper null call to server %s failed, status:%d\n", client
->server
, status
);
394 printf("Got reply from server for PORTMAP/NULL procedure.\n");
395 printf("Send PMAP/DUMP command\n");
396 if (rpc_pmap2_dump_async(rpc
, pmap_dump_cb
, client
) != 0) {
397 printf("Failed to send getport request\n");
402 void pmap_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
404 struct client
*client
= private_data
;
406 printf("pmap_connect_cb status:%d.\n", status
);
407 if (status
!= RPC_STATUS_SUCCESS
) {
408 printf("connection to portmapper on server %s failed\n", client
->server
);
412 printf("Send NULL request to check if portmapper is actually running\n");
413 if (rpc_pmap2_null_async(rpc
, pmap_null_cb
, client
) != 0) {
414 printf("Failed to send null request\n");
420 int main(int argc _U_
, char *argv
[] _U_
)
422 struct rpc_context
*rpc
;
424 struct client client
;
426 rpc
= rpc_init_context();
428 printf("failed to init context\n");
432 client
.server
= SERVER
;
433 client
.export
= EXPORT
;
434 client
.is_finished
= 0;
435 if (rpc_connect_async(rpc
, client
.server
, 111, pmap_connect_cb
, &client
) != 0) {
436 printf("Failed to start connection\n");
441 pfd
.fd
= rpc_get_fd(rpc
);
442 pfd
.events
= rpc_which_events(rpc
);
444 if (poll(&pfd
, 1, -1) < 0) {
445 printf("Poll failed");
448 if (rpc_service(rpc
, pfd
.revents
) < 0) {
449 printf("rpc_service failed\n");
452 if (client
.is_finished
) {
457 rpc_destroy_context(rpc
);
459 printf("nfsclient finished\n");