types: remove the [u_]quad type and replace with [u]int64
[deb_libnfs.git] / examples / nfsclient-async.c
... / ...
CommitLineData
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 highlevel async interface.
19 */
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#ifdef WIN32
25#include "win32_compat.h"
26#else
27#include <sys/stat.h>
28#endif
29
30#ifdef HAVE_POLL_H
31#include <poll.h>
32#endif
33
34#ifdef HAVE_UNISTD_H
35#include <unistd.h>
36#endif
37
38#define SERVER "10.1.1.27"
39#define EXPORT "/VIRTUAL"
40#define NFSFILE "/BOOKS/Classics/Dracula.djvu"
41#define NFSDIR "/BOOKS/Classics/"
42
43#include <stdio.h>
44#include <stdlib.h>
45#include <stdint.h>
46#include <sys/types.h>
47#include <fcntl.h>
48#include "libnfs.h"
49#include "libnfs-raw.h"
50#include "libnfs-raw-mount.h"
51
52struct rpc_context *mount_context;
53
54struct client {
55 char *server;
56 char *export;
57 uint32_t mount_port;
58 struct nfsfh *nfsfh;
59 int is_finished;
60};
61
62void mount_export_cb(struct rpc_context *mount_context, int status, void *data, void *private_data)
63{
64 struct client *client = private_data;
65 exports export = *(exports *)data;
66
67 if (status < 0) {
68 printf("MOUNT/EXPORT failed with \"%s\"\n", rpc_get_error(mount_context));
69 exit(10);
70 }
71
72 printf("Got exports list from server %s\n", client->server);
73 while (export != NULL) {
74 printf("Export: %s\n", export->ex_dir);
75 export = export->ex_next;
76 }
77
78 mount_context = NULL;
79
80 client->is_finished = 1;
81}
82
83void nfs_opendir_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84{
85 struct client *client = private_data;
86 struct nfsdir *nfsdir = data;
87 struct nfsdirent *nfsdirent;
88
89 if (status < 0) {
90 printf("opendir failed with \"%s\"\n", (char *)data);
91 exit(10);
92 }
93
94 printf("opendir successful\n");
95 while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) {
96 printf("Inode:%d Name:%s\n", (int)nfsdirent->inode, nfsdirent->name);
97 }
98 nfs_closedir(nfs, nfsdir);
99
100 mount_context = rpc_init_context();
101 if (mount_getexports_async(mount_context, client->server, mount_export_cb, client) != 0) {
102 printf("Failed to start MOUNT/EXPORT\n");
103 exit(10);
104 }
105}
106
107void nfs_close_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
108{
109 struct client *client = private_data;
110
111 if (status < 0) {
112 printf("close failed with \"%s\"\n", (char *)data);
113 exit(10);
114 }
115
116 printf("close successful\n");
117 printf("call opendir(%s)\n", NFSDIR);
118 if (nfs_opendir_async(nfs, NFSDIR, nfs_opendir_cb, client) != 0) {
119 printf("Failed to start async nfs close\n");
120 exit(10);
121 }
122}
123
124void nfs_fstat_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
125{
126 struct client *client = private_data;
127 struct stat *st;
128
129 if (status < 0) {
130 printf("fstat call failed with \"%s\"\n", (char *)data);
131 exit(10);
132 }
133
134 printf("Got reply from server for fstat(%s).\n", NFSFILE);
135 st = (struct stat *)data;
136 printf("Mode %04o\n", st->st_mode);
137 printf("Size %d\n", (int)st->st_size);
138 printf("Inode %04o\n", (int)st->st_ino);
139
140 printf("Close file\n");
141 if (nfs_close_async(nfs, client->nfsfh, nfs_close_cb, client) != 0) {
142 printf("Failed to start async nfs close\n");
143 exit(10);
144 }
145}
146
147void nfs_read_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
148{
149 struct client *client = private_data;
150 char *read_data;
151 int i;
152
153 if (status < 0) {
154 printf("read failed with \"%s\"\n", (char *)data);
155 exit(10);
156 }
157
158 printf("read successful with %d bytes of data\n", status);
159 read_data = data;
160 for (i=0;i<16;i++) {
161 printf("%02x ", read_data[i]&0xff);
162 }
163 printf("\n");
164 printf("Fstat file :%s\n", NFSFILE);
165 if (nfs_fstat_async(nfs, client->nfsfh, nfs_fstat_cb, client) != 0) {
166 printf("Failed to start async nfs fstat\n");
167 exit(10);
168 }
169}
170
171void nfs_open_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
172{
173 struct client *client = private_data;
174 struct nfsfh *nfsfh;
175
176 if (status < 0) {
177 printf("open call failed with \"%s\"\n", (char *)data);
178 exit(10);
179 }
180
181 nfsfh = data;
182 client->nfsfh = nfsfh;
183 printf("Got reply from server for open(%s). Handle:%p\n", NFSFILE, data);
184 printf("Read first 64 bytes\n");
185 if (nfs_pread_async(nfs, nfsfh, 0, 64, nfs_read_cb, client) != 0) {
186 printf("Failed to start async nfs open\n");
187 exit(10);
188 }
189}
190
191void nfs_stat_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
192{
193 struct client *client = private_data;
194 struct stat *st;
195
196 if (status < 0) {
197 printf("stat call failed with \"%s\"\n", (char *)data);
198 exit(10);
199 }
200
201 printf("Got reply from server for stat(%s).\n", NFSFILE);
202 st = (struct stat *)data;
203 printf("Mode %04o\n", st->st_mode);
204 printf("Size %d\n", (int)st->st_size);
205 printf("Inode %04o\n", (int)st->st_ino);
206
207 printf("Open file for reading :%s\n", NFSFILE);
208 if (nfs_open_async(nfs, NFSFILE, O_RDONLY, nfs_open_cb, client) != 0) {
209 printf("Failed to start async nfs open\n");
210 exit(10);
211 }
212}
213
214void nfs_mount_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
215{
216 struct client *client = private_data;
217
218 if (status < 0) {
219 printf("mount/mnt call failed with \"%s\"\n", (char *)data);
220 exit(10);
221 }
222
223 printf("Got reply from server for MOUNT/MNT procedure.\n");
224 printf("Stat file :%s\n", NFSFILE);
225 if (nfs_stat_async(nfs, NFSFILE, nfs_stat_cb, client) != 0) {
226 printf("Failed to start async nfs stat\n");
227 exit(10);
228 }
229}
230
231
232
233int main(int argc _U_, char *argv[] _U_)
234{
235 struct nfs_context *nfs;
236 int ret;
237 struct client client;
238 struct pollfd pfds[2]; /* nfs:0 mount:1 */
239
240 client.server = SERVER;
241 client.export = EXPORT;
242 client.is_finished = 0;
243
244 nfs = nfs_init_context();
245 if (nfs == NULL) {
246 printf("failed to init context\n");
247 exit(10);
248 }
249
250 ret = nfs_mount_async(nfs, client.server, client.export, nfs_mount_cb, &client);
251 if (ret != 0) {
252 printf("Failed to start async nfs mount\n");
253 exit(10);
254 }
255
256 for (;;) {
257 int num_fds;
258
259 pfds[0].fd = nfs_get_fd(nfs);
260 pfds[0].events = nfs_which_events(nfs);
261 num_fds = 1;
262
263 if (mount_context != 0 && rpc_get_fd(mount_context) != -1) {
264 pfds[1].fd = rpc_get_fd(mount_context);
265 pfds[1].events = rpc_which_events(mount_context);
266 num_fds = 2;
267 }
268 if (poll(&pfds[0], 2, -1) < 0) {
269 printf("Poll failed");
270 exit(10);
271 }
272 if (mount_context != NULL) {
273 if (rpc_service(mount_context, pfds[1].revents) < 0) {
274 printf("rpc_service failed\n");
275 break;
276 }
277 }
278 if (nfs_service(nfs, pfds[0].revents) < 0) {
279 printf("nfs_service failed\n");
280 break;
281 }
282 if (client.is_finished) {
283 break;
284 }
285 }
286
287 nfs_destroy_context(nfs);
288 if (mount_context != NULL) {
289 rpc_destroy_context(mount_context);
290 mount_context = NULL;
291 }
292 printf("nfsclient finished\n");
293 return 0;
294}