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