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