Add a high-level async function to read the export list
[deb_libnfs.git] / lib / libnfs-sync.c
CommitLineData
84004dbf
RS
1/*
2 Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
3
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.
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 Lesser General Public License for more details.
13
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/>.
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 "libnfs.h"
33#include "libnfs-raw.h"
34#include "libnfs-raw-mount.h"
35#include "libnfs-raw-nfs.h"
1896d37b 36#include "libnfs-private.h"
84004dbf
RS
37
38struct sync_cb_data {
39 int is_finished;
40 int status;
41 off_t offset;
42 void *return_data;
43 int return_int;
44};
45
46
47static 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) {
1896d37b 59 nfs_set_error(nfs, "Poll failed");
84004dbf
RS
60 cb_data->status = -EIO;
61 break;
62 }
63 if (nfs_service(nfs, pfd.revents) < 0) {
1896d37b 64 nfs_set_error(nfs, "nfs_service failed");
84004dbf
RS
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 */
1896d37b 79static void mount_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 87 nfs_set_error(nfs, "mount/mnt call failed with \"%s\"", (char *)data);
84004dbf
RS
88 return;
89 }
90}
91
e2ba5764 92int nfs_mount(struct nfs_context *nfs, const char *server, const char *export)
84004dbf
RS
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) {
1896d37b 99 nfs_set_error(nfs, "nfs_mount_async failed");
84004dbf
RS
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 */
1896d37b 112static void stat_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 120 nfs_set_error(nfs, "stat call failed with \"%s\"", (char *)data);
84004dbf
RS
121 return;
122 }
123
124 memcpy(cb_data->return_data, data, sizeof(struct stat));
125}
126
e2ba5764 127int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st)
84004dbf
RS
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) {
1896d37b 135 nfs_set_error(nfs, "nfs_stat_async failed");
84004dbf
RS
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 */
1896d37b 150static void open_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 159 nfs_set_error(nfs, "open call failed with \"%s\"", (char *)data);
84004dbf
RS
160 return;
161 }
162
163 fh = data;
164 nfsfh = cb_data->return_data;
165 *nfsfh = fh;
166}
167
e2ba5764 168int nfs_open(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh)
84004dbf
RS
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) {
1896d37b 176 nfs_set_error(nfs, "nfs_open_async failed");
84004dbf
RS
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 */
1896d37b 191static void pread_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 199 nfs_set_error(nfs, "pread call failed with \"%s\"", (char *)data);
84004dbf
RS
200 return;
201 }
202
203 buffer = cb_data->return_data;
204 memcpy(buffer, (char *)data, status);
205}
206
e2ba5764 207int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buffer)
84004dbf
RS
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) {
1896d37b 215 nfs_set_error(nfs, "nfs_pread_async failed");
84004dbf
RS
216 return -1;
217 }
218
219 wait_for_reply(nfs, &cb_data);
220
221 return cb_data.status;
222}
223
224/*
225 * read()
226 */
e2ba5764 227int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buffer)
84004dbf 228{
e2ba5764 229 return nfs_pread(nfs, nfsfh, nfs_get_current_offset(nfsfh), count, buffer);
84004dbf
RS
230}
231
232/*
233 * close()
234 */
1896d37b 235static void close_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 242 nfs_set_error(nfs, "close call failed with \"%s\"", (char *)data);
84004dbf
RS
243 return;
244 }
245}
246
e2ba5764 247int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh)
84004dbf
RS
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) {
1896d37b 254 nfs_set_error(nfs, "nfs_close_async failed");
84004dbf
RS
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 */
e2ba5764 269int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st)
84004dbf
RS
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) {
1896d37b 277 nfs_set_error(nfs, "nfs_fstat_async failed");
84004dbf
RS
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 */
1896d37b 290static void pwrite_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 297 nfs_set_error(nfs, "pwrite call failed with \"%s\"", (char *)data);
84004dbf
RS
298 return;
299 }
300}
301
e2ba5764 302int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, size_t count, char *buf)
84004dbf
RS
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) {
1896d37b 309 nfs_set_error(nfs, "nfs_pwrite_async failed");
84004dbf
RS
310 return -1;
311 }
312
313 wait_for_reply(nfs, &cb_data);
314
315 return cb_data.status;
316}
317
318/*
319 * write()
320 */
e2ba5764 321int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, size_t count, char *buf)
84004dbf 322{
e2ba5764 323 return nfs_pwrite(nfs, nfsfh, nfs_get_current_offset(nfsfh), count, buf);
84004dbf
RS
324}
325
326
327/*
328 * fsync()
329 */
1896d37b 330static void fsync_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 337 nfs_set_error(nfs, "fsync call failed with \"%s\"", (char *)data);
84004dbf
RS
338 return;
339 }
340}
341
e2ba5764 342int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh)
84004dbf
RS
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) {
1896d37b 349 nfs_set_error(nfs, "nfs_fsync_async failed");
84004dbf
RS
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 */
1896d37b 364static void ftruncate_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 371 nfs_set_error(nfs, "ftruncate call failed with \"%s\"", (char *)data);
84004dbf
RS
372 return;
373 }
374}
375
e2ba5764 376int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t length)
84004dbf
RS
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) {
1896d37b 383 nfs_set_error(nfs, "nfs_ftruncate_async failed");
84004dbf
RS
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 */
1896d37b 397static void truncate_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 404 nfs_set_error(nfs, "truncate call failed with \"%s\"", (char *)data);
84004dbf
RS
405 return;
406 }
407}
408
e2ba5764 409int nfs_truncate(struct nfs_context *nfs, const char *path, off_t length)
84004dbf
RS
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) {
1896d37b 416 nfs_set_error(nfs, "nfs_ftruncate_async failed");
84004dbf
RS
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 */
1896d37b 432static void mkdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 439 nfs_set_error(nfs, "mkdir call failed with \"%s\"", (char *)data);
84004dbf
RS
440 return;
441 }
442}
443
e2ba5764 444int nfs_mkdir(struct nfs_context *nfs, const char *path)
84004dbf
RS
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) {
1896d37b 451 nfs_set_error(nfs, "nfs_mkdir_async failed");
84004dbf
RS
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 */
1896d37b 467static void rmdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 474 nfs_set_error(nfs, "rmdir call failed with \"%s\"", (char *)data);
84004dbf
RS
475 return;
476 }
477}
478
e2ba5764 479int nfs_rmdir(struct nfs_context *nfs, const char *path)
84004dbf
RS
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) {
1896d37b 486 nfs_set_error(nfs, "nfs_rmdir_async failed");
84004dbf
RS
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 */
1896d37b 500static void creat_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 509 nfs_set_error(nfs, "creat call failed with \"%s\"", (char *)data);
84004dbf
RS
510 return;
511 }
512
513 fh = data;
514 nfsfh = cb_data->return_data;
515 *nfsfh = fh;
516}
517
e2ba5764 518int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh)
84004dbf
RS
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) {
1896d37b 526 nfs_set_error(nfs, "nfs_creat_async failed");
84004dbf
RS
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 */
1896d37b 541static void unlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 549 nfs_set_error(nfs, "unlink call failed with \"%s\"", (char *)data);
84004dbf
RS
550 return;
551 }
552}
553
e2ba5764 554int nfs_unlink(struct nfs_context *nfs, const char *path)
84004dbf
RS
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) {
1896d37b 561 nfs_set_error(nfs, "nfs_unlink_async failed");
84004dbf
RS
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 */
1896d37b 575static void opendir_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 584 nfs_set_error(nfs, "opendir call failed with \"%s\"", (char *)data);
84004dbf
RS
585 return;
586 }
587
588 dir = data;
589 nfsdir = cb_data->return_data;
590 *nfsdir = dir;
591}
592
e2ba5764 593int nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir)
84004dbf
RS
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) {
1896d37b 601 nfs_set_error(nfs, "nfs_opendir_async failed");
84004dbf
RS
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 */
1896d37b 614static void lseek_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 622 nfs_set_error(nfs, "lseek call failed with \"%s\"", (char *)data);
84004dbf
RS
623 return;
624 }
625
626 if (cb_data->return_data != NULL) {
627 memcpy(cb_data->return_data, data, sizeof(off_t));
628 }
629}
630
e2ba5764 631int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, off_t offset, int whence, off_t *current_offset)
84004dbf
RS
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) {
1896d37b 639 nfs_set_error(nfs, "nfs_lseek_async failed");
84004dbf
RS
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 */
1896d37b 653static void statvfs_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 661 nfs_set_error(nfs, "statvfs call failed with \"%s\"", (char *)data);
84004dbf
RS
662 return;
663 }
664
665 memcpy(cb_data->return_data, data, sizeof(struct statvfs));
666}
667
e2ba5764 668int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs)
84004dbf
RS
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) {
1896d37b 676 nfs_set_error(nfs, "nfs_statvfs_async failed");
84004dbf
RS
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 */
1896d37b 692static void readlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 700 nfs_set_error(nfs, "readlink call failed with \"%s\"", (char *)data);
84004dbf
RS
701 return;
702 }
703
704 if (strlen(data) > (size_t)cb_data->return_int) {
1896d37b 705 nfs_set_error(nfs, "Too small buffer for readlink");
84004dbf
RS
706 cb_data->status = -ENAMETOOLONG;
707 return;
708 }
709
710 memcpy(cb_data->return_data, data, strlen(data)+1);
711}
712
e2ba5764 713int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize)
84004dbf
RS
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) {
1896d37b 722 nfs_set_error(nfs, "nfs_readlink_async failed");
84004dbf
RS
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 */
1896d37b 736static void chmod_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 744 nfs_set_error(nfs, "chmod call failed with \"%s\"", (char *)data);
84004dbf
RS
745 return;
746 }
747}
748
e2ba5764 749int nfs_chmod(struct nfs_context *nfs, const char *path, int mode)
84004dbf
RS
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) {
1896d37b 756 nfs_set_error(nfs, "nfs_chmod_async failed");
84004dbf
RS
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 */
1896d37b 771static void fchmod_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 779 nfs_set_error(nfs, "fchmod call failed with \"%s\"", (char *)data);
84004dbf
RS
780 return;
781 }
782}
783
e2ba5764 784int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode)
84004dbf
RS
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) {
1896d37b 791 nfs_set_error(nfs, "nfs_fchmod_async failed");
84004dbf
RS
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 */
1896d37b 806static void chown_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 814 nfs_set_error(nfs, "chown call failed with \"%s\"", (char *)data);
84004dbf
RS
815 return;
816 }
817}
818
e2ba5764 819int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid)
84004dbf
RS
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) {
1896d37b 826 nfs_set_error(nfs, "nfs_chown_async failed");
84004dbf
RS
827 return -1;
828 }
829
830 wait_for_reply(nfs, &cb_data);
831
832 return cb_data.status;
833}
834
835/*
836 * fchown()
837 */
1896d37b 838static void fchown_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 846 nfs_set_error(nfs, "fchown call failed with \"%s\"", (char *)data);
84004dbf
RS
847 return;
848 }
849}
850
e2ba5764 851int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid)
84004dbf
RS
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) {
1896d37b 858 nfs_set_error(nfs, "nfs_fchown_async failed");
84004dbf
RS
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 */
1896d37b 872static void utimes_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 880 nfs_set_error(nfs, "utimes call failed with \"%s\"", (char *)data);
84004dbf
RS
881 return;
882 }
883}
884
e2ba5764 885int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times)
84004dbf
RS
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) {
1896d37b 892 nfs_set_error(nfs, "nfs_utimes_async failed");
84004dbf
RS
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 */
1896d37b 906static void utime_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 914 nfs_set_error(nfs, "utime call failed with \"%s\"", (char *)data);
84004dbf
RS
915 return;
916 }
917}
918
e2ba5764 919int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times)
84004dbf
RS
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) {
1896d37b 926 nfs_set_error(nfs, "nfs_utimes_async failed");
84004dbf
RS
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 */
1896d37b 941static void access_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 949 nfs_set_error(nfs, "access call failed with \"%s\"", (char *)data);
84004dbf
RS
950 return;
951 }
952}
953
e2ba5764 954int nfs_access(struct nfs_context *nfs, const char *path, int mode)
84004dbf
RS
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) {
1896d37b 961 nfs_set_error(nfs, "nfs_access_async failed");
84004dbf
RS
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 */
1896d37b 975static void symlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 983 nfs_set_error(nfs, "symlink call failed with \"%s\"", (char *)data);
84004dbf
RS
984 return;
985 }
986}
987
e2ba5764 988int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath)
84004dbf
RS
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) {
1896d37b 995 nfs_set_error(nfs, "nfs_symlink_async failed");
84004dbf
RS
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 */
1896d37b 1009static void rename_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 1017 nfs_set_error(nfs, "rename call failed with \"%s\"", (char *)data);
84004dbf
RS
1018 return;
1019 }
1020}
1021
e2ba5764 1022int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath)
84004dbf
RS
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) {
1896d37b 1029 nfs_set_error(nfs, "nfs_rename_async failed");
84004dbf
RS
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 */
1896d37b 1043static void link_cb(int status, struct nfs_context *nfs, void *data, void *private_data)
84004dbf
RS
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) {
1896d37b 1051 nfs_set_error(nfs, "link call failed with \"%s\"", (char *)data);
84004dbf
RS
1052 return;
1053 }
1054}
1055
e2ba5764 1056int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath)
84004dbf
RS
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) {
1896d37b 1063 nfs_set_error(nfs, "nfs_link_async failed");
84004dbf
RS
1064 return -1;
1065 }
1066
1067 wait_for_reply(nfs, &cb_data);
1068
1069 return cb_data.status;
1070}