2 Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 * High level api to nfs filesystems
25 #include <sys/types.h>
27 #include <sys/statvfs.h>
33 #include "libnfs-raw.h"
34 #include "libnfs-raw-mount.h"
35 #include "libnfs-raw-nfs.h"
36 #include "libnfs-private.h"
47 static void wait_for_reply(struct rpc_context
*rpc
, struct sync_cb_data
*cb_data
)
52 if (cb_data
->is_finished
) {
55 pfd
.fd
= rpc_get_fd(rpc
);
56 pfd
.events
= rpc_which_events(rpc
);
58 if (poll(&pfd
, 1, -1) < 0) {
59 rpc_set_error(rpc
, "Poll failed");
60 cb_data
->status
= -EIO
;
63 if (rpc_service(rpc
, pfd
.revents
) < 0) {
64 rpc_set_error(rpc
, "rpc_service failed");
65 cb_data
->status
= -EIO
;
77 * connect to the server and mount the export
79 static void mount_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
81 struct sync_cb_data
*cb_data
= private_data
;
83 cb_data
->is_finished
= 1;
84 cb_data
->status
= status
;
87 nfs_set_error(nfs
, "mount/mnt call failed with \"%s\"", (char *)data
);
92 int nfs_mount(struct nfs_context
*nfs
, const char *server
, const char *export
)
94 struct sync_cb_data cb_data
;
96 cb_data
.is_finished
= 0;
98 if (nfs_mount_async(nfs
, server
, export
, mount_cb
, &cb_data
) != 0) {
99 nfs_set_error(nfs
, "nfs_mount_async failed");
103 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
105 return cb_data
.status
;
112 static void stat_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
114 struct sync_cb_data
*cb_data
= private_data
;
116 cb_data
->is_finished
= 1;
117 cb_data
->status
= status
;
120 nfs_set_error(nfs
, "stat call failed with \"%s\"", (char *)data
);
124 memcpy(cb_data
->return_data
, data
, sizeof(struct stat
));
127 int nfs_stat(struct nfs_context
*nfs
, const char *path
, struct stat
*st
)
129 struct sync_cb_data cb_data
;
131 cb_data
.is_finished
= 0;
132 cb_data
.return_data
= st
;
134 if (nfs_stat_async(nfs
, path
, stat_cb
, &cb_data
) != 0) {
135 nfs_set_error(nfs
, "nfs_stat_async failed");
139 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
141 return cb_data
.status
;
150 static void open_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
152 struct sync_cb_data
*cb_data
= private_data
;
153 struct nfsfh
*fh
, **nfsfh
;
155 cb_data
->is_finished
= 1;
156 cb_data
->status
= status
;
159 nfs_set_error(nfs
, "open call failed with \"%s\"", (char *)data
);
164 nfsfh
= cb_data
->return_data
;
168 int nfs_open(struct nfs_context
*nfs
, const char *path
, int mode
, struct nfsfh
**nfsfh
)
170 struct sync_cb_data cb_data
;
172 cb_data
.is_finished
= 0;
173 cb_data
.return_data
= nfsfh
;
175 if (nfs_open_async(nfs
, path
, mode
, open_cb
, &cb_data
) != 0) {
176 nfs_set_error(nfs
, "nfs_open_async failed");
180 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
182 return cb_data
.status
;
191 static void pread_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
193 struct sync_cb_data
*cb_data
= private_data
;
195 cb_data
->is_finished
= 1;
196 cb_data
->status
= status
;
199 nfs_set_error(nfs
, "pread call failed with \"%s\"", (char *)data
);
203 buffer
= cb_data
->return_data
;
204 memcpy(buffer
, (char *)data
, status
);
207 int nfs_pread(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, off_t offset
, size_t count
, char *buffer
)
209 struct sync_cb_data cb_data
;
211 cb_data
.is_finished
= 0;
212 cb_data
.return_data
= buffer
;
214 if (nfs_pread_async(nfs
, nfsfh
, offset
, count
, pread_cb
, &cb_data
) != 0) {
215 nfs_set_error(nfs
, "nfs_pread_async failed");
219 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
221 return cb_data
.status
;
227 int nfs_read(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, size_t count
, char *buffer
)
229 return nfs_pread(nfs
, nfsfh
, nfs_get_current_offset(nfsfh
), count
, buffer
);
235 static void close_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
237 struct sync_cb_data
*cb_data
= private_data
;
238 cb_data
->is_finished
= 1;
239 cb_data
->status
= status
;
242 nfs_set_error(nfs
, "close call failed with \"%s\"", (char *)data
);
247 int nfs_close(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
)
249 struct sync_cb_data cb_data
;
251 cb_data
.is_finished
= 0;
253 if (nfs_close_async(nfs
, nfsfh
, close_cb
, &cb_data
) != 0) {
254 nfs_set_error(nfs
, "nfs_close_async failed");
258 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
260 return cb_data
.status
;
269 int nfs_fstat(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, struct stat
*st
)
271 struct sync_cb_data cb_data
;
273 cb_data
.is_finished
= 0;
274 cb_data
.return_data
= st
;
276 if (nfs_fstat_async(nfs
, nfsfh
, stat_cb
, &cb_data
) != 0) {
277 nfs_set_error(nfs
, "nfs_fstat_async failed");
281 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
283 return cb_data
.status
;
290 static void pwrite_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
292 struct sync_cb_data
*cb_data
= private_data
;
293 cb_data
->is_finished
= 1;
294 cb_data
->status
= status
;
297 nfs_set_error(nfs
, "pwrite call failed with \"%s\"", (char *)data
);
302 int nfs_pwrite(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, off_t offset
, size_t count
, char *buf
)
304 struct sync_cb_data cb_data
;
306 cb_data
.is_finished
= 0;
308 if (nfs_pwrite_async(nfs
, nfsfh
, offset
, count
, buf
, pwrite_cb
, &cb_data
) != 0) {
309 nfs_set_error(nfs
, "nfs_pwrite_async failed");
313 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
315 return cb_data
.status
;
321 int nfs_write(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, size_t count
, char *buf
)
323 return nfs_pwrite(nfs
, nfsfh
, nfs_get_current_offset(nfsfh
), count
, buf
);
330 static void fsync_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
332 struct sync_cb_data
*cb_data
= private_data
;
333 cb_data
->is_finished
= 1;
334 cb_data
->status
= status
;
337 nfs_set_error(nfs
, "fsync call failed with \"%s\"", (char *)data
);
342 int nfs_fsync(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
)
344 struct sync_cb_data cb_data
;
346 cb_data
.is_finished
= 0;
348 if (nfs_fsync_async(nfs
, nfsfh
, fsync_cb
, &cb_data
) != 0) {
349 nfs_set_error(nfs
, "nfs_fsync_async failed");
353 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
355 return cb_data
.status
;
364 static void ftruncate_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
366 struct sync_cb_data
*cb_data
= private_data
;
367 cb_data
->is_finished
= 1;
368 cb_data
->status
= status
;
371 nfs_set_error(nfs
, "ftruncate call failed with \"%s\"", (char *)data
);
376 int nfs_ftruncate(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, off_t length
)
378 struct sync_cb_data cb_data
;
380 cb_data
.is_finished
= 0;
382 if (nfs_ftruncate_async(nfs
, nfsfh
, length
, ftruncate_cb
, &cb_data
) != 0) {
383 nfs_set_error(nfs
, "nfs_ftruncate_async failed");
387 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
389 return cb_data
.status
;
397 static void truncate_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
399 struct sync_cb_data
*cb_data
= private_data
;
400 cb_data
->is_finished
= 1;
401 cb_data
->status
= status
;
404 nfs_set_error(nfs
, "truncate call failed with \"%s\"", (char *)data
);
409 int nfs_truncate(struct nfs_context
*nfs
, const char *path
, off_t length
)
411 struct sync_cb_data cb_data
;
413 cb_data
.is_finished
= 0;
415 if (nfs_truncate_async(nfs
, path
, length
, truncate_cb
, &cb_data
) != 0) {
416 nfs_set_error(nfs
, "nfs_ftruncate_async failed");
420 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
422 return cb_data
.status
;
432 static void mkdir_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
434 struct sync_cb_data
*cb_data
= private_data
;
435 cb_data
->is_finished
= 1;
436 cb_data
->status
= status
;
439 nfs_set_error(nfs
, "mkdir call failed with \"%s\"", (char *)data
);
444 int nfs_mkdir(struct nfs_context
*nfs
, const char *path
)
446 struct sync_cb_data cb_data
;
448 cb_data
.is_finished
= 0;
450 if (nfs_mkdir_async(nfs
, path
, mkdir_cb
, &cb_data
) != 0) {
451 nfs_set_error(nfs
, "nfs_mkdir_async failed");
455 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
457 return cb_data
.status
;
467 static void rmdir_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
469 struct sync_cb_data
*cb_data
= private_data
;
470 cb_data
->is_finished
= 1;
471 cb_data
->status
= status
;
474 nfs_set_error(nfs
, "rmdir call failed with \"%s\"", (char *)data
);
479 int nfs_rmdir(struct nfs_context
*nfs
, const char *path
)
481 struct sync_cb_data cb_data
;
483 cb_data
.is_finished
= 0;
485 if (nfs_rmdir_async(nfs
, path
, rmdir_cb
, &cb_data
) != 0) {
486 nfs_set_error(nfs
, "nfs_rmdir_async failed");
490 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
492 return cb_data
.status
;
500 static void creat_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
502 struct sync_cb_data
*cb_data
= private_data
;
503 struct nfsfh
*fh
, **nfsfh
;
505 cb_data
->is_finished
= 1;
506 cb_data
->status
= status
;
509 nfs_set_error(nfs
, "creat call failed with \"%s\"", (char *)data
);
514 nfsfh
= cb_data
->return_data
;
518 int nfs_creat(struct nfs_context
*nfs
, const char *path
, int mode
, struct nfsfh
**nfsfh
)
520 struct sync_cb_data cb_data
;
522 cb_data
.is_finished
= 0;
523 cb_data
.return_data
= nfsfh
;
525 if (nfs_creat_async(nfs
, path
, mode
, creat_cb
, &cb_data
) != 0) {
526 nfs_set_error(nfs
, "nfs_creat_async failed");
530 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
532 return cb_data
.status
;
541 static void unlink_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
543 struct sync_cb_data
*cb_data
= private_data
;
545 cb_data
->is_finished
= 1;
546 cb_data
->status
= status
;
549 nfs_set_error(nfs
, "unlink call failed with \"%s\"", (char *)data
);
554 int nfs_unlink(struct nfs_context
*nfs
, const char *path
)
556 struct sync_cb_data cb_data
;
558 cb_data
.is_finished
= 0;
560 if (nfs_unlink_async(nfs
, path
, unlink_cb
, &cb_data
) != 0) {
561 nfs_set_error(nfs
, "nfs_unlink_async failed");
565 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
567 return cb_data
.status
;
575 static void opendir_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
577 struct sync_cb_data
*cb_data
= private_data
;
578 struct nfsdir
*dir
, **nfsdir
;
580 cb_data
->is_finished
= 1;
581 cb_data
->status
= status
;
584 nfs_set_error(nfs
, "opendir call failed with \"%s\"", (char *)data
);
589 nfsdir
= cb_data
->return_data
;
593 int nfs_opendir(struct nfs_context
*nfs
, const char *path
, struct nfsdir
**nfsdir
)
595 struct sync_cb_data cb_data
;
597 cb_data
.is_finished
= 0;
598 cb_data
.return_data
= nfsdir
;
600 if (nfs_opendir_async(nfs
, path
, opendir_cb
, &cb_data
) != 0) {
601 nfs_set_error(nfs
, "nfs_opendir_async failed");
605 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
607 return cb_data
.status
;
614 static void lseek_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
616 struct sync_cb_data
*cb_data
= private_data
;
618 cb_data
->is_finished
= 1;
619 cb_data
->status
= status
;
622 nfs_set_error(nfs
, "lseek call failed with \"%s\"", (char *)data
);
626 if (cb_data
->return_data
!= NULL
) {
627 memcpy(cb_data
->return_data
, data
, sizeof(off_t
));
631 int nfs_lseek(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, off_t offset
, int whence
, off_t
*current_offset
)
633 struct sync_cb_data cb_data
;
635 cb_data
.is_finished
= 0;
636 cb_data
.return_data
= current_offset
;
638 if (nfs_lseek_async(nfs
, nfsfh
, offset
, whence
, lseek_cb
, &cb_data
) != 0) {
639 nfs_set_error(nfs
, "nfs_lseek_async failed");
643 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
645 return cb_data
.status
;
653 static void statvfs_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
655 struct sync_cb_data
*cb_data
= private_data
;
657 cb_data
->is_finished
= 1;
658 cb_data
->status
= status
;
661 nfs_set_error(nfs
, "statvfs call failed with \"%s\"", (char *)data
);
665 memcpy(cb_data
->return_data
, data
, sizeof(struct statvfs
));
668 int nfs_statvfs(struct nfs_context
*nfs
, const char *path
, struct statvfs
*svfs
)
670 struct sync_cb_data cb_data
;
672 cb_data
.is_finished
= 0;
673 cb_data
.return_data
= svfs
;
675 if (nfs_statvfs_async(nfs
, path
, statvfs_cb
, &cb_data
) != 0) {
676 nfs_set_error(nfs
, "nfs_statvfs_async failed");
680 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
682 return cb_data
.status
;
692 static void readlink_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
694 struct sync_cb_data
*cb_data
= private_data
;
696 cb_data
->is_finished
= 1;
697 cb_data
->status
= status
;
700 nfs_set_error(nfs
, "readlink call failed with \"%s\"", (char *)data
);
704 if (strlen(data
) > (size_t)cb_data
->return_int
) {
705 nfs_set_error(nfs
, "Too small buffer for readlink");
706 cb_data
->status
= -ENAMETOOLONG
;
710 memcpy(cb_data
->return_data
, data
, strlen(data
)+1);
713 int nfs_readlink(struct nfs_context
*nfs
, const char *path
, char *buf
, int bufsize
)
715 struct sync_cb_data cb_data
;
717 cb_data
.is_finished
= 0;
718 cb_data
.return_data
= buf
;
719 cb_data
.return_int
= bufsize
;
721 if (nfs_readlink_async(nfs
, path
, readlink_cb
, &cb_data
) != 0) {
722 nfs_set_error(nfs
, "nfs_readlink_async failed");
726 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
728 return cb_data
.status
;
736 static void chmod_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
738 struct sync_cb_data
*cb_data
= private_data
;
740 cb_data
->is_finished
= 1;
741 cb_data
->status
= status
;
744 nfs_set_error(nfs
, "chmod call failed with \"%s\"", (char *)data
);
749 int nfs_chmod(struct nfs_context
*nfs
, const char *path
, int mode
)
751 struct sync_cb_data cb_data
;
753 cb_data
.is_finished
= 0;
755 if (nfs_chmod_async(nfs
, path
, mode
, chmod_cb
, &cb_data
) != 0) {
756 nfs_set_error(nfs
, "nfs_chmod_async failed");
760 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
762 return cb_data
.status
;
771 static void fchmod_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
773 struct sync_cb_data
*cb_data
= private_data
;
775 cb_data
->is_finished
= 1;
776 cb_data
->status
= status
;
779 nfs_set_error(nfs
, "fchmod call failed with \"%s\"", (char *)data
);
784 int nfs_fchmod(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, int mode
)
786 struct sync_cb_data cb_data
;
788 cb_data
.is_finished
= 0;
790 if (nfs_fchmod_async(nfs
, nfsfh
, mode
, fchmod_cb
, &cb_data
) != 0) {
791 nfs_set_error(nfs
, "nfs_fchmod_async failed");
795 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
797 return cb_data
.status
;
806 static void chown_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
808 struct sync_cb_data
*cb_data
= private_data
;
810 cb_data
->is_finished
= 1;
811 cb_data
->status
= status
;
814 nfs_set_error(nfs
, "chown call failed with \"%s\"", (char *)data
);
819 int nfs_chown(struct nfs_context
*nfs
, const char *path
, int uid
, int gid
)
821 struct sync_cb_data cb_data
;
823 cb_data
.is_finished
= 0;
825 if (nfs_chown_async(nfs
, path
, uid
, gid
, chown_cb
, &cb_data
) != 0) {
826 nfs_set_error(nfs
, "nfs_chown_async failed");
830 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
832 return cb_data
.status
;
838 static void fchown_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
840 struct sync_cb_data
*cb_data
= private_data
;
842 cb_data
->is_finished
= 1;
843 cb_data
->status
= status
;
846 nfs_set_error(nfs
, "fchown call failed with \"%s\"", (char *)data
);
851 int nfs_fchown(struct nfs_context
*nfs
, struct nfsfh
*nfsfh
, int uid
, int gid
)
853 struct sync_cb_data cb_data
;
855 cb_data
.is_finished
= 0;
857 if (nfs_fchown_async(nfs
, nfsfh
, uid
, gid
, fchown_cb
, &cb_data
) != 0) {
858 nfs_set_error(nfs
, "nfs_fchown_async failed");
862 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
864 return cb_data
.status
;
872 static void utimes_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
874 struct sync_cb_data
*cb_data
= private_data
;
876 cb_data
->is_finished
= 1;
877 cb_data
->status
= status
;
880 nfs_set_error(nfs
, "utimes call failed with \"%s\"", (char *)data
);
885 int nfs_utimes(struct nfs_context
*nfs
, const char *path
, struct timeval
*times
)
887 struct sync_cb_data cb_data
;
889 cb_data
.is_finished
= 0;
891 if (nfs_utimes_async(nfs
, path
, times
, utimes_cb
, &cb_data
) != 0) {
892 nfs_set_error(nfs
, "nfs_utimes_async failed");
896 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
898 return cb_data
.status
;
906 static void utime_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
908 struct sync_cb_data
*cb_data
= private_data
;
910 cb_data
->is_finished
= 1;
911 cb_data
->status
= status
;
914 nfs_set_error(nfs
, "utime call failed with \"%s\"", (char *)data
);
919 int nfs_utime(struct nfs_context
*nfs
, const char *path
, struct utimbuf
*times
)
921 struct sync_cb_data cb_data
;
923 cb_data
.is_finished
= 0;
925 if (nfs_utime_async(nfs
, path
, times
, utime_cb
, &cb_data
) != 0) {
926 nfs_set_error(nfs
, "nfs_utimes_async failed");
930 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
932 return cb_data
.status
;
941 static void access_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
943 struct sync_cb_data
*cb_data
= private_data
;
945 cb_data
->is_finished
= 1;
946 cb_data
->status
= status
;
949 nfs_set_error(nfs
, "access call failed with \"%s\"", (char *)data
);
954 int nfs_access(struct nfs_context
*nfs
, const char *path
, int mode
)
956 struct sync_cb_data cb_data
;
958 cb_data
.is_finished
= 0;
960 if (nfs_access_async(nfs
, path
, mode
, access_cb
, &cb_data
) != 0) {
961 nfs_set_error(nfs
, "nfs_access_async failed");
965 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
967 return cb_data
.status
;
975 static void symlink_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
977 struct sync_cb_data
*cb_data
= private_data
;
979 cb_data
->is_finished
= 1;
980 cb_data
->status
= status
;
983 nfs_set_error(nfs
, "symlink call failed with \"%s\"", (char *)data
);
988 int nfs_symlink(struct nfs_context
*nfs
, const char *oldpath
, const char *newpath
)
990 struct sync_cb_data cb_data
;
992 cb_data
.is_finished
= 0;
994 if (nfs_symlink_async(nfs
, oldpath
, newpath
, symlink_cb
, &cb_data
) != 0) {
995 nfs_set_error(nfs
, "nfs_symlink_async failed");
999 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
1001 return cb_data
.status
;
1009 static void rename_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
1011 struct sync_cb_data
*cb_data
= private_data
;
1013 cb_data
->is_finished
= 1;
1014 cb_data
->status
= status
;
1017 nfs_set_error(nfs
, "rename call failed with \"%s\"", (char *)data
);
1022 int nfs_rename(struct nfs_context
*nfs
, const char *oldpath
, const char *newpath
)
1024 struct sync_cb_data cb_data
;
1026 cb_data
.is_finished
= 0;
1028 if (nfs_rename_async(nfs
, oldpath
, newpath
, rename_cb
, &cb_data
) != 0) {
1029 nfs_set_error(nfs
, "nfs_rename_async failed");
1033 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
1035 return cb_data
.status
;
1043 static void link_cb(int status
, struct nfs_context
*nfs
, void *data
, void *private_data
)
1045 struct sync_cb_data
*cb_data
= private_data
;
1047 cb_data
->is_finished
= 1;
1048 cb_data
->status
= status
;
1051 nfs_set_error(nfs
, "link call failed with \"%s\"", (char *)data
);
1056 int nfs_link(struct nfs_context
*nfs
, const char *oldpath
, const char *newpath
)
1058 struct sync_cb_data cb_data
;
1060 cb_data
.is_finished
= 0;
1062 if (nfs_link_async(nfs
, oldpath
, newpath
, link_cb
, &cb_data
) != 0) {
1063 nfs_set_error(nfs
, "nfs_link_async failed");
1067 wait_for_reply(nfs_get_rpc_context(nfs
), &cb_data
);
1069 return cb_data
.status
;
1072 void mount_getexports_cb(struct rpc_context
*mount_context
, int status
, void *data
, void *private_data
)
1074 struct sync_cb_data
*cb_data
= private_data
;
1075 exports export
= *(exports
*)data
;
1077 cb_data
->is_finished
= 1;
1078 cb_data
->status
= status
;
1079 cb_data
->return_data
= NULL
;
1082 rpc_set_error(mount_context
, "mount/export call failed with \"%s\"", (char *)data
);
1086 while (export
!= NULL
) {
1089 new_export
= malloc(sizeof(*new_export
));
1090 memset(new_export
, 0, sizeof(*new_export
));
1091 new_export
->ex_dir
= strdup(export
->ex_dir
);
1092 new_export
->ex_next
= cb_data
->return_data
;
1094 cb_data
->return_data
= new_export
;
1096 export
= export
->ex_next
;
1100 struct exportnode
*mount_getexports(const char *server
)
1102 struct sync_cb_data cb_data
;
1103 struct rpc_context
*rpc
;
1106 cb_data
.is_finished
= 0;
1107 cb_data
.return_data
= NULL
;
1109 rpc
= rpc_init_context();
1110 if (mount_getexports_async(rpc
, server
, mount_getexports_cb
, &cb_data
) != 0) {
1111 rpc_destroy_context(rpc
);
1115 wait_for_reply(rpc
, &cb_data
);
1116 rpc_destroy_context(rpc
);
1118 return cb_data
.return_data
;
1121 void mount_free_export_list(struct exportnode
*exports
)
1123 struct exportnode
*tmp
;
1125 while ((tmp
= exports
)) {
1126 exports
= exports
->ex_next
;