Merge branch 'ronnie'
[ccan] / ccan / nfs / libnfs-sync.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  * High level api to nfs filesystems
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <strings.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/statvfs.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <poll.h>
32 #include "nfs.h"
33 #include "libnfs-raw.h"
34 #include "rpc/mount.h"
35 #include "rpc/nfs.h"
36
37 struct sync_cb_data {
38        int is_finished;
39        int status;
40        off_t offset;
41        void *return_data;
42        int return_int;
43 };
44
45
46 static void wait_for_reply(struct nfs_context *nfs, struct sync_cb_data *cb_data)
47 {
48         struct pollfd pfd;
49
50         for (;;) {
51                 if (cb_data->is_finished) {
52                         break;
53                 }
54                 pfd.fd = nfs_get_fd(nfs);
55                 pfd.events = nfs_which_events(nfs);
56
57                 if (poll(&pfd, 1, -1) < 0) {
58                         printf("Poll failed");
59                         cb_data->status = -EIO;
60                         break;
61                 }
62                 if (nfs_service(nfs, pfd.revents) < 0) {
63                         printf("nfs_service failed\n");
64                         cb_data->status = -EIO;
65                         break;
66                 }
67         }
68 }
69
70
71
72
73
74
75 /*
76  * connect to the server and mount the export
77  */
78 static void mount_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
79 {
80         struct sync_cb_data *cb_data = private_data;
81
82         cb_data->is_finished = 1;
83         cb_data->status = status;
84
85         if (status < 0) {
86                 printf("mount/mnt call failed with \"%s\"\n", (char *)data);
87                 return;
88         }
89 }
90
91 int nfs_mount_sync(struct nfs_context *nfs, const char *server, const char *export)
92 {
93         struct sync_cb_data cb_data;
94
95         cb_data.is_finished = 0;
96
97         if (nfs_mount_async(nfs, server, export, mount_cb, &cb_data) != 0) {
98                 printf("nfs_mount_async failed\n");
99                 return -1;
100         }
101
102         wait_for_reply(nfs, &cb_data);
103
104         return cb_data.status;
105 }
106
107
108 /*
109  * stat()
110  */
111 static void stat_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
112 {
113         struct sync_cb_data *cb_data = private_data;
114
115         cb_data->is_finished = 1;
116         cb_data->status = status;
117
118         if (status < 0) {
119                 printf("stat call failed with \"%s\"\n", (char *)data);
120                 return;
121         }
122
123         memcpy(cb_data->return_data, data, sizeof(struct stat));
124 }
125
126 int nfs_stat_sync(struct nfs_context *nfs, const char *path, struct stat *st)
127 {
128         struct sync_cb_data cb_data;
129
130         cb_data.is_finished = 0;
131         cb_data.return_data = st;
132
133         if (nfs_stat_async(nfs, path, stat_cb, &cb_data) != 0) {
134                 printf("nfs_stat_async failed\n");
135                 return -1;
136         }
137
138         wait_for_reply(nfs, &cb_data);
139
140         return cb_data.status;
141 }
142
143
144
145
146 /*
147  * open()
148  */
149 static void open_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
150 {
151         struct sync_cb_data *cb_data = private_data;
152         struct nfsfh *fh, **nfsfh;
153
154         cb_data->is_finished = 1;
155         cb_data->status = status;
156
157         if (status < 0) {
158                 printf("open call failed with \"%s\"\n", (char *)data);
159                 return;
160         }
161
162         fh    = data;
163         nfsfh = cb_data->return_data;
164         *nfsfh = fh;
165 }
166
167 int nfs_open_sync(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh)
168 {
169         struct sync_cb_data cb_data;
170
171         cb_data.is_finished = 0;
172         cb_data.return_data = nfsfh;
173
174         if (nfs_open_async(nfs, path, mode, open_cb, &cb_data) != 0) {
175                 printf("nfs_open_async failed\n");
176                 return -1;
177         }
178
179         wait_for_reply(nfs, &cb_data);
180
181         return cb_data.status;
182 }
183
184
185
186
187 /*
188  * pread()
189  */
190 static void pread_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
191 {
192         struct sync_cb_data *cb_data = private_data;
193         char *buffer;
194         cb_data->is_finished = 1;
195         cb_data->status = status;
196
197         if (status < 0) {
198                 printf("pread call failed with \"%s\"\n", (char *)data);
199                 return;
200         }
201
202         buffer = cb_data->return_data;
203         memcpy(buffer, (char *)data, status);
204 }
205
206 int nfs_pread_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buffer)
207 {
208         struct sync_cb_data cb_data;
209
210         cb_data.is_finished = 0;
211         cb_data.return_data = buffer;
212
213         if (nfs_pread_async(nfs, nfsfh, offset, count, pread_cb, &cb_data) != 0) {
214                 printf("nfs_pread_async failed\n");
215                 return -1;
216         }
217
218         wait_for_reply(nfs, &cb_data);
219
220         return cb_data.status;
221 }
222
223 /*
224  * read()
225  */
226 int nfs_read_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buffer)
227 {
228         return nfs_pread_sync(nfs, nfsfh, nfs_get_current_offset(nfsfh), count, buffer);
229 }
230
231 /*
232  * close()
233  */
234 static void close_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
235 {
236         struct sync_cb_data *cb_data = private_data;
237         cb_data->is_finished = 1;
238         cb_data->status = status;
239
240         if (status < 0) {
241                 printf("close call failed with \"%s\"\n", (char *)data);
242                 return;
243         }
244 }
245
246 int nfs_close_sync(struct nfs_context *nfs, struct nfsfh *nfsfh)
247 {
248         struct sync_cb_data cb_data;
249
250         cb_data.is_finished = 0;
251
252         if (nfs_close_async(nfs, nfsfh, close_cb, &cb_data) != 0) {
253                 printf("nfs_close_async failed\n");
254                 return -1;
255         }
256
257         wait_for_reply(nfs, &cb_data);
258
259         return cb_data.status;
260 }
261
262
263
264
265 /*
266  * fstat()
267  */
268 int nfs_fstat_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st)
269 {
270         struct sync_cb_data cb_data;
271
272         cb_data.is_finished = 0;
273         cb_data.return_data = st;
274
275         if (nfs_fstat_async(nfs, nfsfh, stat_cb, &cb_data) != 0) {
276                 printf("nfs_fstat_async failed\n");
277                 return -1;
278         }
279
280         wait_for_reply(nfs, &cb_data);
281
282         return cb_data.status;
283 }
284
285
286 /*
287  * pwrite()
288  */
289 static void pwrite_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
290 {
291         struct sync_cb_data *cb_data = private_data;
292         cb_data->is_finished = 1;
293         cb_data->status = status;
294
295         if (status < 0) {
296                 printf("pwrite call failed with \"%s\"\n", (char *)data);
297                 return;
298         }
299 }
300
301 int nfs_pwrite_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf)
302 {
303         struct sync_cb_data cb_data;
304
305         cb_data.is_finished = 0;
306
307         if (nfs_pwrite_async(nfs, nfsfh, offset, count, buf, pwrite_cb, &cb_data) != 0) {
308                 printf("nfs_pwrite_async failed\n");
309                 return -1;
310         }
311
312         wait_for_reply(nfs, &cb_data);
313
314         return cb_data.status;
315 }
316
317 /*
318  * write()
319  */
320 int nfs_write_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf)
321 {
322         return nfs_pwrite_sync(nfs, nfsfh, nfs_get_current_offset(nfsfh), count, buf);
323 }
324
325
326 /*
327  * fsync()
328  */
329 static void fsync_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
330 {
331         struct sync_cb_data *cb_data = private_data;
332         cb_data->is_finished = 1;
333         cb_data->status = status;
334
335         if (status < 0) {
336                 printf("fsync call failed with \"%s\"\n", (char *)data);
337                 return;
338         }
339 }
340
341 int nfs_fsync_sync(struct nfs_context *nfs, struct nfsfh *nfsfh)
342 {
343         struct sync_cb_data cb_data;
344
345         cb_data.is_finished = 0;
346
347         if (nfs_fsync_async(nfs, nfsfh, fsync_cb, &cb_data) != 0) {
348                 printf("nfs_fsync_async failed\n");
349                 return -1;
350         }
351
352         wait_for_reply(nfs, &cb_data);
353
354         return cb_data.status;
355 }
356
357
358
359
360 /*
361  * ftruncate()
362  */
363 static void ftruncate_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
364 {
365         struct sync_cb_data *cb_data = private_data;
366         cb_data->is_finished = 1;
367         cb_data->status = status;
368
369         if (status < 0) {
370                 printf("ftruncate call failed with \"%s\"\n", (char *)data);
371                 return;
372         }
373 }
374
375 int nfs_ftruncate_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length)
376 {
377         struct sync_cb_data cb_data;
378
379         cb_data.is_finished = 0;
380
381         if (nfs_ftruncate_async(nfs, nfsfh, length, ftruncate_cb, &cb_data) != 0) {
382                 printf("nfs_ftruncate_async failed\n");
383                 return -1;
384         }
385
386         wait_for_reply(nfs, &cb_data);
387
388         return cb_data.status;
389 }
390
391
392
393 /*
394  * truncate()
395  */
396 static void truncate_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
397 {
398         struct sync_cb_data *cb_data = private_data;
399         cb_data->is_finished = 1;
400         cb_data->status = status;
401
402         if (status < 0) {
403                 printf("truncate call failed with \"%s\"\n", (char *)data);
404                 return;
405         }
406 }
407
408 int nfs_truncate_sync(struct nfs_context *nfs, const char *path, off_t length)
409 {
410         struct sync_cb_data cb_data;
411
412         cb_data.is_finished = 0;
413
414         if (nfs_truncate_async(nfs, path, length, truncate_cb, &cb_data) != 0) {
415                 printf("nfs_ftruncate_async failed\n");
416                 return -1;
417         }
418
419         wait_for_reply(nfs, &cb_data);
420
421         return cb_data.status;
422 }
423
424
425
426
427
428 /*
429  * mkdir()
430  */
431 static void mkdir_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
432 {
433         struct sync_cb_data *cb_data = private_data;
434         cb_data->is_finished = 1;
435         cb_data->status = status;
436
437         if (status < 0) {
438                 printf("mkdir call failed with \"%s\"\n", (char *)data);
439                 return;
440         }
441 }
442
443 int nfs_mkdir_sync(struct nfs_context *nfs, const char *path)
444 {
445         struct sync_cb_data cb_data;
446
447         cb_data.is_finished = 0;
448
449         if (nfs_mkdir_async(nfs, path, mkdir_cb, &cb_data) != 0) {
450                 printf("nfs_mkdir_async failed\n");
451                 return -1;
452         }
453
454         wait_for_reply(nfs, &cb_data);
455
456         return cb_data.status;
457 }
458
459
460
461
462
463 /*
464  * rmdir()
465  */
466 static void rmdir_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
467 {
468         struct sync_cb_data *cb_data = private_data;
469         cb_data->is_finished = 1;
470         cb_data->status = status;
471
472         if (status < 0) {
473                 printf("rmdir call failed with \"%s\"\n", (char *)data);
474                 return;
475         }
476 }
477
478 int nfs_rmdir_sync(struct nfs_context *nfs, const char *path)
479 {
480         struct sync_cb_data cb_data;
481
482         cb_data.is_finished = 0;
483
484         if (nfs_rmdir_async(nfs, path, rmdir_cb, &cb_data) != 0) {
485                 printf("nfs_rmdir_async failed\n");
486                 return -1;
487         }
488
489         wait_for_reply(nfs, &cb_data);
490
491         return cb_data.status;
492 }
493
494
495
496 /*
497  * creat()
498  */
499 static void creat_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
500 {
501         struct sync_cb_data *cb_data = private_data;
502         struct nfsfh *fh, **nfsfh;
503
504         cb_data->is_finished = 1;
505         cb_data->status = status;
506
507         if (status < 0) {
508                 printf("creat call failed with \"%s\"\n", (char *)data);
509                 return;
510         }
511
512         fh    = data;
513         nfsfh = cb_data->return_data;
514         *nfsfh = fh;
515 }
516
517 int nfs_creat_sync(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh)
518 {
519         struct sync_cb_data cb_data;
520
521         cb_data.is_finished = 0;
522         cb_data.return_data = nfsfh;
523
524         if (nfs_creat_async(nfs, path, mode, creat_cb, &cb_data) != 0) {
525                 printf("nfs_creat_async failed\n");
526                 return -1;
527         }
528
529         wait_for_reply(nfs, &cb_data);
530
531         return cb_data.status;
532 }
533
534
535
536
537 /*
538  * unlink()
539  */
540 static void unlink_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
541 {
542         struct sync_cb_data *cb_data = private_data;
543
544         cb_data->is_finished = 1;
545         cb_data->status = status;
546
547         if (status < 0) {
548                 printf("unlink call failed with \"%s\"\n", (char *)data);
549                 return;
550         }
551 }
552
553 int nfs_unlink_sync(struct nfs_context *nfs, const char *path)
554 {
555         struct sync_cb_data cb_data;
556
557         cb_data.is_finished = 0;
558
559         if (nfs_unlink_async(nfs, path, unlink_cb, &cb_data) != 0) {
560                 printf("nfs_unlink_async failed\n");
561                 return -1;
562         }
563
564         wait_for_reply(nfs, &cb_data);
565
566         return cb_data.status;
567 }
568
569
570
571 /*
572  * opendir()
573  */
574 static void opendir_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
575 {
576         struct sync_cb_data *cb_data = private_data;
577         struct nfsdir *dir, **nfsdir;
578
579         cb_data->is_finished = 1;
580         cb_data->status = status;
581
582         if (status < 0) {
583                 printf("opendir call failed with \"%s\"\n", (char *)data);
584                 return;
585         }
586
587         dir     = data;
588         nfsdir  = cb_data->return_data;
589         *nfsdir = dir;
590 }
591
592 int nfs_opendir_sync(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir)
593 {
594         struct sync_cb_data cb_data;
595
596         cb_data.is_finished = 0;
597         cb_data.return_data = nfsdir;
598
599         if (nfs_opendir_async(nfs, path, opendir_cb, &cb_data) != 0) {
600                 printf("nfs_opendir_async failed\n");
601                 return -1;
602         }
603
604         wait_for_reply(nfs, &cb_data);
605
606         return cb_data.status;
607 }
608
609
610 /*
611  * lseek()
612  */
613 static void lseek_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
614 {
615         struct sync_cb_data *cb_data = private_data;
616
617         cb_data->is_finished = 1;
618         cb_data->status = status;
619
620         if (status < 0) {
621                 printf("lseek call failed with \"%s\"\n", (char *)data);
622                 return;
623         }
624
625         if (cb_data->return_data != NULL) {
626                 memcpy(cb_data->return_data, data, sizeof(off_t));
627         }
628 }
629
630 int nfs_lseek_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, off_t *current_offset)
631 {
632         struct sync_cb_data cb_data;
633
634         cb_data.is_finished = 0;
635         cb_data.return_data = current_offset;
636
637         if (nfs_lseek_async(nfs, nfsfh, offset, whence, lseek_cb, &cb_data) != 0) {
638                 printf("nfs_lseek_async failed\n");
639                 return -1;
640         }
641
642         wait_for_reply(nfs, &cb_data);
643
644         return cb_data.status;
645 }
646
647
648
649 /*
650  * statvfs()
651  */
652 static void statvfs_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
653 {
654         struct sync_cb_data *cb_data = private_data;
655
656         cb_data->is_finished = 1;
657         cb_data->status = status;
658
659         if (status < 0) {
660                 printf("statvfs call failed with \"%s\"\n", (char *)data);
661                 return;
662         }
663
664         memcpy(cb_data->return_data, data, sizeof(struct statvfs));
665 }
666
667 int nfs_statvfs_sync(struct nfs_context *nfs, const char *path, struct statvfs *svfs)
668 {
669         struct sync_cb_data cb_data;
670
671         cb_data.is_finished = 0;
672         cb_data.return_data = svfs;
673
674         if (nfs_statvfs_async(nfs, path, statvfs_cb, &cb_data) != 0) {
675                 printf("nfs_statvfs_async failed\n");
676                 return -1;
677         }
678
679         wait_for_reply(nfs, &cb_data);
680
681         return cb_data.status;
682 }
683
684
685
686
687
688 /*
689  * readlink()
690  */
691 static void readlink_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
692 {
693         struct sync_cb_data *cb_data = private_data;
694
695         cb_data->is_finished = 1;
696         cb_data->status = status;
697
698         if (status < 0) {
699                 printf("readlink call failed with \"%s\"\n", (char *)data);
700                 return;
701         }
702
703         if (strlen(data) > (size_t)cb_data->return_int) {
704                 printf("Too small buffer for readlink\n");
705                 cb_data->status = -ENAMETOOLONG;
706                 return;
707         }
708
709         memcpy(cb_data->return_data, data, strlen(data)+1);
710 }
711
712 int nfs_readlink_sync(struct nfs_context *nfs, const char *path, char *buf, int bufsize)
713 {
714         struct sync_cb_data cb_data;
715
716         cb_data.is_finished = 0;
717         cb_data.return_data = buf;
718         cb_data.return_int  = bufsize;
719
720         if (nfs_readlink_async(nfs, path, readlink_cb, &cb_data) != 0) {
721                 printf("nfs_readlink_async failed\n");
722                 return -1;
723         }
724
725         wait_for_reply(nfs, &cb_data);
726
727         return cb_data.status;
728 }
729
730
731
732 /*
733  * chmod()
734  */
735 static void chmod_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
736 {
737         struct sync_cb_data *cb_data = private_data;
738
739         cb_data->is_finished = 1;
740         cb_data->status = status;
741
742         if (status < 0) {
743                 printf("chmod call failed with \"%s\"\n", (char *)data);
744                 return;
745         }
746 }
747
748 int nfs_chmod_sync(struct nfs_context *nfs, const char *path, int mode)
749 {
750         struct sync_cb_data cb_data;
751
752         cb_data.is_finished = 0;
753
754         if (nfs_chmod_async(nfs, path, mode, chmod_cb, &cb_data) != 0) {
755                 printf("nfs_chmod_async failed\n");
756                 return -1;
757         }
758
759         wait_for_reply(nfs, &cb_data);
760
761         return cb_data.status;
762 }
763
764
765
766
767 /*
768  * fchmod()
769  */
770 static void fchmod_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
771 {
772         struct sync_cb_data *cb_data = private_data;
773
774         cb_data->is_finished = 1;
775         cb_data->status = status;
776
777         if (status < 0) {
778                 printf("fchmod call failed with \"%s\"\n", (char *)data);
779                 return;
780         }
781 }
782
783 int nfs_fchmod_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode)
784 {
785         struct sync_cb_data cb_data;
786
787         cb_data.is_finished = 0;
788
789         if (nfs_fchmod_async(nfs, nfsfh, mode, fchmod_cb, &cb_data) != 0) {
790                 printf("nfs_fchmod_async failed\n");
791                 return -1;
792         }
793
794         wait_for_reply(nfs, &cb_data);
795
796         return cb_data.status;
797 }
798
799
800
801
802 /*
803  * chown()
804  */
805 static void chown_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
806 {
807         struct sync_cb_data *cb_data = private_data;
808
809         cb_data->is_finished = 1;
810         cb_data->status = status;
811
812         if (status < 0) {
813                 printf("chown call failed with \"%s\"\n", (char *)data);
814                 return;
815         }
816 }
817
818 int nfs_chown_sync(struct nfs_context *nfs, const char *path, int uid, int gid)
819 {
820         struct sync_cb_data cb_data;
821
822         cb_data.is_finished = 0;
823
824         if (nfs_chown_async(nfs, path, uid, gid, chown_cb, &cb_data) != 0) {
825                 printf("nfs_chown_async failed\n");
826                 return -1;
827         }
828
829         wait_for_reply(nfs, &cb_data);
830
831         return cb_data.status;
832 }
833
834 /*
835  * fchown()
836  */
837 static void fchown_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
838 {
839         struct sync_cb_data *cb_data = private_data;
840
841         cb_data->is_finished = 1;
842         cb_data->status = status;
843
844         if (status < 0) {
845                 printf("fchown call failed with \"%s\"\n", (char *)data);
846                 return;
847         }
848 }
849
850 int nfs_fchown_sync(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid)
851 {
852         struct sync_cb_data cb_data;
853
854         cb_data.is_finished = 0;
855
856         if (nfs_fchown_async(nfs, nfsfh, uid, gid, fchown_cb, &cb_data) != 0) {
857                 printf("nfs_fchown_async failed\n");
858                 return -1;
859         }
860
861         wait_for_reply(nfs, &cb_data);
862
863         return cb_data.status;
864 }
865
866
867
868 /*
869  * utimes()
870  */
871 static void utimes_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
872 {
873         struct sync_cb_data *cb_data = private_data;
874
875         cb_data->is_finished = 1;
876         cb_data->status = status;
877
878         if (status < 0) {
879                 printf("utimes call failed with \"%s\"\n", (char *)data);
880                 return;
881         }
882 }
883
884 int nfs_utimes_sync(struct nfs_context *nfs, const char *path, struct timeval *times)
885 {
886         struct sync_cb_data cb_data;
887
888         cb_data.is_finished = 0;
889
890         if (nfs_utimes_async(nfs, path, times, utimes_cb, &cb_data) != 0) {
891                 printf("nfs_utimes_async failed\n");
892                 return -1;
893         }
894
895         wait_for_reply(nfs, &cb_data);
896
897         return cb_data.status;
898 }
899
900
901
902 /*
903  * utime()
904  */
905 static void utime_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
906 {
907         struct sync_cb_data *cb_data = private_data;
908
909         cb_data->is_finished = 1;
910         cb_data->status = status;
911
912         if (status < 0) {
913                 printf("utime call failed with \"%s\"\n", (char *)data);
914                 return;
915         }
916 }
917
918 int nfs_utime_sync(struct nfs_context *nfs, const char *path, struct utimbuf *times)
919 {
920         struct sync_cb_data cb_data;
921
922         cb_data.is_finished = 0;
923
924         if (nfs_utime_async(nfs, path, times, utime_cb, &cb_data) != 0) {
925                 printf("nfs_utimes_async failed\n");
926                 return -1;
927         }
928
929         wait_for_reply(nfs, &cb_data);
930
931         return cb_data.status;
932 }
933
934
935
936
937 /*
938  * access()
939  */
940 static void access_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
941 {
942         struct sync_cb_data *cb_data = private_data;
943
944         cb_data->is_finished = 1;
945         cb_data->status = status;
946
947         if (status < 0) {
948                 printf("access call failed with \"%s\"\n", (char *)data);
949                 return;
950         }
951 }
952
953 int nfs_access_sync(struct nfs_context *nfs, const char *path, int mode)
954 {
955         struct sync_cb_data cb_data;
956
957         cb_data.is_finished = 0;
958
959         if (nfs_access_async(nfs, path, mode, access_cb, &cb_data) != 0) {
960                 printf("nfs_access_async failed\n");
961                 return -1;
962         }
963
964         wait_for_reply(nfs, &cb_data);
965
966         return cb_data.status;
967 }
968
969
970
971 /*
972  * symlink()
973  */
974 static void symlink_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
975 {
976         struct sync_cb_data *cb_data = private_data;
977
978         cb_data->is_finished = 1;
979         cb_data->status = status;
980
981         if (status < 0) {
982                 printf("symlink call failed with \"%s\"\n", (char *)data);
983                 return;
984         }
985 }
986
987 int nfs_symlink_sync(struct nfs_context *nfs, const char *oldpath, const char *newpath)
988 {
989         struct sync_cb_data cb_data;
990
991         cb_data.is_finished = 0;
992
993         if (nfs_symlink_async(nfs, oldpath, newpath, symlink_cb, &cb_data) != 0) {
994                 printf("nfs_symlink_async failed\n");
995                 return -1;
996         }
997
998         wait_for_reply(nfs, &cb_data);
999
1000         return cb_data.status;
1001 }
1002
1003
1004
1005 /*
1006  * rename()
1007  */
1008 static void rename_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
1009 {
1010         struct sync_cb_data *cb_data = private_data;
1011
1012         cb_data->is_finished = 1;
1013         cb_data->status = status;
1014
1015         if (status < 0) {
1016                 printf("rename call failed with \"%s\"\n", (char *)data);
1017                 return;
1018         }
1019 }
1020
1021 int nfs_rename_sync(struct nfs_context *nfs, const char *oldpath, const char *newpath)
1022 {
1023         struct sync_cb_data cb_data;
1024
1025         cb_data.is_finished = 0;
1026
1027         if (nfs_rename_async(nfs, oldpath, newpath, rename_cb, &cb_data) != 0) {
1028                 printf("nfs_rename_async failed\n");
1029                 return -1;
1030         }
1031
1032         wait_for_reply(nfs, &cb_data);
1033
1034         return cb_data.status;
1035 }
1036
1037
1038
1039 /*
1040  * link()
1041  */
1042 static void link_cb(int status, struct nfs_context *nfs _U_, void *data, void *private_data)
1043 {
1044         struct sync_cb_data *cb_data = private_data;
1045
1046         cb_data->is_finished = 1;
1047         cb_data->status = status;
1048
1049         if (status < 0) {
1050                 printf("link call failed with \"%s\"\n", (char *)data);
1051                 return;
1052         }
1053 }
1054
1055 int nfs_link_sync(struct nfs_context *nfs, const char *oldpath, const char *newpath)
1056 {
1057         struct sync_cb_data cb_data;
1058
1059         cb_data.is_finished = 0;
1060
1061         if (nfs_link_async(nfs, oldpath, newpath, link_cb, &cb_data) != 0) {
1062                 printf("nfs_link_async failed\n");
1063                 return -1;
1064         }
1065
1066         wait_for_reply(nfs, &cb_data);
1067
1068         return cb_data.status;
1069 }