2017-06-26 08:42:17 +03:00
|
|
|
/* -*- mode:c; tab-width:8; c-basic-offset:8; indent-tabs-mode:nil; -*- */
|
2011-02-06 07:45:09 +03:00
|
|
|
/*
|
|
|
|
Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2.1 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Lesser General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
|
|
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* High level api to nfs filesystems
|
|
|
|
*/
|
2017-06-27 23:31:44 +03:00
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#endif
|
|
|
|
|
2013-04-14 21:11:48 +04:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2013-04-14 21:32:01 +04:00
|
|
|
#ifdef AROS
|
|
|
|
#include "aros_compat.h"
|
2013-04-14 21:11:48 +04:00
|
|
|
#endif
|
|
|
|
|
2021-09-10 05:01:31 +03:00
|
|
|
#ifdef PS2_EE
|
|
|
|
#include "ps2_compat.h"
|
|
|
|
#endif
|
|
|
|
|
2020-08-14 17:47:39 +03:00
|
|
|
#ifdef PS3_PPU
|
|
|
|
#include "ps3_compat.h"
|
|
|
|
#endif
|
|
|
|
|
2011-09-01 23:35:54 +04:00
|
|
|
#ifdef WIN32
|
2018-04-16 22:38:38 +03:00
|
|
|
#include <win32/win32_compat.h>
|
2017-02-26 21:14:30 +03:00
|
|
|
#endif
|
|
|
|
|
2013-05-29 04:54:12 +04:00
|
|
|
#ifdef HAVE_UTIME_H
|
2013-04-11 07:28:40 +04:00
|
|
|
#include <utime.h>
|
2013-05-29 04:54:12 +04:00
|
|
|
#endif
|
2013-04-11 07:28:40 +04:00
|
|
|
|
2013-04-14 21:32:01 +04:00
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_VFS_H
|
|
|
|
#include <sys/vfs.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_STATVFS_H
|
|
|
|
#include <sys/statvfs.h>
|
|
|
|
#endif
|
|
|
|
|
2016-03-11 02:09:16 +03:00
|
|
|
#if defined(__ANDROID__) && !defined(HAVE_SYS_STATVFS_H)
|
|
|
|
#define statvfs statfs
|
|
|
|
#endif
|
|
|
|
|
2013-05-29 04:38:37 +04:00
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#endif
|
|
|
|
|
2013-05-29 04:54:12 +04:00
|
|
|
#ifdef HAVE_STRINGS_H
|
|
|
|
#include <strings.h>
|
|
|
|
#endif
|
|
|
|
|
2017-05-10 00:30:14 +03:00
|
|
|
#ifdef HAVE_SYS_SYSMACROS_H
|
2014-07-21 00:39:06 +04:00
|
|
|
#include <sys/sysmacros.h>
|
|
|
|
#endif
|
|
|
|
|
2018-07-03 11:58:15 +03:00
|
|
|
#ifdef HAVE_SYS_TIME_H
|
|
|
|
#include <sys/time.h>
|
|
|
|
#endif
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
#include <errno.h>
|
2011-06-19 03:38:20 +04:00
|
|
|
#include <stdarg.h>
|
2011-02-06 07:45:09 +03:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2018-07-12 10:45:23 +03:00
|
|
|
#include <time.h>
|
2014-06-08 22:22:06 +04:00
|
|
|
#include "slist.h"
|
2011-02-06 07:45:09 +03:00
|
|
|
#include "libnfs.h"
|
|
|
|
#include "libnfs-raw.h"
|
|
|
|
#include "libnfs-raw-mount.h"
|
2014-03-17 04:48:35 +04:00
|
|
|
#include "libnfs-raw-portmap.h"
|
2011-06-19 03:38:20 +04:00
|
|
|
#include "libnfs-private.h"
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_free_nfsdir(struct nfsdir *nfsdir)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
while (nfsdir->entries) {
|
|
|
|
struct nfsdirent *dirent = nfsdir->entries->next;
|
|
|
|
if (nfsdir->entries->name != NULL) {
|
|
|
|
free(nfsdir->entries->name);
|
|
|
|
}
|
|
|
|
free(nfsdir->entries);
|
|
|
|
nfsdir->entries = dirent;
|
|
|
|
}
|
2017-06-27 23:31:44 +03:00
|
|
|
free(nfsdir->fh.val);
|
2011-02-06 07:45:09 +03:00
|
|
|
free(nfsdir);
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_dircache_add(struct nfs_context *nfs, struct nfsdir *nfsdir)
|
2014-06-08 22:22:06 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
int i = 0;
|
2014-06-08 22:22:06 +04:00
|
|
|
LIBNFS_LIST_ADD(&nfs->dircache, nfsdir);
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
for (nfsdir = nfs->dircache; nfsdir; nfsdir = nfsdir->next, i++) {
|
2014-06-08 22:22:06 +04:00
|
|
|
if (i > MAX_DIR_CACHE) {
|
|
|
|
LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir);
|
|
|
|
nfs_free_nfsdir(nfsdir);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
struct nfsdir *
|
|
|
|
nfs_dircache_find(struct nfs_context *nfs, struct nfs_fh *fh)
|
2014-06-08 22:22:06 +04:00
|
|
|
{
|
|
|
|
struct nfsdir *nfsdir;
|
|
|
|
|
|
|
|
for (nfsdir = nfs->dircache; nfsdir; nfsdir = nfsdir->next) {
|
2017-06-27 23:31:44 +03:00
|
|
|
if (nfsdir->fh.len == fh->len &&
|
|
|
|
!memcmp(nfsdir->fh.val, fh->val, fh->len)) {
|
2014-06-08 22:22:06 +04:00
|
|
|
LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir);
|
|
|
|
return nfsdir;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
|
|
|
nfs_dircache_drop(struct nfs_context *nfs, struct nfs_fh *fh)
|
2016-02-07 03:26:35 +03:00
|
|
|
{
|
|
|
|
struct nfsdir *cached;
|
|
|
|
|
|
|
|
cached = nfs_dircache_find(nfs, fh);
|
|
|
|
if (cached) {
|
|
|
|
nfs_free_nfsdir(cached);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static uint32_t
|
|
|
|
nfs_pagecache_hash(struct nfs_pagecache *pagecache, uint64_t offset) {
|
|
|
|
return (2654435761UL * (1 + ((uint32_t)(offset) / NFS_BLKSIZE))) &
|
|
|
|
(pagecache->num_entries - 1);
|
2016-05-13 13:03:40 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_pagecache_invalidate(struct nfs_context *nfs, struct nfsfh *nfsfh) {
|
2016-05-13 13:03:40 +03:00
|
|
|
if (nfsfh->pagecache.entries) {
|
|
|
|
RPC_LOG(nfs->rpc, 2, "invalidating pagecache");
|
2017-06-26 08:42:17 +03:00
|
|
|
memset(nfsfh->pagecache.entries, 0x00,
|
|
|
|
sizeof(struct nfs_pagecache_entry) *
|
|
|
|
nfsfh->pagecache.num_entries);
|
2016-05-13 13:03:40 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_pagecache_put(struct nfs_pagecache *pagecache, uint64_t offset,
|
2017-06-27 23:31:44 +03:00
|
|
|
const char *buf, size_t len)
|
|
|
|
{
|
2017-07-08 09:33:55 +03:00
|
|
|
time_t ts = pagecache->ttl ? (time_t)(rpc_current_time() / 1000) : 1;
|
2016-05-13 13:03:40 +03:00
|
|
|
if (!pagecache->num_entries) return;
|
|
|
|
while (len > 0) {
|
|
|
|
uint64_t page_offset = offset & ~(NFS_BLKSIZE - 1);
|
|
|
|
uint32_t entry = nfs_pagecache_hash(pagecache, page_offset);
|
|
|
|
struct nfs_pagecache_entry *e = &pagecache->entries[entry];
|
2016-09-20 23:57:56 +03:00
|
|
|
size_t n = MIN(NFS_BLKSIZE - offset % NFS_BLKSIZE, len);
|
2016-09-21 19:32:45 +03:00
|
|
|
|
2016-05-13 13:03:40 +03:00
|
|
|
/* we can only write to the cache if we add a full page or
|
|
|
|
* partially update a page that is still valid */
|
|
|
|
if (n == NFS_BLKSIZE ||
|
|
|
|
(e->ts && e->offset == page_offset &&
|
|
|
|
(!pagecache->ttl || ts - e->ts <= pagecache->ttl))) {
|
|
|
|
e->ts = ts;
|
|
|
|
e->offset = page_offset;
|
|
|
|
memcpy(e->buf + offset % NFS_BLKSIZE, buf, n);
|
|
|
|
}
|
|
|
|
buf += n;
|
|
|
|
offset += n;
|
|
|
|
len -= n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
char *
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_pagecache_get(struct nfs_pagecache *pagecache, uint64_t offset)
|
|
|
|
{
|
2016-09-20 22:35:46 +03:00
|
|
|
uint32_t entry;
|
|
|
|
struct nfs_pagecache_entry *e;
|
|
|
|
|
|
|
|
entry = nfs_pagecache_hash(pagecache, offset);
|
|
|
|
e = &pagecache->entries[entry];
|
|
|
|
|
|
|
|
if (offset != e->offset) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!e->ts) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-08 09:33:55 +03:00
|
|
|
if (pagecache->ttl && (time_t)(rpc_current_time() / 1000) - e->ts > pagecache->ttl) {
|
2017-05-11 04:11:00 +03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-05-13 13:03:40 +03:00
|
|
|
return e->buf;
|
|
|
|
}
|
|
|
|
|
2018-04-27 04:15:02 +03:00
|
|
|
void nfs_pagecache_init(struct nfs_context *nfs, struct nfsfh *nfsfh) {
|
|
|
|
/* init page cache */
|
|
|
|
if (nfs->rpc->pagecache) {
|
|
|
|
nfsfh->pagecache.num_entries = nfs->rpc->pagecache;
|
|
|
|
nfsfh->pagecache.ttl = nfs->rpc->pagecache_ttl;
|
|
|
|
nfsfh->pagecache.entries = malloc(sizeof(struct nfs_pagecache_entry) * nfsfh->pagecache.num_entries);
|
|
|
|
nfs_pagecache_invalidate(nfs, nfsfh);
|
|
|
|
RPC_LOG(nfs->rpc, 2, "init pagecache entries %d pagesize %d\n",
|
|
|
|
nfsfh->pagecache.num_entries, NFS_BLKSIZE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2011-08-28 13:25:20 +04:00
|
|
|
rpc_set_auth(nfs->rpc, auth);
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_get_fd(struct nfs_context *nfs)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
return rpc_get_fd(nfs->rpc);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_queue_length(struct nfs_context *nfs)
|
2011-09-11 15:32:48 +04:00
|
|
|
{
|
|
|
|
return rpc_queue_length(nfs->rpc);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_which_events(struct nfs_context *nfs)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
return rpc_which_events(nfs->rpc);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_service(struct nfs_context *nfs, int revents)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
return rpc_service(nfs->rpc, revents);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
char *
|
|
|
|
nfs_get_error(struct nfs_context *nfs)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
return rpc_get_error(nfs->rpc);
|
|
|
|
};
|
|
|
|
|
2016-07-29 20:25:39 +03:00
|
|
|
#ifdef HAVE_SO_BINDTODEVICE
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_interface(struct nfs_context *nfs, const char *ifname)
|
2016-07-29 20:25:39 +03:00
|
|
|
{
|
|
|
|
rpc_set_interface(nfs_get_rpc_context(nfs), ifname);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static int
|
|
|
|
nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val)
|
2013-12-26 04:57:52 +04:00
|
|
|
{
|
2014-06-23 18:31:32 +04:00
|
|
|
if (!strcmp(arg, "tcp-syncnt")) {
|
2013-12-26 21:08:26 +04:00
|
|
|
rpc_set_tcp_syncnt(nfs_get_rpc_context(nfs), atoi(val));
|
2014-06-23 18:31:32 +04:00
|
|
|
} else if (!strcmp(arg, "uid")) {
|
2013-12-26 21:08:26 +04:00
|
|
|
rpc_set_uid(nfs_get_rpc_context(nfs), atoi(val));
|
2014-06-23 18:31:32 +04:00
|
|
|
} else if (!strcmp(arg, "gid")) {
|
2013-12-26 21:08:26 +04:00
|
|
|
rpc_set_gid(nfs_get_rpc_context(nfs), atoi(val));
|
2014-12-05 19:44:15 +03:00
|
|
|
} else if (!strcmp(arg, "readahead")) {
|
2014-06-23 18:31:32 +04:00
|
|
|
rpc_set_readahead(nfs_get_rpc_context(nfs), atoi(val));
|
2016-05-13 13:03:40 +03:00
|
|
|
} else if (!strcmp(arg, "pagecache")) {
|
|
|
|
rpc_set_pagecache(nfs_get_rpc_context(nfs), atoi(val));
|
2015-06-23 09:52:59 +03:00
|
|
|
} else if (!strcmp(arg, "debug")) {
|
|
|
|
rpc_set_debug(nfs_get_rpc_context(nfs), atoi(val));
|
2015-01-17 22:49:08 +03:00
|
|
|
} else if (!strcmp(arg, "auto-traverse-mounts")) {
|
|
|
|
nfs->auto_traverse_mounts = atoi(val);
|
2016-02-08 03:06:00 +03:00
|
|
|
} else if (!strcmp(arg, "dircache")) {
|
|
|
|
nfs_set_dircache(nfs, atoi(val));
|
2017-05-10 07:43:31 +03:00
|
|
|
} else if (!strcmp(arg, "autoreconnect")) {
|
|
|
|
nfs_set_autoreconnect(nfs, atoi(val));
|
2016-07-29 20:25:39 +03:00
|
|
|
#ifdef HAVE_SO_BINDTODEVICE
|
|
|
|
} else if (!strcmp(arg, "if")) {
|
|
|
|
nfs_set_interface(nfs, val);
|
|
|
|
#endif
|
2017-06-25 03:58:47 +03:00
|
|
|
} else if (!strcmp(arg, "version")) {
|
|
|
|
if (nfs_set_version(nfs, atoi(val)) < 0) {
|
|
|
|
nfs_set_error(nfs, "NFS version %d is not supported",
|
|
|
|
atoi(val));
|
|
|
|
return -1;
|
|
|
|
}
|
2018-04-08 07:36:37 +03:00
|
|
|
} else if (!strcmp(arg, "nfsport")) {
|
|
|
|
nfs->nfsport = atoi(val);
|
|
|
|
} else if (!strcmp(arg, "mountport")) {
|
|
|
|
nfs->mountport = atoi(val);
|
2013-12-26 04:57:52 +04:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-01 01:17:23 +03:00
|
|
|
static int
|
|
|
|
tohex(char ch)
|
|
|
|
{
|
|
|
|
if (ch >= '0' && ch <= '9') {
|
|
|
|
return ch - '0';
|
|
|
|
}
|
|
|
|
ch &= 0xDF;
|
|
|
|
if (ch >= 'A' && ch <= 'F') {
|
|
|
|
return ch - 'A' + 10;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static struct nfs_url *
|
|
|
|
nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete)
|
2013-12-23 17:03:00 +04:00
|
|
|
{
|
|
|
|
struct nfs_url *urls;
|
2021-09-01 01:17:23 +03:00
|
|
|
char *strp, *flagsp, *strp2, ch;
|
|
|
|
int tmp;
|
2013-12-23 17:03:00 +04:00
|
|
|
|
|
|
|
if (strncmp(url, "nfs://", 6)) {
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Invalid URL specified");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
urls = malloc(sizeof(struct nfs_url));
|
|
|
|
if (urls == NULL) {
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Out of memory");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-26 15:48:21 +04:00
|
|
|
memset(urls, 0x00, sizeof(struct nfs_url));
|
2013-12-23 17:03:00 +04:00
|
|
|
urls->server = strdup(url + 6);
|
|
|
|
if (urls->server == NULL) {
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Out of memory");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-09-01 01:17:23 +03:00
|
|
|
/* unescape all % hex hex characters */
|
|
|
|
strp = urls->server;
|
|
|
|
while (strp && *strp) {
|
|
|
|
strp = strchr(strp, '%');
|
|
|
|
if (strp == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tmp = tohex(strp[1]);
|
|
|
|
if (tmp < 0) {
|
|
|
|
strp++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ch = (tmp & 0x0f) << 4;
|
|
|
|
tmp = tohex(strp[2]);
|
|
|
|
if (tmp < 0) {
|
|
|
|
strp++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ch |= tmp & 0x0f;
|
|
|
|
*strp = ch;
|
|
|
|
strcpy(strp + 1, strp + 3);
|
|
|
|
strp++;
|
|
|
|
}
|
|
|
|
|
2013-12-23 17:03:00 +04:00
|
|
|
if (urls->server[0] == '/' || urls->server[0] == '\0' ||
|
|
|
|
urls->server[0] == '?') {
|
|
|
|
if (incomplete) {
|
|
|
|
flagsp = strchr(urls->server, '?');
|
|
|
|
goto flags;
|
|
|
|
}
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Invalid server string");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
strp = strchr(urls->server, '/');
|
|
|
|
if (strp == NULL) {
|
|
|
|
if (incomplete) {
|
|
|
|
flagsp = strchr(urls->server, '?');
|
|
|
|
goto flags;
|
|
|
|
}
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Incomplete or invalid URL specified.");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
urls->path = strdup(strp);
|
|
|
|
if (urls->path == NULL) {
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Out of memory");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
*strp = 0;
|
|
|
|
|
2021-07-18 00:46:09 +03:00
|
|
|
strp = strchr(urls->server, ':');
|
|
|
|
if (strp) {
|
|
|
|
*strp++ = 0;
|
|
|
|
nfs->nfsport = atoi(strp);
|
|
|
|
}
|
|
|
|
|
2013-12-23 17:03:00 +04:00
|
|
|
if (dir) {
|
|
|
|
flagsp = strchr(urls->path, '?');
|
|
|
|
goto flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
strp = strrchr(urls->path, '/');
|
|
|
|
if (strp == NULL) {
|
|
|
|
if (incomplete) {
|
|
|
|
flagsp = strchr(urls->path, '?');
|
|
|
|
goto flags;
|
|
|
|
}
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Incomplete or invalid URL specified.");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
urls->file = strdup(strp);
|
|
|
|
if (urls->path == NULL) {
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Out of memory");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
*strp = 0;
|
|
|
|
flagsp = strchr(urls->file, '?');
|
|
|
|
|
|
|
|
flags:
|
|
|
|
if (flagsp) {
|
|
|
|
*flagsp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (urls->file && !strlen(urls->file)) {
|
|
|
|
free(urls->file);
|
|
|
|
urls->file = NULL;
|
|
|
|
if (!incomplete) {
|
|
|
|
nfs_destroy_url(urls);
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_set_error(nfs, "Incomplete or invalid URL "
|
|
|
|
"specified.");
|
2013-12-23 17:03:00 +04:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (flagsp != NULL && *(flagsp+1) != 0) {
|
|
|
|
strp = flagsp + 1;
|
|
|
|
flagsp = strchr(strp, '&');
|
|
|
|
if (flagsp) {
|
|
|
|
*flagsp = 0;
|
|
|
|
}
|
|
|
|
strp2 = strchr(strp, '=');
|
|
|
|
if (strp2) {
|
|
|
|
*strp2 = 0;
|
|
|
|
strp2++;
|
2013-12-26 21:08:26 +04:00
|
|
|
nfs_set_context_args(nfs, strp, strp2);
|
2013-12-23 17:03:00 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-26 13:43:15 +04:00
|
|
|
if (urls->server && strlen(urls->server) <= 1) {
|
|
|
|
free(urls->server);
|
|
|
|
urls->server = NULL;
|
|
|
|
}
|
|
|
|
|
2013-12-23 17:03:00 +04:00
|
|
|
return urls;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
struct nfs_url *
|
|
|
|
nfs_parse_url_full(struct nfs_context *nfs, const char *url)
|
2013-12-23 17:03:00 +04:00
|
|
|
{
|
|
|
|
return nfs_parse_url(nfs, url, 0, 0);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
struct nfs_url *
|
|
|
|
nfs_parse_url_dir(struct nfs_context *nfs, const char *url)
|
2013-12-23 17:03:00 +04:00
|
|
|
{
|
|
|
|
return nfs_parse_url(nfs, url, 1, 0);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
struct nfs_url *
|
|
|
|
nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url)
|
2013-12-23 17:03:00 +04:00
|
|
|
{
|
|
|
|
return nfs_parse_url(nfs, url, 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_destroy_url(struct nfs_url *url)
|
2013-12-23 17:03:00 +04:00
|
|
|
{
|
|
|
|
if (url) {
|
|
|
|
free(url->server);
|
|
|
|
free(url->path);
|
|
|
|
free(url->file);
|
|
|
|
}
|
|
|
|
free(url);
|
|
|
|
}
|
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
#define MAX_CLIENT_NAME 64
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
struct nfs_context *
|
|
|
|
nfs_init_context(void)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
struct nfs_context *nfs;
|
2017-07-06 00:15:51 +03:00
|
|
|
int i;
|
2017-07-08 05:58:31 +03:00
|
|
|
uint64_t v;
|
2017-07-06 00:15:51 +03:00
|
|
|
verifier4 verifier;
|
|
|
|
char client_name[MAX_CLIENT_NAME];
|
|
|
|
|
2011-02-06 07:45:09 +03:00
|
|
|
nfs = malloc(sizeof(struct nfs_context));
|
|
|
|
if (nfs == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-01-28 08:54:14 +04:00
|
|
|
memset(nfs, 0, sizeof(struct nfs_context));
|
|
|
|
|
2011-02-06 07:45:09 +03:00
|
|
|
nfs->rpc = rpc_init_context();
|
|
|
|
if (nfs->rpc == NULL) {
|
|
|
|
free(nfs);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-01-28 08:54:14 +04:00
|
|
|
nfs->cwd = strdup("/");
|
2014-12-10 01:00:15 +03:00
|
|
|
nfs->mask = 022;
|
2015-01-17 22:49:08 +03:00
|
|
|
nfs->auto_traverse_mounts = 1;
|
2016-02-08 03:06:00 +03:00
|
|
|
nfs->dircache_enabled = 1;
|
2017-05-30 03:21:13 +03:00
|
|
|
/* Default is never give up, never surrender */
|
|
|
|
nfs->auto_reconnect = -1;
|
2017-06-25 03:58:47 +03:00
|
|
|
nfs->version = NFS_V3;
|
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
/* NFSv4 parameters */
|
2017-07-08 05:58:31 +03:00
|
|
|
/* We need a "random" initial verifier */
|
|
|
|
v = rpc_current_time() << 32 | getpid();
|
2017-07-06 00:15:51 +03:00
|
|
|
for (i = 0; i < NFS4_VERIFIER_SIZE; i++) {
|
2017-07-08 05:58:31 +03:00
|
|
|
verifier[i] = v & 0xff;
|
|
|
|
v >>= 8;
|
2017-07-06 00:15:51 +03:00
|
|
|
}
|
|
|
|
nfs4_set_verifier(nfs, verifier);
|
|
|
|
|
|
|
|
snprintf(client_name, MAX_CLIENT_NAME, "Libnfs pid:%d %d", getpid(),
|
|
|
|
(int)time(NULL));
|
|
|
|
nfs4_set_client_name(nfs, client_name);
|
|
|
|
|
2011-02-06 07:45:09 +03:00
|
|
|
return nfs;
|
|
|
|
}
|
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
void
|
|
|
|
nfs4_set_client_name(struct nfs_context *nfs, const char *client_name)
|
|
|
|
{
|
|
|
|
nfs->client_name = strdup(client_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nfs4_set_verifier(struct nfs_context *nfs, const char *verifier)
|
|
|
|
{
|
|
|
|
memcpy(nfs->verifier, verifier, NFS4_VERIFIER_SIZE);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_destroy_context(struct nfs_context *nfs)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2015-01-17 22:19:13 +03:00
|
|
|
while (nfs->nested_mounts) {
|
|
|
|
struct nested_mounts *mnt = nfs->nested_mounts;
|
|
|
|
|
|
|
|
LIBNFS_LIST_REMOVE(&nfs->nested_mounts, mnt);
|
|
|
|
free(mnt->path);
|
2017-06-27 23:31:44 +03:00
|
|
|
free(mnt->fh.val);
|
2017-02-19 20:14:29 +03:00
|
|
|
free(mnt);
|
2015-01-17 22:19:13 +03:00
|
|
|
}
|
|
|
|
|
2011-02-06 07:45:09 +03:00
|
|
|
rpc_destroy_context(nfs->rpc);
|
|
|
|
nfs->rpc = NULL;
|
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
free(nfs->server);
|
|
|
|
nfs->server = NULL;
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
free(nfs->export);
|
|
|
|
nfs->export = NULL;
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
free(nfs->cwd);
|
|
|
|
nfs->cwd = NULL;
|
2014-01-28 08:54:14 +04:00
|
|
|
|
2017-07-06 00:15:51 +03:00
|
|
|
free(nfs->rootfh.val);
|
|
|
|
nfs->rootfh.len = 0;
|
|
|
|
nfs->rootfh.val = NULL;
|
|
|
|
|
|
|
|
free(nfs->client_name);
|
|
|
|
nfs->client_name = NULL;
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2014-06-08 22:22:06 +04:00
|
|
|
while (nfs->dircache) {
|
|
|
|
struct nfsdir *nfsdir = nfs->dircache;
|
|
|
|
LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir);
|
|
|
|
nfs_free_nfsdir(nfsdir);
|
|
|
|
}
|
|
|
|
|
2011-02-06 07:45:09 +03:00
|
|
|
free(nfs);
|
|
|
|
}
|
|
|
|
|
2013-10-27 00:16:09 +04:00
|
|
|
struct rpc_cb_data {
|
|
|
|
char *server;
|
|
|
|
uint32_t program;
|
|
|
|
uint32_t version;
|
|
|
|
|
|
|
|
rpc_cb cb;
|
|
|
|
void *private_data;
|
2014-01-01 04:11:11 +04:00
|
|
|
};
|
2013-10-27 00:16:09 +04:00
|
|
|
|
|
|
|
void free_rpc_cb_data(struct rpc_cb_data *data)
|
|
|
|
{
|
|
|
|
free(data->server);
|
|
|
|
data->server = NULL;
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
2018-04-08 07:36:37 +03:00
|
|
|
static int
|
|
|
|
rpc_connect_port_internal(struct rpc_context *rpc, int port, struct rpc_cb_data *data);
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
rpc_connect_program_5_cb(struct rpc_context *rpc, int status,
|
|
|
|
void *command_data, void *private_data)
|
2014-03-17 02:00:19 +04:00
|
|
|
{
|
|
|
|
struct rpc_cb_data *data = private_data;
|
|
|
|
|
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
|
|
|
/* Dont want any more callbacks even if the socket is closed */
|
|
|
|
rpc->connect_cb = NULL;
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2014-03-17 02:00:19 +04:00
|
|
|
data->cb(rpc, status, command_data, data->private_data);
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->cb(rpc, status, NULL, data->private_data);
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
rpc_connect_program_4_cb(struct rpc_context *rpc, int status,
|
|
|
|
void *command_data, void *private_data)
|
2013-10-27 00:16:09 +04:00
|
|
|
{
|
|
|
|
struct rpc_cb_data *data = private_data;
|
|
|
|
|
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
|
|
|
/* Dont want any more callbacks even if the socket is closed */
|
|
|
|
rpc->connect_cb = NULL;
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2013-10-27 00:16:09 +04:00
|
|
|
data->cb(rpc, status, command_data, data->private_data);
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-11-27 23:46:23 +03:00
|
|
|
if (rpc_null_async(rpc, data->program, data->version,
|
|
|
|
rpc_connect_program_5_cb, data) != 0) {
|
2018-02-03 09:50:06 +03:00
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data);
|
2016-11-27 23:46:23 +03:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
2013-10-27 00:16:09 +04:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
rpc_connect_program_3_cb(struct rpc_context *rpc, int status,
|
|
|
|
void *command_data, void *private_data)
|
2013-10-27 00:16:09 +04:00
|
|
|
{
|
|
|
|
struct rpc_cb_data *data = private_data;
|
2014-03-18 08:29:32 +04:00
|
|
|
struct pmap3_string_result *gar;
|
2014-03-17 04:48:35 +04:00
|
|
|
uint32_t rpc_port = 0;
|
2015-03-11 07:06:38 +03:00
|
|
|
char *ptr;
|
2013-10-27 00:16:09 +04:00
|
|
|
|
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2013-10-27 00:16:09 +04:00
|
|
|
data->cb(rpc, status, command_data, data->private_data);
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-17 04:48:35 +04:00
|
|
|
switch (rpc->s.ss_family) {
|
|
|
|
case AF_INET:
|
2016-06-02 04:14:01 +03:00
|
|
|
rpc_port = *(uint32_t *)(void *)command_data;
|
2014-03-17 04:48:35 +04:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
/* ouch. portmapper and ipv6 are not great */
|
|
|
|
gar = command_data;
|
|
|
|
if (gar->addr == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ptr = strrchr(gar->addr, '.');
|
|
|
|
if (ptr == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rpc_port = atoi(ptr + 1);
|
|
|
|
*ptr = 0;
|
|
|
|
ptr = strrchr(gar->addr, '.');
|
|
|
|
if (ptr == NULL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rpc_port += 256 * atoi(ptr + 1);
|
|
|
|
break;
|
|
|
|
}
|
2013-10-27 00:16:09 +04:00
|
|
|
if (rpc_port == 0) {
|
2017-06-16 00:26:17 +03:00
|
|
|
rpc_set_error(rpc, "RPC error. Program is not available on %s",
|
|
|
|
data->server);
|
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc),
|
|
|
|
data->private_data);
|
2013-10-27 00:16:09 +04:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
rpc_disconnect(rpc, "normal disconnect");
|
2018-04-08 07:36:37 +03:00
|
|
|
if (rpc_connect_port_internal(rpc, rpc_port, data)) {
|
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, command_data,
|
|
|
|
data->private_data);
|
2013-10-27 00:16:09 +04:00
|
|
|
free_rpc_cb_data(data);
|
2018-04-08 07:36:37 +03:00
|
|
|
return;
|
|
|
|
}
|
2013-10-27 00:16:09 +04:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
rpc_connect_program_2_cb(struct rpc_context *rpc, int status,
|
|
|
|
void *command_data, void *private_data)
|
2013-10-27 00:16:09 +04:00
|
|
|
{
|
|
|
|
struct rpc_cb_data *data = private_data;
|
2014-03-17 04:48:35 +04:00
|
|
|
struct pmap3_mapping map;
|
2013-10-27 00:16:09 +04:00
|
|
|
|
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2013-10-27 00:16:09 +04:00
|
|
|
data->cb(rpc, status, command_data, data->private_data);
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-17 04:48:35 +04:00
|
|
|
switch (rpc->s.ss_family) {
|
|
|
|
case AF_INET:
|
2017-06-26 08:42:17 +03:00
|
|
|
if (rpc_pmap2_getport_async(rpc, data->program, data->version,
|
|
|
|
IPPROTO_TCP,
|
|
|
|
rpc_connect_program_3_cb,
|
|
|
|
private_data) != 0) {
|
2018-02-03 09:50:06 +03:00
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data);
|
2014-03-17 04:48:35 +04:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
map.prog=data->program;
|
|
|
|
map.vers=data->version;
|
|
|
|
map.netid="";
|
|
|
|
map.addr="";
|
|
|
|
map.owner="";
|
2017-06-26 08:42:17 +03:00
|
|
|
if (rpc_pmap3_getaddr_async(rpc, &map,
|
|
|
|
rpc_connect_program_3_cb,
|
|
|
|
private_data) != 0) {
|
2018-02-03 09:50:06 +03:00
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data);
|
2014-03-17 04:48:35 +04:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2013-10-27 00:16:09 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
rpc_connect_program_1_cb(struct rpc_context *rpc, int status,
|
|
|
|
void *command_data, void *private_data)
|
2013-10-27 00:16:09 +04:00
|
|
|
{
|
|
|
|
struct rpc_cb_data *data = private_data;
|
|
|
|
|
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
|
|
|
/* Dont want any more callbacks even if the socket is closed */
|
|
|
|
rpc->connect_cb = NULL;
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2013-10-27 00:16:09 +04:00
|
|
|
data->cb(rpc, status, command_data, data->private_data);
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-17 04:48:35 +04:00
|
|
|
switch (rpc->s.ss_family) {
|
|
|
|
case AF_INET:
|
2017-06-26 08:42:17 +03:00
|
|
|
if (rpc_pmap2_null_async(rpc, rpc_connect_program_2_cb,
|
|
|
|
data) != 0) {
|
2018-02-03 09:50:06 +03:00
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data);
|
2014-03-17 04:48:35 +04:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2017-06-26 08:42:17 +03:00
|
|
|
if (rpc_pmap3_null_async(rpc, rpc_connect_program_2_cb,
|
|
|
|
data) != 0) {
|
2018-02-03 09:50:06 +03:00
|
|
|
data->cb(rpc, RPC_STATUS_ERROR, command_data, data->private_data);
|
2014-03-17 04:48:35 +04:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2013-10-27 00:16:09 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-08 07:36:37 +03:00
|
|
|
static int
|
|
|
|
rpc_connect_port_internal(struct rpc_context *rpc, int port, struct rpc_cb_data *data)
|
|
|
|
{
|
|
|
|
if (rpc_connect_async(rpc, data->server, port,
|
|
|
|
rpc_connect_program_4_cb, data) != 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
rpc_connect_port_async(struct rpc_context *rpc, const char *server,
|
|
|
|
int port,
|
|
|
|
int program, int version,
|
|
|
|
rpc_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
struct rpc_cb_data *data;
|
|
|
|
|
|
|
|
data = malloc(sizeof(struct rpc_cb_data));
|
|
|
|
if (data == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memset(data, 0, sizeof(struct rpc_cb_data));
|
|
|
|
data->server = strdup(server);
|
|
|
|
data->program = program;
|
|
|
|
data->version = version;
|
|
|
|
|
|
|
|
data->cb = cb;
|
|
|
|
data->private_data = private_data;
|
|
|
|
|
|
|
|
if (rpc_connect_port_internal(rpc, port, data)) {
|
|
|
|
rpc_set_error(rpc, "Failed to start connection. %s",
|
|
|
|
rpc_get_error(rpc));
|
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
rpc_connect_program_async(struct rpc_context *rpc, const char *server,
|
|
|
|
int program, int version,
|
|
|
|
rpc_cb cb, void *private_data)
|
2013-10-27 00:16:09 +04:00
|
|
|
{
|
|
|
|
struct rpc_cb_data *data;
|
|
|
|
|
|
|
|
data = malloc(sizeof(struct rpc_cb_data));
|
|
|
|
if (data == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
memset(data, 0, sizeof(struct rpc_cb_data));
|
|
|
|
data->server = strdup(server);
|
|
|
|
data->program = program;
|
|
|
|
data->version = version;
|
|
|
|
|
|
|
|
data->cb = cb;
|
|
|
|
data->private_data = private_data;
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
if (rpc_connect_async(rpc, server, 111, rpc_connect_program_1_cb,
|
|
|
|
data) != 0) {
|
2018-02-02 07:23:57 +03:00
|
|
|
rpc_set_error(rpc, "Failed to start connection. %s",
|
|
|
|
rpc_get_error(rpc));
|
2013-10-27 00:16:09 +04:00
|
|
|
free_rpc_cb_data(data);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
2017-06-26 08:42:17 +03:00
|
|
|
free_nfs_cb_data(struct nfs_cb_data *data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
|
|
|
if (data->continue_data != NULL) {
|
2014-02-18 02:29:07 +04:00
|
|
|
assert(data->free_continue_data);
|
2011-02-06 07:45:09 +03:00
|
|
|
data->free_continue_data(data->continue_data);
|
|
|
|
}
|
|
|
|
|
2014-02-18 02:34:18 +04:00
|
|
|
free(data->saved_path);
|
2017-06-27 23:31:44 +03:00
|
|
|
free(data->fh.val);
|
2016-05-31 22:55:14 +03:00
|
|
|
if (!data->not_my_buffer) {
|
|
|
|
free(data->buffer);
|
|
|
|
}
|
2011-06-19 02:43:28 +04:00
|
|
|
|
2011-02-06 07:45:09 +03:00
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
|
|
|
nfs_free_nfsfh(struct nfsfh *nfsfh)
|
2014-07-20 11:07:46 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
if (nfsfh->fh.val != NULL) {
|
|
|
|
free(nfsfh->fh.val);
|
|
|
|
nfsfh->fh.len = 0;
|
|
|
|
nfsfh->fh.val = NULL;
|
2014-07-20 11:07:46 +04:00
|
|
|
}
|
2016-05-13 13:03:40 +03:00
|
|
|
free(nfsfh->pagecache.entries);
|
2014-07-20 11:07:46 +04:00
|
|
|
free(nfsfh);
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/*
|
|
|
|
* Async call for mounting an nfs share and geting the root filehandle
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
nfs_mount_async(struct nfs_context *nfs, const char *server,
|
|
|
|
const char *export, nfs_cb cb, void *private_data)
|
2015-01-17 22:24:17 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_mount_async(nfs, server, export, cb, private_data);
|
2017-07-06 00:15:51 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_mount_async(nfs, server, export, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-06 00:15:51 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2018-12-29 06:56:29 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Async call for umounting an nfs share
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
nfs_umount_async(struct nfs_context *nfs, nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_umount_async(nfs, cb, private_data);
|
|
|
|
case NFS_V4:
|
|
|
|
/* umount is a no-op in v4 */
|
|
|
|
(*cb)(0, nfs, NULL, private_data);
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2015-01-17 22:24:17 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_normalize_path(struct nfs_context *nfs, char *path)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
char *str;
|
2019-10-10 01:08:10 +03:00
|
|
|
size_t len;
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* // -> / */
|
|
|
|
while ((str = strstr(path, "//"))) {
|
|
|
|
while(*str) {
|
|
|
|
*str = *(str + 1);
|
|
|
|
str++;
|
2015-01-17 22:24:17 +03:00
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* /./ -> / */
|
|
|
|
while ((str = strstr(path, "/./"))) {
|
|
|
|
while(*(str + 1)) {
|
|
|
|
*str = *(str + 2);
|
|
|
|
str++;
|
|
|
|
}
|
2015-06-19 14:15:56 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* ^/../ -> error */
|
|
|
|
if (!strncmp(path, "/../", 4)) {
|
|
|
|
nfs_set_error(nfs,
|
|
|
|
"Absolute path starts with '/../' "
|
|
|
|
"during normalization");
|
|
|
|
return -1;
|
2015-06-19 14:15:56 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* ^[^/] -> error */
|
|
|
|
if (path[0] != '/') {
|
|
|
|
nfs_set_error(nfs,
|
|
|
|
"Absolute path does not start with '/'");
|
|
|
|
return -1;
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
2011-05-31 18:08:29 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* /string/../ -> / */
|
|
|
|
while ((str = strstr(path, "/../"))) {
|
|
|
|
char *tmp;
|
2011-05-31 18:08:29 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
if (!strncmp(path, "/../", 4)) {
|
|
|
|
nfs_set_error(nfs,
|
|
|
|
"Absolute path starts with '/../' "
|
|
|
|
"during normalization");
|
|
|
|
return -1;
|
|
|
|
}
|
2014-07-19 14:32:40 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
tmp = str - 1;
|
|
|
|
while (*tmp != '/') {
|
|
|
|
tmp--;
|
|
|
|
}
|
|
|
|
str += 3;
|
|
|
|
while((*(tmp++) = *(str++)) != '\0')
|
|
|
|
;
|
2011-05-31 18:08:29 +04:00
|
|
|
}
|
2015-01-17 22:19:13 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* /$ -> \0 */
|
|
|
|
len = strlen(path);
|
|
|
|
if (len > 1) {
|
|
|
|
if (path[len - 1] == '/') {
|
|
|
|
path[len - 1] = '\0';
|
|
|
|
len--;
|
|
|
|
}
|
2017-05-10 07:22:46 +03:00
|
|
|
}
|
2017-06-27 23:31:44 +03:00
|
|
|
if (path[0] == '\0') {
|
|
|
|
nfs_set_error(nfs,
|
|
|
|
"Absolute path became '' "
|
|
|
|
"during normalization");
|
|
|
|
return -1;
|
2017-06-16 00:26:17 +03:00
|
|
|
}
|
2015-01-17 22:19:13 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* /.$ -> \0 */
|
|
|
|
if (len >= 2) {
|
|
|
|
if (!strcmp(&path[len - 2], "/.")) {
|
|
|
|
path[len - 2] = '\0';
|
|
|
|
len -= 2;
|
|
|
|
}
|
2017-05-10 07:22:46 +03:00
|
|
|
}
|
2015-01-17 22:19:13 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* ^/..$ -> error */
|
|
|
|
if (!strcmp(path, "/..")) {
|
|
|
|
nfs_set_error(nfs,
|
|
|
|
"Absolute path is '/..' "
|
|
|
|
"during normalization");
|
|
|
|
return -1;
|
2017-05-10 07:22:46 +03:00
|
|
|
}
|
2015-01-17 22:19:13 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
/* /string/..$ -> / */
|
|
|
|
if (len >= 3) {
|
|
|
|
if (!strcmp(&path[len - 3], "/..")) {
|
|
|
|
char *tmp = &path[len - 3];
|
|
|
|
while (*--tmp != '/')
|
|
|
|
;
|
|
|
|
*tmp = '\0';
|
|
|
|
}
|
2015-01-17 22:19:13 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
return 0;
|
|
|
|
}
|
2017-05-09 17:15:11 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_stat_async(struct nfs_context *nfs, const char *path,
|
|
|
|
nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_stat_async(nfs, path, cb, private_data);
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv4",
|
|
|
|
__FUNCTION__);
|
|
|
|
return -1;
|
|
|
|
}
|
2015-01-17 22:19:13 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_stat64_async(struct nfs_context *nfs, const char *path,
|
|
|
|
nfs_cb cb, void *private_data)
|
2015-01-17 22:19:13 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-07-08 00:41:11 +03:00
|
|
|
return nfs3_stat64_async(nfs, path, 0,
|
|
|
|
cb, private_data);
|
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_stat64_async(nfs, path, 0,
|
|
|
|
cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-08 00:41:11 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_lstat64_async(struct nfs_context *nfs, const char *path,
|
|
|
|
nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-07-08 00:41:11 +03:00
|
|
|
return nfs3_stat64_async(nfs, path, 1,
|
|
|
|
cb, private_data);
|
2017-07-08 06:46:28 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_stat64_async(nfs, path, 1,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-08 06:46:28 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-08-06 09:02:39 +03:00
|
|
|
nfs_open2_async(struct nfs_context *nfs, const char *path, int flags,
|
|
|
|
int mode, nfs_cb cb, void *private_data)
|
2017-05-05 17:55:09 +03:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-08-06 09:02:39 +03:00
|
|
|
return nfs3_open_async(nfs, path, flags, mode,
|
|
|
|
cb, private_data);
|
2017-07-16 00:46:38 +03:00
|
|
|
case NFS_V4:
|
2017-08-06 09:02:39 +03:00
|
|
|
return nfs4_open_async(nfs, path, flags, mode,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-16 00:46:38 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2017-05-05 17:55:09 +03:00
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-08-06 09:02:39 +03:00
|
|
|
int
|
|
|
|
nfs_open_async(struct nfs_context *nfs, const char *path, int flags,
|
|
|
|
nfs_cb cb, void *private_data)
|
|
|
|
{
|
2017-08-06 11:57:55 +03:00
|
|
|
return nfs_open2_async(nfs, path, flags, 0666 & ~nfs->mask,
|
|
|
|
cb, private_data);
|
2017-08-06 09:02:39 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_chdir_async(struct nfs_context *nfs, const char *path,
|
|
|
|
nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_chdir_async(nfs, path, cb, private_data);
|
2017-07-10 13:09:07 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_chdir_async(nfs, path, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-10 13:09:07 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset,
|
|
|
|
uint64_t count, nfs_cb cb, void *private_data)
|
2014-07-18 01:31:23 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_pread_async_internal(nfs, nfsfh, offset,
|
|
|
|
(size_t)count,
|
|
|
|
cb, private_data, 0);
|
2017-07-26 02:22:40 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_pread_async_internal(nfs, nfsfh, offset,
|
|
|
|
(size_t)count,
|
|
|
|
cb, private_data, 0);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-26 02:22:40 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count,
|
|
|
|
nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_pread_async_internal(nfs, nfsfh, nfsfh->offset,
|
|
|
|
(size_t)count,
|
|
|
|
cb, private_data, 1);
|
2017-07-26 02:22:40 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_pread_async_internal(nfs, nfsfh, nfsfh->offset,
|
|
|
|
(size_t)count,
|
|
|
|
cb, private_data, 1);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-26 02:22:40 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset,
|
|
|
|
uint64_t count, const void *buf, nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_pwrite_async_internal(nfs, nfsfh, offset,
|
|
|
|
(size_t)count, buf,
|
|
|
|
cb, private_data, 0);
|
2017-07-29 12:51:24 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_pwrite_async_internal(nfs, nfsfh, offset,
|
|
|
|
(size_t)count, buf,
|
|
|
|
cb, private_data, 0);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-29 12:51:24 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d.",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-10-03 03:55:42 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count,
|
|
|
|
const void *buf, nfs_cb cb, void *private_data)
|
2011-10-03 03:55:42 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_write_async(nfs, nfsfh, count, buf,
|
|
|
|
cb, private_data);
|
2017-07-29 12:51:24 +03:00
|
|
|
case NFS_V4:
|
2017-08-03 13:23:08 +03:00
|
|
|
return nfs4_write_async(nfs, nfsfh, count, buf,
|
|
|
|
cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-29 12:51:24 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2011-10-03 03:55:42 +04:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
|
2017-06-26 08:42:17 +03:00
|
|
|
void *private_data)
|
2011-10-03 03:55:42 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_close_async(nfs, nfsfh, cb, private_data);
|
2017-07-16 00:46:38 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_close_async(nfs, nfsfh, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-16 00:46:38 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
|
|
|
|
void *private_data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_fstat_async(nfs, nfsfh, cb, private_data);
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv4",
|
|
|
|
__FUNCTION__);
|
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
|
2017-06-26 08:42:17 +03:00
|
|
|
void *private_data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_fstat64_async(nfs, nfsfh, cb, private_data);
|
2017-07-16 00:46:38 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_fstat64_async(nfs, nfsfh, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-16 00:46:38 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb,
|
|
|
|
void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_fsync_async(nfs, nfsfh, cb, private_data);
|
2017-08-25 18:07:22 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_fsync_async(nfs, nfsfh, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-08-25 18:07:22 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
|
|
|
uint64_t length, nfs_cb cb, void *private_data)
|
2016-07-05 20:14:49 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_ftruncate_async(nfs, nfsfh, length,
|
|
|
|
cb, private_data);
|
2017-08-25 18:31:25 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_ftruncate_async(nfs, nfsfh, length,
|
|
|
|
cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-08-25 18:31:25 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
2016-07-05 20:14:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length,
|
|
|
|
nfs_cb cb, void *private_data)
|
2016-07-05 20:14:49 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_truncate_async(nfs, path, length, cb, private_data);
|
2017-08-25 03:13:00 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_truncate_async(nfs, path, length, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-08-25 03:13:00 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
2016-07-05 20:14:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_mkdir2_async(struct nfs_context *nfs, const char *path, int mode,
|
|
|
|
nfs_cb cb, void *private_data)
|
2014-01-28 08:54:14 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_mkdir2_async(nfs, path, mode, cb, private_data);
|
2017-07-13 16:04:35 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_mkdir2_async(nfs, path, mode, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-07-13 16:04:35 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-01-28 08:54:14 +04:00
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
2017-06-26 08:42:17 +03:00
|
|
|
void *private_data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs_mkdir2_async(nfs, path, 0755, cb, private_data);
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_rmdir_async(nfs, path, cb, private_data);
|
2017-07-14 00:04:28 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_rmdir_async(nfs, path, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-14 00:04:28 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_create_async(struct nfs_context *nfs, const char *path, int flags,
|
|
|
|
int mode, nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_create_async(nfs, path, flags, mode,
|
|
|
|
cb, private_data);
|
2017-08-06 12:15:04 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_create_async(nfs, path, flags, mode,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-08-06 12:15:04 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb,
|
|
|
|
void *private_data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs_create_async(nfs, path, 0, mode, cb, private_data);
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_unlink_async(nfs, path, cb, private_data);
|
2017-08-06 12:24:05 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_unlink_async(nfs, path, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-08-06 12:24:05 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev,
|
|
|
|
nfs_cb cb, void *private_data)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_mknod_async(nfs, path, mode, dev, cb, private_data);
|
2017-08-15 13:05:47 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_mknod_async(nfs, path, mode, dev, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-08-15 13:05:47 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_opendir_async(nfs, path, cb, private_data);
|
2017-08-20 02:08:46 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_opendir_async(nfs, path, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv4",
|
|
|
|
__FUNCTION__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
struct nfsdirent *
|
|
|
|
nfs_readdir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
struct nfsdirent *nfsdirent = nfsdir->current;
|
2012-11-24 20:18:54 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
if (nfsdir->current != NULL) {
|
|
|
|
nfsdir->current = nfsdir->current->next;
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfsdirent;
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
long
|
|
|
|
nfs_telldir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir)
|
|
|
|
{
|
|
|
|
long i;
|
|
|
|
struct nfsdirent *tmp;
|
|
|
|
|
|
|
|
for (i = 0, tmp = nfsdir->entries; tmp; i++, tmp = tmp->next) {
|
|
|
|
if (tmp == nfsdir->current) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
nfs_seekdir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir, long loc)
|
|
|
|
{
|
|
|
|
if (loc < 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (nfsdir->current = nfsdir->entries;
|
2020-06-22 19:11:33 +03:00
|
|
|
nfsdir->current && loc--;
|
|
|
|
nfsdir->current = nfsdir->current->next) {
|
2017-06-27 23:31:44 +03:00
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
|
|
|
nfs_rewinddir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir)
|
|
|
|
{
|
|
|
|
nfsdir->current = nfsdir->entries;
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
|
|
|
nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2018-04-23 22:39:28 +03:00
|
|
|
if (nfs && nfs->dircache_enabled) {
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_dircache_add(nfs, nfsdir);
|
|
|
|
} else {
|
|
|
|
nfs_free_nfsdir(nfsdir);
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
void
|
|
|
|
nfs_getcwd(struct nfs_context *nfs, const char **cwd)
|
2011-02-06 07:45:09 +03:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
if (cwd) {
|
|
|
|
*cwd = nfs->cwd;
|
2011-02-06 07:45:09 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset,
|
|
|
|
int whence, nfs_cb cb, void *private_data)
|
2014-07-28 00:21:18 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_lseek_async(nfs, nfsfh, offset, whence,
|
|
|
|
cb, private_data);
|
2017-08-26 01:05:12 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_lseek_async(nfs, nfsfh, offset, whence,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-08-26 01:05:12 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-07-28 00:21:18 +04:00
|
|
|
}
|
|
|
|
|
2018-01-07 01:35:42 +03:00
|
|
|
int
|
|
|
|
nfs_lockf_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
|
|
|
enum nfs4_lock_op op, uint64_t count,
|
|
|
|
nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_lockf_async(nfs, nfsfh, op, count,
|
|
|
|
cb, private_data);
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-08 07:37:55 +03:00
|
|
|
int
|
|
|
|
nfs_fcntl_async(struct nfs_context *nfs, struct nfsfh *nfsfh,
|
|
|
|
enum nfs4_fcntl_op cmd, void *arg,
|
|
|
|
nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_fcntl_async(nfs, nfsfh, cmd, arg,
|
|
|
|
cb, private_data);
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
2014-07-28 00:21:18 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_statvfs_async(nfs, path, cb, private_data);
|
2017-08-27 00:56:19 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_statvfs_async(nfs, path, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-08-27 00:56:19 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-07-28 00:21:18 +04:00
|
|
|
}
|
|
|
|
|
2018-12-26 06:33:38 +03:00
|
|
|
int
|
|
|
|
nfs_statvfs64_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_statvfs64_async(nfs, path, cb, private_data);
|
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_statvfs64_async(nfs, path, cb, private_data);
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_readlink_async(nfs, path, cb, private_data);
|
2017-07-26 05:14:04 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_readlink_async(nfs, path, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-26 05:14:04 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode,
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_cb cb, void *private_data)
|
2014-07-27 23:21:33 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_chmod_async_internal(nfs, path, 0, mode,
|
2017-06-26 08:42:17 +03:00
|
|
|
cb, private_data);
|
2017-09-01 07:02:43 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_chmod_async_internal(nfs, path, 0, mode,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-01 07:02:43 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-07-27 23:21:33 +04:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode,
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_cb cb, void *private_data)
|
2014-07-27 23:21:33 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_chmod_async_internal(nfs, path, 1, mode,
|
2017-06-26 08:42:17 +03:00
|
|
|
cb, private_data);
|
2017-09-01 07:02:43 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_chmod_async_internal(nfs, path, 1, mode,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-01 07:02:43 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-07-27 23:21:33 +04:00
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode,
|
|
|
|
nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_fchmod_async(nfs, nfsfh, mode, cb, private_data);
|
2017-09-01 07:02:43 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_fchmod_async(nfs, nfsfh, mode, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-01 07:02:43 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid,
|
|
|
|
nfs_cb cb, void *private_data)
|
2014-07-28 00:16:01 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_chown_async_internal(nfs, path, 0, uid, gid,
|
|
|
|
cb, private_data);
|
2017-09-01 23:42:59 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_chown_async_internal(nfs, path, 0, uid, gid,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-01 23:42:59 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-07-28 00:16:01 +04:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid,
|
|
|
|
nfs_cb cb, void *private_data)
|
2014-07-28 00:16:01 +04:00
|
|
|
{
|
2017-06-26 08:42:17 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_chown_async_internal(nfs, path, 1, uid, gid,
|
|
|
|
cb, private_data);
|
2017-09-01 23:42:59 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_chown_async_internal(nfs, path, 1, uid, gid,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-01 23:42:59 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-07-28 00:16:01 +04:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid,
|
|
|
|
int gid, nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_fchown_async(nfs, nfsfh, uid, gid,
|
|
|
|
cb, private_data);
|
2017-09-01 23:42:59 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_fchown_async(nfs, nfsfh, uid, gid,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-01 23:42:59 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-06-27 23:31:44 +03:00
|
|
|
nfs_utimes_async(struct nfs_context *nfs, const char *path,
|
|
|
|
struct timeval *times, nfs_cb cb, void *private_data)
|
2017-06-26 08:42:17 +03:00
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-06-27 23:31:44 +03:00
|
|
|
return nfs3_utimes_async_internal(nfs, path, 0, times,
|
|
|
|
cb, private_data);
|
2017-09-02 23:25:55 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_utimes_async_internal(nfs, path, 0, times,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-09-02 23:25:55 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_lutimes_async(struct nfs_context *nfs, const char *path,
|
|
|
|
struct timeval *times, nfs_cb cb, void *private_data)
|
2014-09-14 18:41:04 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_utimes_async_internal(nfs, path, 1, times,
|
|
|
|
cb, private_data);
|
2017-09-02 23:25:55 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_utimes_async_internal(nfs, path, 1, times,
|
|
|
|
cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-09-02 23:25:55 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-09-14 18:41:04 +04:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_utime_async(struct nfs_context *nfs, const char *path,
|
|
|
|
struct utimbuf *times, nfs_cb cb, void *private_data)
|
2014-09-14 18:41:04 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_utime_async(nfs, path, times, cb, private_data);
|
2018-01-10 10:09:14 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_utime_async(nfs, path, times, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv4",
|
|
|
|
__FUNCTION__);
|
|
|
|
return -1;
|
|
|
|
}
|
2014-09-14 18:41:04 +04:00
|
|
|
}
|
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
int
|
|
|
|
nfs_access_async(struct nfs_context *nfs, const char *path, int mode,
|
|
|
|
nfs_cb cb, void *private_data)
|
2014-09-14 18:41:04 +04:00
|
|
|
{
|
2017-06-27 23:31:44 +03:00
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_access_async(nfs, path, mode, cb, private_data);
|
2017-09-02 22:43:04 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_access_async(nfs, path, mode, cb, private_data);
|
2017-06-27 23:31:44 +03:00
|
|
|
default:
|
2017-09-02 22:43:04 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-27 23:31:44 +03:00
|
|
|
return -1;
|
|
|
|
}
|
2014-09-14 18:41:04 +04:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb,
|
|
|
|
void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_access2_async(nfs, path, cb, private_data);
|
2017-09-02 22:43:04 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_access2_async(nfs, path, cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "%s does not support NFSv4",
|
|
|
|
__FUNCTION__);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2014-09-14 18:41:04 +04:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
2017-07-01 01:40:59 +03:00
|
|
|
nfs_symlink_async(struct nfs_context *nfs, const char *target,
|
2017-06-26 08:42:17 +03:00
|
|
|
const char *newpath, nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
2017-07-01 01:40:59 +03:00
|
|
|
return nfs3_symlink_async(nfs, target, newpath,
|
2017-06-26 08:42:17 +03:00
|
|
|
cb, private_data);
|
2017-07-26 04:36:52 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_symlink_async(nfs, target, newpath,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-07-26 04:36:52 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_rename_async(struct nfs_context *nfs, const char *oldpath,
|
|
|
|
const char *newpath, nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_rename_async(nfs, oldpath, newpath,
|
|
|
|
cb, private_data);
|
2017-08-14 02:01:23 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_rename_async(nfs, oldpath, newpath,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-08-14 02:01:23 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_link_async(struct nfs_context *nfs, const char *oldpath,
|
|
|
|
const char *newpath, nfs_cb cb, void *private_data)
|
|
|
|
{
|
|
|
|
switch (nfs->version) {
|
|
|
|
case NFS_V3:
|
|
|
|
return nfs3_link_async(nfs, oldpath, newpath,
|
|
|
|
cb, private_data);
|
2017-08-08 13:47:22 +03:00
|
|
|
case NFS_V4:
|
|
|
|
return nfs4_link_async(nfs, oldpath, newpath,
|
|
|
|
cb, private_data);
|
2017-06-26 08:42:17 +03:00
|
|
|
default:
|
2017-08-08 13:47:22 +03:00
|
|
|
nfs_set_error(nfs, "%s does not support NFSv%d",
|
|
|
|
__FUNCTION__, nfs->version);
|
2017-06-26 08:42:17 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2011-02-06 07:45:09 +03:00
|
|
|
|
2011-05-31 18:08:29 +04:00
|
|
|
/*
|
2021-08-10 09:29:42 +03:00
|
|
|
* Get/Set the maximum supported READ size by the server
|
2011-05-31 18:08:29 +04:00
|
|
|
*/
|
2017-06-26 08:42:17 +03:00
|
|
|
uint64_t
|
|
|
|
nfs_get_readmax(struct nfs_context *nfs)
|
2011-05-31 18:08:29 +04:00
|
|
|
{
|
|
|
|
return nfs->readmax;
|
|
|
|
}
|
2021-08-10 09:29:42 +03:00
|
|
|
void
|
|
|
|
nfs_set_readmax(struct nfs_context *nfs, uint64_t readmax)
|
|
|
|
{
|
|
|
|
nfs->readmax = readmax;
|
|
|
|
}
|
2011-05-31 18:08:29 +04:00
|
|
|
|
|
|
|
/*
|
2021-08-10 09:29:42 +03:00
|
|
|
* Get/Set the maximum supported WRITE size by the server
|
2011-05-31 18:08:29 +04:00
|
|
|
*/
|
2017-06-26 08:42:17 +03:00
|
|
|
uint64_t
|
|
|
|
nfs_get_writemax(struct nfs_context *nfs)
|
2011-05-31 18:08:29 +04:00
|
|
|
{
|
2013-10-24 06:18:41 +04:00
|
|
|
return nfs->writemax;
|
2011-05-31 18:08:29 +04:00
|
|
|
}
|
2021-08-10 09:29:42 +03:00
|
|
|
void
|
|
|
|
nfs_set_writemax(struct nfs_context *nfs, uint64_t writemax)
|
|
|
|
{
|
|
|
|
nfs->writemax = writemax;
|
|
|
|
}
|
2011-06-19 03:38:20 +04:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_tcp_syncnt(struct nfs_context *nfs, int v) {
|
2014-01-13 14:22:21 +04:00
|
|
|
rpc_set_tcp_syncnt(nfs->rpc, v);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_uid(struct nfs_context *nfs, int uid) {
|
2014-01-13 14:22:21 +04:00
|
|
|
rpc_set_uid(nfs->rpc, uid);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_gid(struct nfs_context *nfs, int gid) {
|
2014-01-13 14:22:21 +04:00
|
|
|
rpc_set_gid(nfs->rpc, gid);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_pagecache(struct nfs_context *nfs, uint32_t v) {
|
2016-05-13 13:03:40 +03:00
|
|
|
rpc_set_pagecache(nfs->rpc, v);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_pagecache_ttl(struct nfs_context *nfs, uint32_t v) {
|
2016-05-13 13:03:40 +03:00
|
|
|
rpc_set_pagecache_ttl(nfs->rpc, v);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_readahead(struct nfs_context *nfs, uint32_t v) {
|
2014-06-23 18:31:32 +04:00
|
|
|
rpc_set_readahead(nfs->rpc, v);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_debug(struct nfs_context *nfs, int level) {
|
2015-06-23 09:52:59 +03:00
|
|
|
rpc_set_debug(nfs->rpc, level);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_dircache(struct nfs_context *nfs, int enabled) {
|
2016-02-08 03:06:00 +03:00
|
|
|
nfs->dircache_enabled = enabled;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_autoreconnect(struct nfs_context *nfs, int num_retries) {
|
2017-05-30 03:21:13 +03:00
|
|
|
nfs->auto_reconnect = num_retries;
|
2017-05-10 07:43:31 +03:00
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_set_version(struct nfs_context *nfs, int version) {
|
2017-06-25 03:58:47 +03:00
|
|
|
switch (version) {
|
|
|
|
case NFS_V3:
|
|
|
|
case NFS_V4:
|
|
|
|
nfs->version = version;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
nfs_set_error(nfs, "NFS version %d is not supported", version);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-07-17 13:08:43 +03:00
|
|
|
int
|
|
|
|
nfs_get_version(struct nfs_context *nfs) {
|
|
|
|
return nfs->version;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_error(struct nfs_context *nfs, char *error_string, ...)
|
2011-06-19 03:38:20 +04:00
|
|
|
{
|
|
|
|
va_list ap;
|
2011-06-21 12:33:50 +04:00
|
|
|
char *str = NULL;
|
2011-06-19 03:38:20 +04:00
|
|
|
|
2011-06-21 12:33:50 +04:00
|
|
|
va_start(ap, error_string);
|
2011-08-29 12:00:09 +04:00
|
|
|
str = malloc(1024);
|
|
|
|
vsnprintf(str, 1024, error_string, ap);
|
2011-06-19 03:38:20 +04:00
|
|
|
if (nfs->rpc->error_string != NULL) {
|
|
|
|
free(nfs->rpc->error_string);
|
|
|
|
}
|
|
|
|
nfs->rpc->error_string = str;
|
2014-01-28 08:54:14 +04:00
|
|
|
va_end(ap);
|
2011-06-19 03:38:20 +04:00
|
|
|
}
|
2011-06-19 08:54:17 +04:00
|
|
|
|
|
|
|
struct mount_cb_data {
|
|
|
|
rpc_cb cb;
|
|
|
|
void *private_data;
|
|
|
|
char *server;
|
|
|
|
};
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
free_mount_cb_data(struct mount_cb_data *data)
|
2011-06-19 08:54:17 +04:00
|
|
|
{
|
|
|
|
if (data->server != NULL) {
|
|
|
|
free(data->server);
|
|
|
|
data->server = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
mount_export_5_cb(struct rpc_context *rpc, int status, void *command_data,
|
|
|
|
void *private_data)
|
2011-06-19 08:54:17 +04:00
|
|
|
{
|
|
|
|
struct mount_cb_data *data = private_data;
|
|
|
|
|
2012-11-24 20:18:54 +04:00
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2011-06-19 08:54:17 +04:00
|
|
|
data->cb(rpc, -EFAULT, command_data, data->private_data);
|
|
|
|
free_mount_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
data->cb(rpc, 0, command_data, data->private_data);
|
|
|
|
if (rpc_disconnect(rpc, "normal disconnect") != 0) {
|
|
|
|
rpc_set_error(rpc, "Failed to disconnect\n");
|
|
|
|
}
|
|
|
|
free_mount_cb_data(data);
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
static void
|
|
|
|
mount_export_4_cb(struct rpc_context *rpc, int status, void *command_data,
|
|
|
|
void *private_data)
|
2011-06-19 08:54:17 +04:00
|
|
|
{
|
|
|
|
struct mount_cb_data *data = private_data;
|
|
|
|
|
2012-11-24 20:18:54 +04:00
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
2011-10-09 12:47:07 +04:00
|
|
|
/* Dont want any more callbacks even if the socket is closed */
|
|
|
|
rpc->connect_cb = NULL;
|
|
|
|
|
2017-06-16 00:05:38 +03:00
|
|
|
if (status != RPC_STATUS_SUCCESS) {
|
2011-06-19 08:54:17 +04:00
|
|
|
data->cb(rpc, -EFAULT, command_data, data->private_data);
|
|
|
|
free_mount_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-26 21:11:05 +04:00
|
|
|
if (rpc_mount3_export_async(rpc, mount_export_5_cb, data) != 0) {
|
2011-06-19 08:54:17 +04:00
|
|
|
data->cb(rpc, -ENOMEM, command_data, data->private_data);
|
|
|
|
free_mount_cb_data(data);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb,
|
|
|
|
void *private_data)
|
2011-06-19 08:54:17 +04:00
|
|
|
{
|
|
|
|
struct mount_cb_data *data;
|
|
|
|
|
2012-11-24 20:18:54 +04:00
|
|
|
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
|
|
|
|
2011-06-19 08:54:17 +04:00
|
|
|
data = malloc(sizeof(struct mount_cb_data));
|
|
|
|
if (data == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
2011-09-03 08:11:22 +04:00
|
|
|
memset(data, 0, sizeof(struct mount_cb_data));
|
2011-06-19 08:54:17 +04:00
|
|
|
data->cb = cb;
|
|
|
|
data->private_data = private_data;
|
|
|
|
data->server = strdup(server);
|
|
|
|
if (data->server == NULL) {
|
|
|
|
free_mount_cb_data(data);
|
|
|
|
return -1;
|
2014-02-14 01:36:54 +04:00
|
|
|
}
|
2017-06-26 08:42:17 +03:00
|
|
|
if (rpc_connect_program_async(rpc, data->server, MOUNT_PROGRAM,
|
|
|
|
MOUNT_V3, mount_export_4_cb, data) != 0) {
|
2018-02-01 06:28:05 +03:00
|
|
|
rpc_set_error(rpc, "Failed to start connection. %s",
|
|
|
|
rpc_get_error(rpc));
|
2011-06-19 08:54:17 +04:00
|
|
|
free_mount_cb_data(data);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
struct rpc_context *
|
|
|
|
nfs_get_rpc_context(struct nfs_context *nfs)
|
2011-06-19 16:31:34 +04:00
|
|
|
{
|
2012-11-24 20:18:54 +04:00
|
|
|
assert(nfs->rpc->magic == RPC_CONTEXT_MAGIC);
|
2011-06-19 16:31:34 +04:00
|
|
|
return nfs->rpc;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
const char *
|
|
|
|
nfs_get_server(struct nfs_context *nfs) {
|
2011-07-31 04:46:34 +04:00
|
|
|
return nfs->server;
|
|
|
|
}
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
const char *
|
|
|
|
nfs_get_export(struct nfs_context *nfs) {
|
2011-07-31 04:46:34 +04:00
|
|
|
return nfs->export;
|
|
|
|
}
|
2011-08-28 13:48:01 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
const struct nfs_fh *
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_get_rootfh(struct nfs_context *nfs) {
|
2012-01-11 00:04:01 +04:00
|
|
|
return &nfs->rootfh;
|
|
|
|
}
|
2012-03-08 14:25:21 +04:00
|
|
|
|
2017-06-27 23:31:44 +03:00
|
|
|
struct nfs_fh *
|
2017-06-26 08:42:17 +03:00
|
|
|
nfs_get_fh(struct nfsfh *nfsfh) {
|
2012-03-08 14:25:21 +04:00
|
|
|
return &nfsfh->fh;
|
|
|
|
}
|
2014-12-10 01:00:15 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
uint16_t
|
|
|
|
nfs_umask(struct nfs_context *nfs, uint16_t mask) {
|
2014-12-10 01:00:15 +03:00
|
|
|
uint16_t tmp = nfs->mask;
|
|
|
|
nfs->mask = mask;
|
|
|
|
return tmp;
|
|
|
|
}
|
2016-03-02 08:35:41 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Sets timeout for nfs apis
|
|
|
|
*/
|
2017-06-26 08:42:17 +03:00
|
|
|
void
|
|
|
|
nfs_set_timeout(struct nfs_context *nfs,int timeout)
|
2016-03-02 08:35:41 +03:00
|
|
|
{
|
|
|
|
rpc_set_timeout(nfs->rpc,timeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Gets timeout for nfs apis
|
|
|
|
*/
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
nfs_get_timeout(struct nfs_context *nfs)
|
2016-03-02 08:35:41 +03:00
|
|
|
{
|
|
|
|
return rpc_get_timeout(nfs->rpc);
|
|
|
|
}
|
2016-11-27 23:46:23 +03:00
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
int
|
|
|
|
rpc_null_async(struct rpc_context *rpc, int program, int version, rpc_cb cb,
|
|
|
|
void *private_data)
|
2016-11-27 23:46:23 +03:00
|
|
|
{
|
|
|
|
struct rpc_pdu *pdu;
|
|
|
|
|
2017-06-26 08:42:17 +03:00
|
|
|
pdu = rpc_allocate_pdu(rpc, program, version, 0, cb, private_data,
|
|
|
|
(zdrproc_t)zdr_void, 0);
|
2016-11-27 23:46:23 +03:00
|
|
|
if (pdu == NULL) {
|
2017-06-26 08:42:17 +03:00
|
|
|
rpc_set_error(rpc, "Out of memory. Failed to allocate pdu "
|
|
|
|
"for NULL call");
|
2016-11-27 23:46:23 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rpc_queue_pdu(rpc, pdu) != 0) {
|
2017-06-26 08:42:17 +03:00
|
|
|
rpc_set_error(rpc, "Out of memory. Failed to queue pdu "
|
|
|
|
"for NULL call");
|
2016-11-27 23:46:23 +03:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|