initial libnfs checkin
[deb_libnfs.git] / examples / nfsclient-raw.c
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
22 #define SERVER "10.1.1.27"
23 #define EXPORT "/VIRTUAL"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <poll.h>
28 #include "libnfs.h"
29 #include "libnfs-raw.h"
30 #include "libnfs-raw-mount.h"
31
32 struct client {
33 char *server;
34 char *export;
35 uint32_t mount_port;
36 int is_finished;
37 };
38
39 void mount_mnt_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
40 {
41 struct client *client = private_data;
42
43 if (status == RPC_STATUS_ERROR) {
44 printf("mount/mnt call failed with \"%s\"\n", (char *)data);
45 exit(10);
46 }
47 if (status != RPC_STATUS_SUCCESS) {
48 printf("mount/mnt call to server %s failed, status:%d\n", client->server, status);
49 exit(10);
50 }
51
52 printf("Got reply from server for MOUNT/MNT procedure.\n");
53 client->is_finished = 1;
54 }
55
56
57 void mount_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
58 {
59 struct client *client = private_data;
60
61 if (status == RPC_STATUS_ERROR) {
62 printf("mount null call failed with \"%s\"\n", (char *)data);
63 exit(10);
64 }
65 if (status != RPC_STATUS_SUCCESS) {
66 printf("mount null call to server %s failed, status:%d\n", client->server, status);
67 exit(10);
68 }
69
70 printf("Got reply from server for MOUNT/NULL procedure.\n");
71 printf("Send MOUNT/MNT command for %s\n", client->export);
72 if (rpc_mount_mnt_async(rpc, mount_mnt_cb, client->export, client) != 0) {
73 printf("Failed to send mnt request\n");
74 exit(10);
75 }
76
77 }
78
79 void mount_connect_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
80 {
81 struct client *client = private_data;
82
83 if (status != RPC_STATUS_SUCCESS) {
84 printf("connection to RPC.MOUNTD on server %s failed\n", client->server);
85 exit(10);
86 }
87
88 printf("Connected to RPC.MOUNTD on %s:%d\n", client->server, client->mount_port);
89 printf("Send NULL request to check if RPC.MOUNTD is actually running\n");
90 if (rpc_mount_null_async(rpc, mount_null_cb, client) != 0) {
91 printf("Failed to send null request\n");
92 exit(10);
93 }
94 }
95
96
97 void pmap_getport_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
98 {
99 struct client *client = private_data;
100 uint32_t port;
101
102 if (status == RPC_STATUS_ERROR) {
103 printf("portmapper getport call failed with \"%s\"\n", (char *)data);
104 exit(10);
105 }
106 if (status != RPC_STATUS_SUCCESS) {
107 printf("portmapper getport call to server %s failed, status:%d\n", client->server, status);
108 exit(10);
109 }
110
111 client->mount_port = *(uint32_t *)data;
112 printf("GETPORT returned Port:%d\n", client->mount_port);
113 if (client->mount_port == 0) {
114 printf("RPC.MOUNTD is not available on server : %s\n", client->server, client->mount_port);
115 exit(10);
116 }
117
118 printf("Disconnect socket from portmap server\n");
119 if (rpc_disconnect(rpc, "normal disconnect") != 0) {
120 printf("Failed to disconnect socket to portmapper\n");
121 exit(10);
122 }
123
124 printf("Connect to RPC.MOUNTD on %s:%d\n", client->server, client->mount_port);
125 if (rpc_connect_async(rpc, client->server, client->mount_port, mount_connect_cb, client) != 0) {
126 printf("Failed to start connection\n");
127 exit(10);
128 }
129 }
130
131
132 void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
133 {
134 struct client *client = private_data;
135
136 if (status == RPC_STATUS_ERROR) {
137 printf("portmapper null call failed with \"%s\"\n", (char *)data);
138 exit(10);
139 }
140 if (status != RPC_STATUS_SUCCESS) {
141 printf("portmapper null call to server %s failed, status:%d\n", client->server, status);
142 exit(10);
143 }
144
145 printf("Got reply from server for PORTMAP/NULL procedure.\n");
146 printf("Send getport request asking for MOUNT port\n");
147 if (rpc_pmap_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, pmap_getport_cb, client) != 0) {
148 printf("Failed to send getport request\n");
149 exit(10);
150 }
151 }
152
153 void pmap_connect_cb(struct rpc_context *rpc, int status, void *data, void *private_data)
154 {
155 struct client *client = private_data;
156
157 printf("pmap_connect_cb status:%d.\n", status);
158 if (status != RPC_STATUS_SUCCESS) {
159 printf("connection to portmapper on server %s failed\n", client->server);
160 exit(10);
161 }
162
163 printf("Send NULL request to check if portmapper is actually running\n");
164 if (rpc_pmap_null_async(rpc, pmap_null_cb, client) != 0) {
165 printf("Failed to send null request\n");
166 exit(10);
167 }
168 }
169
170
171 int main(int argc, char *argv[])
172 {
173 struct rpc_context *rpc;
174 struct pollfd pfd;
175 int ret;
176 struct client client;
177
178 rpc = rpc_init_context();
179 if (rpc == NULL) {
180 printf("failed to init context\n");
181 exit(10);
182 }
183
184 client.server = SERVER;
185 client.export = EXPORT;
186 client.is_finished = 0;
187 if (rpc_connect_async(rpc, client.server, 111, pmap_connect_cb, &client) != 0) {
188 printf("Failed to start connection\n");
189 exit(10);
190 }
191
192 for (;;) {
193 pfd.fd = rpc_get_fd(rpc);
194 pfd.events = rpc_which_events(rpc);
195
196 if (poll(&pfd, 1, -1) < 0) {
197 printf("Poll failed");
198 exit(10);
199 }
200 if (rpc_service(rpc, pfd.revents) < 0) {
201 printf("rpc_service failed\n");
202 break;
203 }
204 if (client.is_finished) {
205 break;
206 }
207 }
208
209 rpc_destroy_context(rpc);
210 rpc=NULL;
211 printf("nfsclient finished\n");
212 return 0;
213 }