ZDR: remove dependency on zdr.h from the examples and nfs-ls
[deb_libnfs.git] / examples / nfsclient-async.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 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
52 struct rpc_context *mount_context;
53
54 struct client {
55 char *server;
56 char *export;
57 uint32_t mount_port;
58 struct nfsfh *nfsfh;
59 int is_finished;
60 };
61
62 void 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
83 void 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
107 void 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
124 void 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
147 void 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
171 void 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
191 void 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
214 void 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
233 int 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 }