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.
22 #define SERVER "10.1.1.27"
23 #define EXPORT "/shared"
29 #include "libnfs-raw.h"
30 #include "libnfs-raw-mount.h"
31 #include "libnfs-raw-nfs.h"
32 #include "libnfs-raw-rquota.h"
40 struct nfs_fh3 rootfh
;
43 void rquota_getquota_cb(struct rpc_context
*rpc _U_
, int status
, void *data
, void *private_data
)
45 struct client
*client
= private_data
;
46 GETQUOTA1res
*res
= data
;
48 if (status
== RPC_STATUS_ERROR
) {
49 printf("rquota/getquota call failed with \"%s\"\n", (char *)data
);
52 if (status
!= RPC_STATUS_SUCCESS
) {
53 printf("rquota/getquota call to server %s failed, status:%d\n", client
->server
, status
);
57 printf("rquota responded ok\n");
58 client
->is_finished
= 1;
61 void rquota_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
63 struct client
*client
= private_data
;
65 if (status
!= RPC_STATUS_SUCCESS
) {
66 printf("connection to RPC.RQUOTAD on server %s failed\n", client
->server
);
70 printf("Connected to RPC.RQUOTAD on %s:%d\n", client
->server
, client
->rquota_port
);
71 printf("Send GETQUOTA request for uid 100\n");
72 if (rpc_rquota1_getquota_async(rpc
, rquota_getquota_cb
, EXPORT
, 100, client
) != 0) {
73 printf("Failed to send fsinfo request\n");
78 void nfs_fsinfo_cb(struct rpc_context
*rpc _U_
, int status
, void *data
, void *private_data
)
80 struct client
*client
= private_data
;
81 FSINFO3res
*res
= data
;
83 if (status
== RPC_STATUS_ERROR
) {
84 printf("nfs/fsinfo call failed with \"%s\"\n", (char *)data
);
87 if (status
!= RPC_STATUS_SUCCESS
) {
88 printf("nfs/fsinfo call to server %s failed, status:%d\n", client
->server
, status
);
92 printf("Got reply from server for NFS/FSINFO procedure.\n");
93 printf("Read Max:%d\n", (int)res
->FSINFO3res_u
.resok
.rtmax
);
94 printf("Write Max:%d\n", (int)res
->FSINFO3res_u
.resok
.wtmax
);
96 printf("Disconnect socket from nfs server\n");
97 if (rpc_disconnect(rpc
, "normal disconnect") != 0) {
98 printf("Failed to disconnect socket to nfs\n");
102 printf("Connect to RPC.RQUOTAD on %s:%d\n", client
->server
, client
->rquota_port
);
103 if (rpc_connect_async(rpc
, client
->server
, client
->rquota_port
, rquota_connect_cb
, client
) != 0) {
104 printf("Failed to start connection\n");
110 void nfs_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
112 struct client
*client
= private_data
;
114 if (status
!= RPC_STATUS_SUCCESS
) {
115 printf("connection to RPC.MOUNTD on server %s failed\n", client
->server
);
119 printf("Connected to RPC.NFSD on %s:%d\n", client
->server
, client
->mount_port
);
120 printf("Send FSINFO request\n");
121 if (rpc_nfs_fsinfo_async(rpc
, nfs_fsinfo_cb
, &client
->rootfh
, client
) != 0) {
122 printf("Failed to send fsinfo request\n");
127 void mount_mnt_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
129 struct client
*client
= private_data
;
130 mountres3
*mnt
= data
;
132 if (status
== RPC_STATUS_ERROR
) {
133 printf("mount/mnt call failed with \"%s\"\n", (char *)data
);
136 if (status
!= RPC_STATUS_SUCCESS
) {
137 printf("mount/mnt call to server %s failed, status:%d\n", client
->server
, status
);
141 printf("Got reply from server for MOUNT/MNT procedure.\n");
142 client
->rootfh
.data
.data_len
= mnt
->mountres3_u
.mountinfo
.fhandle
.fhandle3_len
;
143 client
->rootfh
.data
.data_val
= malloc(client
->rootfh
.data
.data_len
);
144 memcpy(client
->rootfh
.data
.data_val
, mnt
->mountres3_u
.mountinfo
.fhandle
.fhandle3_val
, client
->rootfh
.data
.data_len
);
146 printf("Disconnect socket from mountd server\n");
147 if (rpc_disconnect(rpc
, "normal disconnect") != 0) {
148 printf("Failed to disconnect socket to mountd\n");
152 printf("Connect to RPC.NFSD on %s:%d\n", client
->server
, 2049);
153 if (rpc_connect_async(rpc
, client
->server
, 2049, nfs_connect_cb
, client
) != 0) {
154 printf("Failed to start connection\n");
160 void mount_null_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
162 struct client
*client
= private_data
;
164 if (status
== RPC_STATUS_ERROR
) {
165 printf("mount null call failed with \"%s\"\n", (char *)data
);
168 if (status
!= RPC_STATUS_SUCCESS
) {
169 printf("mount null call to server %s failed, status:%d\n", client
->server
, status
);
173 printf("Got reply from server for MOUNT/NULL procedure.\n");
174 printf("Send MOUNT/MNT command for %s\n", client
->export
);
175 if (rpc_mount_mnt_async(rpc
, mount_mnt_cb
, client
->export
, client
) != 0) {
176 printf("Failed to send mnt request\n");
181 void mount_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
183 struct client
*client
= private_data
;
185 if (status
!= RPC_STATUS_SUCCESS
) {
186 printf("connection to RPC.MOUNTD on server %s failed\n", client
->server
);
190 printf("Connected to RPC.MOUNTD on %s:%d\n", client
->server
, client
->mount_port
);
191 printf("Send NULL request to check if RPC.MOUNTD is actually running\n");
192 if (rpc_mount_null_async(rpc
, mount_null_cb
, client
) != 0) {
193 printf("Failed to send null request\n");
199 void pmap_getport2_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
201 struct client
*client
= private_data
;
203 if (status
== RPC_STATUS_ERROR
) {
204 printf("portmapper getport call failed with \"%s\"\n", (char *)data
);
207 if (status
!= RPC_STATUS_SUCCESS
) {
208 printf("portmapper getport call to server %s failed, status:%d\n", client
->server
, status
);
212 client
->mount_port
= *(uint32_t *)data
;
213 printf("GETPORT returned RPC.MOUNTD is on port:%d\n", client
->mount_port
);
214 if (client
->mount_port
== 0) {
215 printf("RPC.MOUNTD is not available on server : %s:%d\n", client
->server
, client
->mount_port
);
219 printf("Disconnect socket from portmap server\n");
220 if (rpc_disconnect(rpc
, "normal disconnect") != 0) {
221 printf("Failed to disconnect socket to portmapper\n");
225 printf("Connect to RPC.MOUNTD on %s:%d\n", client
->server
, client
->mount_port
);
226 if (rpc_connect_async(rpc
, client
->server
, client
->mount_port
, mount_connect_cb
, client
) != 0) {
227 printf("Failed to start connection\n");
232 void pmap_getport1_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
234 struct client
*client
= private_data
;
236 if (status
== RPC_STATUS_ERROR
) {
237 printf("portmapper getport call failed with \"%s\"\n", (char *)data
);
240 if (status
!= RPC_STATUS_SUCCESS
) {
241 printf("portmapper getport call to server %s failed, status:%d\n", client
->server
, status
);
245 client
->rquota_port
= *(uint32_t *)data
;
246 printf("GETPORT returned RPC.RQUOTAD on port:%d\n", client
->rquota_port
);
247 if (client
->rquota_port
== 0) {
248 printf("RPC.RQUOTAD is not available on server : %s:%d\n", client
->server
, client
->rquota_port
);
252 printf("Send getport request asking for MOUNT port\n");
253 if (rpc_pmap_getport_async(rpc
, MOUNT_PROGRAM
, MOUNT_V3
, pmap_getport2_cb
, client
) != 0) {
254 printf("Failed to send getport request\n");
259 void pmap_null_cb(struct rpc_context
*rpc
, int status
, void *data
, void *private_data
)
261 struct client
*client
= private_data
;
263 if (status
== RPC_STATUS_ERROR
) {
264 printf("portmapper null call failed with \"%s\"\n", (char *)data
);
267 if (status
!= RPC_STATUS_SUCCESS
) {
268 printf("portmapper null call to server %s failed, status:%d\n", client
->server
, status
);
272 printf("Got reply from server for PORTMAP/NULL procedure.\n");
273 printf("Send getport request asking for MOUNT port\n");
274 if (rpc_pmap_getport_async(rpc
, RQUOTA_PROGRAM
, RQUOTA_V1
, pmap_getport1_cb
, client
) != 0) {
275 printf("Failed to send getport request\n");
280 void pmap_connect_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
282 struct client
*client
= private_data
;
284 printf("pmap_connect_cb status:%d.\n", status
);
285 if (status
!= RPC_STATUS_SUCCESS
) {
286 printf("connection to portmapper on server %s failed\n", client
->server
);
290 printf("Send NULL request to check if portmapper is actually running\n");
291 if (rpc_pmap_null_async(rpc
, pmap_null_cb
, client
) != 0) {
292 printf("Failed to send null request\n");
298 int main(int argc _U_
, char *argv
[] _U_
)
300 struct rpc_context
*rpc
;
302 struct client client
;
304 rpc
= rpc_init_context();
306 printf("failed to init context\n");
310 client
.server
= SERVER
;
311 client
.export
= EXPORT
;
312 client
.is_finished
= 0;
313 if (rpc_connect_async(rpc
, client
.server
, 111, pmap_connect_cb
, &client
) != 0) {
314 printf("Failed to start connection\n");
319 pfd
.fd
= rpc_get_fd(rpc
);
320 pfd
.events
= rpc_which_events(rpc
);
322 if (poll(&pfd
, 1, -1) < 0) {
323 printf("Poll failed");
326 if (rpc_service(rpc
, pfd
.revents
) < 0) {
327 printf("rpc_service failed\n");
330 if (client
.is_finished
) {
335 rpc_destroy_context(rpc
);
337 printf("nfsclient finished\n");