kio-extras5/0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch

16488 lines
448 KiB
Diff
Raw Normal View History

From c2c1b0cbdfc5788c1755f0fcf25ada2cc6c47858 Mon Sep 17 00:00:00 2001
From: Mathias Tillman <master.homer@gmail.com>
Date: Thu, 16 Oct 2014 12:15:17 +0200
Subject: [PATCH 4/5] Added support for NFSv3, major refactoring, fixed bugs.
REVIEW: 120343
BUG: 268797
BUG: 309113
(cherry picked from commit 1f13cf8b4c5ff5ac6a2c131a89c19c7e77c0194f)
---
nfs/CMakeLists.txt | 2 +-
nfs/README | 4 +-
nfs/TODO | 2 -
nfs/kio_nfs.cpp | 1900 +++++++++++++---------------------------
nfs/kio_nfs.h | 238 +++--
nfs/mount.h | 325 -------
nfs/mount.x | 255 ------
nfs/mount_xdr.c | 353 --------
nfs/nfs.protocol | 4 +
nfs/nfs_prot.h | 699 ---------------
nfs/nfs_prot.x | 365 --------
nfs/nfs_prot_xdr.c | 886 -------------------
nfs/nfsv2.cpp | 1858 +++++++++++++++++++++++++++++++++++++++
nfs/nfsv2.h | 103 +++
nfs/nfsv3.cpp | 2195 +++++++++++++++++++++++++++++++++++++++++++++++
nfs/nfsv3.h | 114 +++
nfs/rpc_mnt2.h | 238 +++++
nfs/rpc_mnt2.x | 255 ++++++
nfs/rpc_mnt2_xdr.c | 277 ++++++
nfs/rpc_mnt3.h | 168 ++++
nfs/rpc_mnt3_xdr.c | 147 ++++
nfs/rpc_nfs2_prot.h | 488 +++++++++++
nfs/rpc_nfs2_prot.x | 365 ++++++++
nfs/rpc_nfs2_prot_xdr.c | 699 +++++++++++++++
nfs/rpc_nfs3_prot.h | 1330 ++++++++++++++++++++++++++++
nfs/rpc_nfs3_prot.x | 908 ++++++++++++++++++++
nfs/rpc_nfs3_prot_xdr.c | 1908 ++++++++++++++++++++++++++++++++++++++++
27 files changed, 11805 insertions(+), 4281 deletions(-)
delete mode 100644 nfs/mount.h
delete mode 100644 nfs/mount.x
delete mode 100644 nfs/mount_xdr.c
delete mode 100644 nfs/nfs_prot.h
delete mode 100644 nfs/nfs_prot.x
delete mode 100644 nfs/nfs_prot_xdr.c
create mode 100644 nfs/nfsv2.cpp
create mode 100644 nfs/nfsv2.h
create mode 100644 nfs/nfsv3.cpp
create mode 100644 nfs/nfsv3.h
create mode 100644 nfs/rpc_mnt2.h
create mode 100644 nfs/rpc_mnt2.x
create mode 100644 nfs/rpc_mnt2_xdr.c
create mode 100644 nfs/rpc_mnt3.h
create mode 100644 nfs/rpc_mnt3_xdr.c
create mode 100644 nfs/rpc_nfs2_prot.h
create mode 100644 nfs/rpc_nfs2_prot.x
create mode 100644 nfs/rpc_nfs2_prot_xdr.c
create mode 100644 nfs/rpc_nfs3_prot.h
create mode 100644 nfs/rpc_nfs3_prot.x
create mode 100644 nfs/rpc_nfs3_prot_xdr.c
diff --git a/nfs/CMakeLists.txt b/nfs/CMakeLists.txt
index 7987427f625990dcb3fb36e62c790b01d3608894..2ed2186e113dad9e9c178cbac680d7c96dff789a 100644
--- a/nfs/CMakeLists.txt
+++ b/nfs/CMakeLists.txt
@@ -1,6 +1,6 @@
add_definitions(-DTRANSLATION_DOMAIN=\"kio_nfs\")
-add_library(kio_nfs MODULE kio_nfs.cpp mount_xdr.c nfs_prot_xdr.c)
+add_library(kio_nfs MODULE kio_nfs.cpp nfsv2.cpp nfsv3.cpp rpc_mnt3_xdr.c rpc_nfs3_prot_xdr.c rpc_mnt2_xdr.c rpc_nfs2_prot_xdr.c)
target_link_libraries(kio_nfs KF5::KIOCore KF5::I18n Qt5::Network)
install(TARGETS kio_nfs DESTINATION ${PLUGIN_INSTALL_DIR} )
diff --git a/nfs/README b/nfs/README
index 9d92d73104ede629e617aeb8e117802ebf4190c2..a266381dfdb47f7b9083b05a8505fbc1e9ca38ec 100644
--- a/nfs/README
+++ b/nfs/README
@@ -1,3 +1,3 @@
-this is an ioslave for KDE for NFS, version 2.
+This contains a kio slave for NFS version 2 and 3.
-Alex
+Mathias
diff --git a/nfs/TODO b/nfs/TODO
index 6e5525127454c936f829028c521999ba4f046c08..92a82fbc6d9a0d38c241287528c0de022ee62bef 100644
--- a/nfs/TODO
+++ b/nfs/TODO
@@ -1,5 +1,3 @@
--symlink stuff (listing and stating works already)
--honour the resume flag
-maybe use rpcgen ?
-cache handling: how long should file handles be cached ?
should the stat'ed structures be cached ? no, IMHO
diff --git a/nfs/kio_nfs.cpp b/nfs/kio_nfs.cpp
index 406c5f2efde4bceed17c6bb017a2b6c5d2ca2711..7f64dca9ca866d34f14e048c2326314f70f6d4a3 100644
--- a/nfs/kio_nfs.cpp
+++ b/nfs/kio_nfs.cpp
@@ -1,6 +1,7 @@
/* This file is part of the KDE project
- Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org>
+ Copyright(C) 2000 Alexander Neundorf <neundorf@kde.org>,
+ 2014 Mathias Tillman <master.homer@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -27,1457 +28,708 @@
#include <sys/utsname.h>
#include <arpa/inet.h>
-
-// This is needed on Solaris so that rpc.h defines clnttcp_create etc.
-#ifndef PORTMAP
-#define PORTMAP
-#endif
-#include <rpc/rpc.h> // for rpc calls
-
-#include <errno.h>
-#include <grp.h>
-#include <memory.h>
#include <netdb.h>
-#include <pwd.h>
-#include <stdlib.h>
-#include <strings.h>
-#include <stdio.h>
-#include <time.h>
-#include <unistd.h>
#include <QFile>
#include <QDir>
#include <QDebug>
-#include <QLoggingCategory>
+#include <QtNetwork/QHostInfo>
#include <KLocalizedString>
#include <kio/global.h>
-#include <iostream>
-
-#define fhandle _fhandle
-#include "mount.h"
-
-#define MAXHOSTLEN 256
-
-//#define MAXFHAGE 60*15 //15 minutes maximum age for file handles
-//this ioslave is for NFS version 2
-#define NFSPROG ((u_long)100003)
-#define NFSVERS ((u_long)2)
+#include "nfsv2.h"
+#include "nfsv3.h"
using namespace KIO;
using namespace std;
-Q_DECLARE_LOGGING_CATEGORY(LOG_KIO_NFS)
Q_LOGGING_CATEGORY(LOG_KIO_NFS, "kde.kio-nfs")
-extern "C" { int Q_DECL_EXPORT kdemain(int argc, char **argv); }
+extern "C" int Q_DECL_EXPORT kdemain(int argc, char** argv);
-int kdemain( int argc, char **argv )
+int kdemain(int argc, char** argv)
{
- if (argc != 4)
- {
- fprintf(stderr, "Usage: kio_nfs protocol domain-socket1 domain-socket2\n");
- exit(-1);
- }
- qCDebug(LOG_KIO_NFS) << "NFS: kdemain: starting";
-
- NFSProtocol slave(argv[2], argv[3]);
- slave.dispatchLoop();
- return 0;
+ if (argc != 4) {
+ fprintf(stderr, "Usage: kio_nfs protocol domain-socket1 domain-socket2\n");
+ exit(-1);
+ }
+
+ qCDebug(LOG_KIO_NFS) << "NFS: kdemain: starting";
+
+ NFSSlave slave(argv[2], argv[3]);
+ slave.dispatchLoop();
+
+ return 0;
}
-static bool isRoot(const QString& path)
+NFSSlave::NFSSlave(const QByteArray& pool, const QByteArray& app)
+ : KIO::SlaveBase("nfs", pool, app),
+ m_protocol(NULL)
+{
+
+ qCDebug(LOG_KIO_NFS) << pool << app;
+}
+NFSSlave::~NFSSlave()
{
- return (path.isEmpty() || (path=="/"));
+ if (m_protocol != NULL) {
+ delete m_protocol;
+ }
}
-static bool isAbsoluteLink(const QString& path)
+void NFSSlave::openConnection()
{
- //hmm, don't know
- if (path.isEmpty()) return true;
- if (path[0]=='/') return true;
- return false;
+ qCDebug(LOG_KIO_NFS) << "openConnection";
+
+ if (m_protocol != NULL) {
+ m_protocol->openConnection();
+ } else {
+ bool connectionError = false;
+
+ int version = 4;
+ while (version > 1) {
+ qCDebug(LOG_KIO_NFS) << "Trying NFS version" << version;
+
+ // We need to create a new NFS protocol handler
+ switch (version) {
+ case 4: {
+ // TODO
+ qCDebug(LOG_KIO_NFS) << "NFSv4 is not supported at this time";
+ }
+ break;
+ case 3: {
+ m_protocol = new NFSProtocolV3(this);
+ }
+ break;
+ case 2: {
+ m_protocol = new NFSProtocolV2(this);
+ }
+ break;
+ }
+
+ // Unimplemented protocol version
+ if (m_protocol == NULL) {
+ version--;
+ continue;
+ }
+
+ m_protocol->setHost(m_host);
+ if (m_protocol->isCompatible(connectionError)) {
+ break;
+ }
+
+ version--;
+ delete m_protocol;
+ m_protocol = NULL;
+ }
+
+
+ if (m_protocol == NULL) {
+ // If we could not find a compatible protocol, send an error.
+ if (!connectionError) {
+ error(KIO::ERR_COULD_NOT_CONNECT, i18n("%1: Unsupported NFS version", m_host));
+ } else {
+ error(KIO::ERR_COULD_NOT_CONNECT, m_host);
+ }
+ } else {
+ // Otherwise we open the connection
+ m_protocol->openConnection();
+ }
+ }
}
-static void createVirtualDirEntry(UDSEntry & entry)
+void NFSSlave::closeConnection()
{
- entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR );
- entry.insert( KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH );
- entry.insert( KIO::UDSEntry::UDS_USER, QString::fromLatin1("root") );
- entry.insert( KIO::UDSEntry::UDS_GROUP, QString::fromLatin1("root") );
- //a dummy size
- entry.insert( KIO::UDSEntry::UDS_SIZE, 1024 );
+ qCDebug(LOG_KIO_NFS);
+
+ if (m_protocol != NULL) {
+ m_protocol->closeConnection();
+ }
}
+void NFSSlave::setHost(const QString& host, quint16 /*port*/, const QString& /*user*/, const QString& /*pass*/)
+{
+ qCDebug(LOG_KIO_NFS);
+
+ if (m_protocol != NULL) {
+ // New host? New protocol!
+ if (m_host != host) {
+ qCDebug(LOG_KIO_NFS) << "Deleting old protocol";
+ delete m_protocol;
+ m_protocol = NULL;
+ } else {
+ m_protocol->setHost(host);
+ }
+ }
+
+ m_host = host;
+}
-static void stripTrailingSlash(QString& path)
+void NFSSlave::put(const QUrl& url, int _mode, KIO::JobFlags _flags)
{
- //if (path=="/") return;
- if (path == QLatin1String("/"))
- path = "";
- else if (path.endsWith(QLatin1Char('/')))
- path.truncate(path.length()-1);
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->put(url, _mode, _flags);
+ }
}
-static void getLastPart(const QString& path, QString& lastPart, QString& rest)
+void NFSSlave::get(const QUrl& url)
{
- int slashPos=path.lastIndexOf('/');
- lastPart=path.mid(slashPos+1);
- rest=path.left(slashPos+1);
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->get(url);
+ }
}
-static QString removeFirstPart(const QString& path)
+void NFSSlave::listDir(const QUrl& url)
{
- QString result("");
- if (path.isEmpty()) return result;
- result=path.mid(1);
- int slashPos=result.indexOf('/');
- return result.mid(slashPos+1);
+ qCDebug(LOG_KIO_NFS) << url;
+
+ if (verifyProtocol()) {
+ m_protocol->listDir(url);
+ }
}
-NFSFileHandle::NFSFileHandle()
-:m_isInvalid(false)
+void NFSSlave::symlink(const QString& target, const QUrl& dest, KIO::JobFlags _flags)
{
- memset(m_handle,'\0',NFS_FHSIZE+1);
-// m_detectTime=time(0);
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->symlink(target, dest, _flags);
+ }
}
-NFSFileHandle::NFSFileHandle(const NFSFileHandle & handle)
-:m_isInvalid(false)
+void NFSSlave::stat(const QUrl& url)
{
- m_handle[NFS_FHSIZE]='\0';
- memcpy(m_handle,handle.m_handle,NFS_FHSIZE);
- m_isInvalid=handle.m_isInvalid;
-// m_detectTime=handle.m_detectTime;
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->stat(url);
+ }
}
-NFSFileHandle::~NFSFileHandle()
-{}
+void NFSSlave::mkdir(const QUrl& url, int permissions)
+{
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->mkdir(url, permissions);
+ }
+}
-NFSFileHandle& NFSFileHandle::operator= (const NFSFileHandle& src)
+void NFSSlave::del(const QUrl& url, bool isfile)
{
- memcpy(m_handle,src.m_handle,NFS_FHSIZE);
- m_isInvalid=src.m_isInvalid;
-// m_detectTime=src.m_detectTime;
- return *this;
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->del(url, isfile);
+ }
}
-NFSFileHandle& NFSFileHandle::operator= (const char* src)
+void NFSSlave::chmod(const QUrl& url, int permissions)
{
- if (src==0)
- {
- m_isInvalid=true;
- return *this;
- };
- memcpy(m_handle,src,NFS_FHSIZE);
- m_isInvalid=false;
-// m_detectTime=time(0);
- return *this;
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->chmod(url, permissions);
+ }
}
-/*time_t NFSFileHandle::age() const
+void NFSSlave::rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags)
{
- return (time(0)-m_detectTime);
-}*/
+ qCDebug(LOG_KIO_NFS);
+ if (verifyProtocol()) {
+ m_protocol->rename(src, dest, flags);
+ }
+}
-NFSProtocol::NFSProtocol (const QByteArray &pool, const QByteArray &app )
-:SlaveBase( "nfs", pool, app )
-,m_client(0)
-,m_sock(-1)
-,m_lastCheck(time(0))
+void NFSSlave::copy(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags)
{
- qCDebug(LOG_KIO_NFS)<<"NFS::NFS: -"<<pool<<"-";
+ qCDebug(LOG_KIO_NFS);
+
+ if (verifyProtocol()) {
+ m_protocol->copy(src, dest, mode, flags);
+ }
}
-NFSProtocol::~NFSProtocol()
+bool NFSSlave::verifyProtocol()
+{
+ const bool haveProtocol = (m_protocol != NULL);
+ if (!haveProtocol) {
+ openConnection();
+
+ if (m_protocol == NULL) {
+ // We have failed.... :(
+ qCDebug(LOG_KIO_NFS) << "Could not find a compatible protocol version!!";
+ return false;
+ }
+
+ // If we are not connected @openConnection will have sent an
+ // error message to the client, so it's safe to return here.
+ if (!m_protocol->isConnected()) {
+ return false;
+ }
+ } else if (!m_protocol->isConnected()) {
+ m_protocol->openConnection();
+ if (!m_protocol->isConnected()) {
+ return false;
+ }
+ }
+
+ if (m_protocol->isConnected()) {
+ return true;
+ }
+
+ finished();
+ return false;
+}
+
+
+NFSFileHandle::NFSFileHandle()
+ : m_handle(NULL),
+ m_size(0),
+ m_linkHandle(NULL),
+ m_linkSize(0),
+ m_isInvalid(true),
+ m_isLink(false)
{
- closeConnection();
+
}
-/*This one is currently unused, so it could be removed.
- The intention was to keep handles around, and from time to time
- remove handles which are too old. Alex
- */
-/*void NFSProtocol::checkForOldFHs()
+NFSFileHandle::NFSFileHandle(const NFSFileHandle& src)
+ : NFSFileHandle()
{
- qCDebug(LOG_KIO_NFS)<<"checking for fhs older than "<<MAXFHAGE;
- qCDebug(LOG_KIO_NFS)<<"current items: "<<m_handleCache.count();
- NFSFileHandleMap::Iterator it=m_handleCache.begin();
- NFSFileHandleMap::Iterator lastIt=it;
- while (it!=m_handleCache.end())
- {
- qCDebug(LOG_KIO_NFS)<<it.data().age()<<flush;
- if (it.data().age()>MAXFHAGE)
- {
- qCDebug(LOG_KIO_NFS)<<"removing";
- m_handleCache.remove(it);
- if (it==lastIt)
- {
- it=m_handleCache.begin();
- lastIt=it;
- }
- else
- it=lastIt;
- }
- lastIt=it;
- it++;
- };
- qCDebug(LOG_KIO_NFS)<<"left items: "<<m_handleCache.count();
- m_lastCheck=time(0);
-}*/
-
-void NFSProtocol::closeConnection()
+ (*this) = src;
+}
+
+NFSFileHandle::NFSFileHandle(const fhandle3& src)
+ : NFSFileHandle()
{
- ::close(m_sock);
- m_sock=-1;
- if (m_client==0) return;
- CLNT_DESTROY(m_client);
+ (*this) = src;
+}
- m_client=0;
+NFSFileHandle::NFSFileHandle(const fhandle& src)
+ : NFSFileHandle()
+{
+ (*this) = src;
}
-bool NFSProtocol::isExportedDir(const QString& path)
+NFSFileHandle::NFSFileHandle(const nfs_fh3& src)
+ : NFSFileHandle()
{
- return m_exportedDirs.contains(path.mid(1));
+ (*this) = src;
}
-/* This one works recursive.
- It tries to get the file handle out of the file handle cache.
- If this doesn't succeed, it needs to do a nfs rpc call
- in order to obtain one.
- */
-NFSFileHandle NFSProtocol::getFileHandle(QString path)
+NFSFileHandle::NFSFileHandle(const nfs_fh& src)
+ : NFSFileHandle()
{
- if (m_client==0) openConnection();
-
- //I'm not sure if this is useful
- //if ((time(0)-m_lastCheck)>MAXFHAGE) checkForOldFHs();
-
- stripTrailingSlash(path);
- qCDebug(LOG_KIO_NFS)<<"getting FH for -"<<path<<"-";
- //now the path looks like "/root/some/dir" or "" if it was "/"
- NFSFileHandle parentFH;
- //we didn't find it
- if (path.isEmpty())
- {
- qCDebug(LOG_KIO_NFS)<<"path is empty, invalidating the FH";
- parentFH.setInvalid();
- return parentFH;
- }
- //check whether we have this filehandle cached
- //the filehandles of the exported root dirs are always in the cache
- if (m_handleCache.find(path)!=m_handleCache.end())
- {
- qCDebug(LOG_KIO_NFS)<<"path is in the cache, returning the FH -"<<m_handleCache[path]<<"-";
- return m_handleCache[path];
- }
- QString rest, lastPart;
- getLastPart(path,lastPart,rest);
- qCDebug(LOG_KIO_NFS)<<"splitting path into rest -"<<rest<<"- and lastPart -"<<lastPart<<"-";
-
- parentFH=getFileHandle(rest);
- //f*ck, it's invalid
- if (parentFH.isInvalid())
- {
- qCDebug(LOG_KIO_NFS)<<"the parent FH is invalid";
- return parentFH;
- }
- // do the rpc call
- diropargs dirargs;
- diropres dirres;
- memcpy(dirargs.dir.data,(const char*)parentFH,NFS_FHSIZE);
- QByteArray tmpStr=QFile::encodeName(lastPart);
- dirargs.name=tmpStr.data();
-
- //cerr<<"calling rpc: FH: -"<<parentFH<<"- with name -"<<dirargs.name<<"-"<<endl;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_LOOKUP,
- (xdrproc_t) xdr_diropargs, (char*)&dirargs,
- (xdrproc_t) xdr_diropres, (char*)&dirres,total_timeout);
-
- if ((clnt_stat!=RPC_SUCCESS) || (dirres.status!=NFS_OK))
- {
- //we failed
- qCDebug(LOG_KIO_NFS)<<"lookup of filehandle failed";
- parentFH.setInvalid();
- return parentFH;
- }
- //everything went fine up to now :-)
- parentFH=dirres.diropres_u.diropres.file.data;
- //qCDebug(LOG_KIO_NFS)<<"filesize: "<<dirres.diropres_u.diropres.attributes.size;
- m_handleCache.insert(path,parentFH);
- qCDebug(LOG_KIO_NFS)<<"return FH -"<<parentFH<<"-";
- return parentFH;
+ (*this) = src;
}
-/* Open connection connects to the mount daemon on the server side.
- In order to do this it needs authentication and calls auth_unix_create().
- Then it asks the mount daemon for the exported shares. Then it tries
- to mount all these shares. If this succeeded for at least one of them,
- a client for the nfs daemon is created.
- */
-void NFSProtocol::openConnection()
+NFSFileHandle::~NFSFileHandle()
{
- qCDebug(LOG_KIO_NFS)<<"NFS::openConnection for" << m_currentHost;
- if (m_currentHost.isEmpty())
- {
- error(ERR_UNKNOWN_HOST, QString());
- return;
- }
- struct sockaddr_in server_addr;
- if (m_currentHost[0] >= '0' && m_currentHost[0] <= '9')
- {
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.s_addr = inet_addr(m_currentHost.toLatin1());
- }
- else
- {
- struct hostent *hp=gethostbyname(m_currentHost.toLatin1());
- if (hp==0)
- {
- error(ERR_UNKNOWN_HOST, m_currentHost);
- return;
- }
- server_addr.sin_family = AF_INET;
- memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
- }
-
- // create mount daemon client
- closeConnection();
- server_addr.sin_port = 0;
- m_sock = RPC_ANYSOCK;
- m_client=clnttcp_create(&server_addr,MOUNTPROG, MOUNTVERS, &m_sock, 0, 0);
- if (m_client==0)
- {
- server_addr.sin_port = 0;
- m_sock = RPC_ANYSOCK;
- pertry_timeout.tv_sec = 3;
- pertry_timeout.tv_usec = 0;
- m_client = clntudp_create(&server_addr,MOUNTPROG, MOUNTVERS, pertry_timeout, &m_sock);
- if (m_client==0)
- {
- clnt_pcreateerror(const_cast<char *>("mount clntudp_create"));
- error(ERR_COULD_NOT_CONNECT, m_currentHost);
- return;
- }
- }
- QString hostName = QHostInfo::localHostName();
- QString domainName = QHostInfo::localDomainName();
- if (!domainName.isEmpty()) {
- hostName = hostName + QLatin1Char('.') + domainName;
- }
- qCDebug(LOG_KIO_NFS) << "hostname is -" << hostName << "-";
- m_client->cl_auth = authunix_create(hostName.toUtf8().data(), geteuid(), getegid(), 0, 0);
- total_timeout.tv_sec = 20;
- total_timeout.tv_usec = 0;
-
- exports exportlist;
- //now do the stuff
- memset(&exportlist, '\0', sizeof(exportlist));
-
- int clnt_stat = clnt_call(m_client, MOUNTPROC_EXPORT,(xdrproc_t) xdr_void, NULL,
- (xdrproc_t) xdr_exports, (char*)&exportlist,total_timeout);
- if (!checkForError(clnt_stat, 0, m_currentHost.toLatin1())) return;
-
- fhstatus fhStatus;
- bool atLeastOnceSucceeded(false);
- for(; exportlist!=0;exportlist = exportlist->ex_next) {
- qCDebug(LOG_KIO_NFS) << "found export: " << exportlist->ex_dir;
-
- memset(&fhStatus, 0, sizeof(fhStatus));
- clnt_stat = clnt_call(m_client, MOUNTPROC_MNT,(xdrproc_t) xdr_dirpath, (char*)(&(exportlist->ex_dir)),
- (xdrproc_t) xdr_fhstatus,(char*) &fhStatus,total_timeout);
- if (fhStatus.fhs_status==0) {
- atLeastOnceSucceeded=true;
- NFSFileHandle fh;
- fh=fhStatus.fhstatus_u.fhs_fhandle;
- QString fname;
- if ( exportlist->ex_dir[0] == '/' )
- fname = exportlist->ex_dir + 1;
- else
- fname = exportlist->ex_dir;
- m_handleCache.insert(QString("/")+fname,fh);
- m_exportedDirs.append(fname);
- // kDebug() <<"appending file -"<<fname<<"- with FH: -"<<fhStatus.fhstatus_u.fhs_fhandle<<"-";
- }
- }
- if (!atLeastOnceSucceeded)
- {
- closeConnection();
- error(ERR_COULD_NOT_AUTHENTICATE, m_currentHost);
- return;
- }
- server_addr.sin_port = 0;
-
- //now create the client for the nfs daemon
- //first get rid of the old one
- closeConnection();
- m_sock = RPC_ANYSOCK;
- m_client = clnttcp_create(&server_addr,NFSPROG,NFSVERS,&m_sock,0,0);
- if (m_client == 0)
- {
- server_addr.sin_port = 0;
- m_sock = RPC_ANYSOCK;
- pertry_timeout.tv_sec = 3;
- pertry_timeout.tv_usec = 0;
- m_client = clntudp_create(&server_addr,NFSPROG, NFSVERS, pertry_timeout, &m_sock);
- if (m_client==0)
- {
- clnt_pcreateerror(const_cast<char *>("NFS clntudp_create"));
- error(ERR_COULD_NOT_CONNECT, m_currentHost);
- return;
- }
- }
- m_client->cl_auth = authunix_create(hostName.toUtf8().data(),geteuid(),getegid(),0,0);
- connected();
- qCDebug(LOG_KIO_NFS)<<"openConnection succeeded";
+ if (m_handle != NULL) {
+ delete [] m_handle;
+ }
+ if (m_linkHandle != NULL) {
+ delete [] m_linkHandle;
+ }
}
-void NFSProtocol::listDir( const QUrl& _url)
+void NFSFileHandle::toFH(nfs_fh3& fh) const
{
- QUrl url(_url);
- QString path( url.path());
-
- if (path.isEmpty())
- {
- url.setPath("/");
- redirection(url);
- finished();
- return;
- }
- //open the connection
- if (m_client==0) openConnection();
- //it failed
- if (m_client==0) return;
- if (isRoot(path))
- {
- qCDebug(LOG_KIO_NFS)<<"listing root";
- totalSize( m_exportedDirs.count());
- //in this case we don't need to do a real listdir
- UDSEntry entry;
- for (QStringList::const_iterator it=m_exportedDirs.constBegin(); it!=m_exportedDirs.constEnd(); ++it)
- {
- entry.clear();
- entry.insert( KIO::UDSEntry::UDS_NAME, (*it) );
- qCDebug(LOG_KIO_NFS)<<"listing "<<(*it);
- createVirtualDirEntry(entry);
- listEntry( entry );
- }
- finished();
- return;
- }
-
- QStringList filesToList;
- qCDebug(LOG_KIO_NFS)<<"getting subdir -"<<path<<"-";
- stripTrailingSlash(path);
- NFSFileHandle fh=getFileHandle(path);
- //cerr<<"this is the fh: -"<<fh<<"-"<<endl;
- if (fh.isInvalid())
- {
- error( ERR_DOES_NOT_EXIST, path);
- return;
- }
- readdirargs listargs;
- memset(&listargs,0,sizeof(listargs));
- listargs.count=1024*16;
- memcpy(listargs.dir.data,fh,NFS_FHSIZE);
- readdirres listres;
- entry* lastEntry = 0;
- do
- {
- memset(&listres,'\0',sizeof(listres));
- // In case that we didn't get all entries we need to set the cookie to the last one we actually received
- if(lastEntry != 0){
- memcpy(listargs.cookie, lastEntry->cookie, NFS_COOKIESIZE);
- }
- int clnt_stat = clnt_call(m_client, NFSPROC_READDIR, (xdrproc_t) xdr_readdirargs, (char*)&listargs,
- (xdrproc_t) xdr_readdirres, (char*)&listres,total_timeout);
- if (!checkForError(clnt_stat,listres.status,path)) return;
- for (entry *dirEntry=listres.readdirres_u.reply.entries;dirEntry!=0;dirEntry=dirEntry->nextentry)
- {
- if ((QString(".")!=dirEntry->name) && (QString("..")!=dirEntry->name))
- filesToList.append(QFile::decodeName(dirEntry->name));
- lastEntry = dirEntry;
- }
- } while (!listres.readdirres_u.reply.eof);
- totalSize( filesToList.count());
-
- UDSEntry entry;
- //stat all files in filesToList
- for (QStringList::const_iterator it=filesToList.constBegin(); it!=filesToList.constEnd(); ++it)
- {
- diropargs dirargs;
- diropres dirres;
- memcpy(dirargs.dir.data,fh,NFS_FHSIZE);
- QByteArray tmpStr=QFile::encodeName(*it);
- dirargs.name=tmpStr.data();
-
- qCDebug(LOG_KIO_NFS)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-";
-
- int clnt_stat= clnt_call(m_client, NFSPROC_LOOKUP,
- (xdrproc_t) xdr_diropargs, (char*)&dirargs,
- (xdrproc_t) xdr_diropres, (char*)&dirres,total_timeout);
- if (!checkForError(clnt_stat,dirres.status,(*it))) return;
-
- NFSFileHandle tmpFH;
- tmpFH=dirres.diropres_u.diropres.file.data;
- m_handleCache.insert(path+'/'+(*it),tmpFH);
-
- entry.clear();
-
- entry.insert( KIO::UDSEntry::UDS_NAME, (*it) );
-
- //is it a symlink ?
- if (S_ISLNK(dirres.diropres_u.diropres.attributes.mode))
- {
- qCDebug(LOG_KIO_NFS)<<"it's a symlink !";
- //cerr<<"fh: "<<tmpFH<<endl;
- nfs_fh nfsFH;
- memcpy(nfsFH.data,dirres.diropres_u.diropres.file.data,NFS_FHSIZE);
- //get the link dest
- readlinkres readLinkRes;
- char nameBuf[NFS_MAXPATHLEN];
- readLinkRes.readlinkres_u.data=nameBuf;
- int clnt_stat=clnt_call(m_client, NFSPROC_READLINK,
- (xdrproc_t) xdr_nfs_fh, (char*)&nfsFH,
- (xdrproc_t) xdr_readlinkres, (char*)&readLinkRes,total_timeout);
- if (!checkForError(clnt_stat,readLinkRes.status,(*it))) return;
- qCDebug(LOG_KIO_NFS)<<"link dest is -"<<readLinkRes.readlinkres_u.data<<"-";
- QByteArray linkDest(readLinkRes.readlinkres_u.data);
- entry.insert( KIO::UDSEntry::UDS_LINK_DEST, QString::fromLocal8Bit( linkDest ) );
-
- bool isValid=isValidLink(path,linkDest);
- if (!isValid)
- {
- completeBadLinkUDSEntry(entry,dirres.diropres_u.diropres.attributes);
- }
- else
- {
- if (isAbsoluteLink(linkDest))
- {
- completeAbsoluteLinkUDSEntry(entry,linkDest);
- }
- else
- {
- tmpStr=QDir::cleanPath(path+QString("/")+QString(linkDest)).toLatin1();
- dirargs.name=tmpStr.data();
- tmpFH=getFileHandle(tmpStr);
- memcpy(dirargs.dir.data,tmpFH,NFS_FHSIZE);
-
- attrstat attrAndStat;
-
- qCDebug(LOG_KIO_NFS)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-";
-
- clnt_stat = clnt_call(m_client, NFSPROC_GETATTR,
- (xdrproc_t) xdr_diropargs, (char*)&dirargs,
- (xdrproc_t) xdr_attrstat, (char*)&attrAndStat,total_timeout);
- if (!checkForError(clnt_stat,attrAndStat.status,tmpStr)) return;
- completeUDSEntry(entry,attrAndStat.attrstat_u.attributes);
- }
- }
- }
- else
- completeUDSEntry(entry,dirres.diropres_u.diropres.attributes);
- listEntry( entry );
- }
- finished();
+ fh.data.data_len = m_size;
+ fh.data.data_val = m_handle;
}
-void NFSProtocol::stat( const QUrl & url)
+void NFSFileHandle::toFH(nfs_fh& fh) const
{
- QString path(url.path());
- stripTrailingSlash(path);
- qCDebug(LOG_KIO_NFS)<<"NFS::stat for -"<<path<<"-";
- QString tmpPath=path;
- if ((tmpPath.length()>1) && (tmpPath[0]=='/')) tmpPath=tmpPath.mid(1);
- // We can't stat root, but we know it's a dir
- if (isRoot(path) || isExportedDir(path))
- {
- UDSEntry entry;
-
- entry.insert( KIO::UDSEntry::UDS_NAME, path );
- createVirtualDirEntry(entry);
- // no size
- statEntry( entry );
- finished();
- qCDebug(LOG_KIO_NFS)<<"succeeded";
- return;
- }
-
- NFSFileHandle fh=getFileHandle(path);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,path);
- return;
- }
-
- diropargs dirargs;
- attrstat attrAndStat;
- memcpy(dirargs.dir.data,fh,NFS_FHSIZE);
- QByteArray tmpStr=QFile::encodeName(path);
- dirargs.name=tmpStr.data();
-
- qCDebug(LOG_KIO_NFS)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-";
-
- int clnt_stat = clnt_call(m_client, NFSPROC_GETATTR,
- (xdrproc_t) xdr_diropargs, (char*)&dirargs,
- (xdrproc_t) xdr_attrstat, (char*)&attrAndStat,total_timeout);
- if (!checkForError(clnt_stat,attrAndStat.status,path)) return;
- UDSEntry entry;
- entry.clear();
-
- QString fileName, parentDir;
- getLastPart(path, fileName, parentDir);
- stripTrailingSlash(parentDir);
-
- entry.insert( KIO::UDSEntry::UDS_NAME, fileName );
-
- //is it a symlink ?
- if (S_ISLNK(attrAndStat.attrstat_u.attributes.mode))
- {
- qCDebug(LOG_KIO_NFS)<<"it's a symlink !";
- nfs_fh nfsFH;
- memcpy(nfsFH.data,fh,NFS_FHSIZE);
- //get the link dest
- readlinkres readLinkRes;
- char nameBuf[NFS_MAXPATHLEN];
- readLinkRes.readlinkres_u.data=nameBuf;
-
- int clnt_stat=clnt_call(m_client, NFSPROC_READLINK,
- (xdrproc_t) xdr_nfs_fh, (char*)&nfsFH,
- (xdrproc_t) xdr_readlinkres, (char*)&readLinkRes,total_timeout);
- if (!checkForError(clnt_stat,readLinkRes.status,path)) return;
- qCDebug(LOG_KIO_NFS)<<"link dest is -"<<readLinkRes.readlinkres_u.data<<"-";
- QByteArray linkDest(readLinkRes.readlinkres_u.data);
- entry.insert( KIO::UDSEntry::UDS_LINK_DEST, QString::fromLocal8Bit( linkDest ) );
-
- bool isValid=isValidLink(parentDir,linkDest);
- if (!isValid)
- {
- completeBadLinkUDSEntry(entry,attrAndStat.attrstat_u.attributes);
- }
- else
- {
- if (isAbsoluteLink(linkDest))
- {
- completeAbsoluteLinkUDSEntry(entry,linkDest);
- }
- else
- {
-
- tmpStr=QDir::cleanPath(parentDir+QString("/")+QString(linkDest)).toLatin1();
- diropargs dirargs;
- dirargs.name=tmpStr.data();
- NFSFileHandle tmpFH;
- tmpFH=getFileHandle(tmpStr);
- memcpy(dirargs.dir.data,tmpFH,NFS_FHSIZE);
-
- qCDebug(LOG_KIO_NFS)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-";
- clnt_stat = clnt_call(m_client, NFSPROC_GETATTR,
- (xdrproc_t) xdr_diropargs, (char*)&dirargs,
- (xdrproc_t) xdr_attrstat, (char*)&attrAndStat,total_timeout);
- if (!checkForError(clnt_stat,attrAndStat.status,tmpStr)) return;
- completeUDSEntry(entry,attrAndStat.attrstat_u.attributes);
- }
- }
- }
- else
- completeUDSEntry(entry,attrAndStat.attrstat_u.attributes);
- statEntry( entry );
- finished();
+ memcpy(fh.data, m_handle, m_size);
}
-void NFSProtocol::completeAbsoluteLinkUDSEntry(UDSEntry& entry, const QByteArray& path)
+void NFSFileHandle::toFHLink(nfs_fh3& fh) const
{
- //taken from file.cc
- struct stat buff;
- if ( ::stat( path.data(), &buff ) == -1 ) return;
-
- entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, buff.st_mode & S_IFMT ); // extract file type
- entry.insert( KIO::UDSEntry::UDS_ACCESS, buff.st_mode & 07777 ); // extract permissions
- entry.insert( KIO::UDSEntry::UDS_SIZE, buff.st_size );
- entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, buff.st_mtime );
-
- uid_t uid = buff.st_uid;
-
- QString str;
- if ( !m_usercache.contains( uid ) ) {
- struct passwd *user = getpwuid( uid );
- if ( user )
- {
- m_usercache.insert( uid, QString::fromLatin1(user->pw_name) );
- str = user->pw_name;
- }
- else
- str = "???";
- } else
- str = m_usercache.value( uid );
-
- entry.insert( KIO::UDSEntry::UDS_USER, str );
-
- gid_t gid = buff.st_gid;
-
- if ( !m_groupcache.contains( gid ) )
- {
- struct group *grp = getgrgid( gid );
- if ( grp )
- {
- m_groupcache.insert( gid, QString::fromLatin1(grp->gr_name) );
- str = grp->gr_name;
- }
- else
- str = "???";
- }
- else
- str = m_groupcache.value( gid );
-
- entry.insert( KIO::UDSEntry::UDS_GROUP, str );
-
- entry.insert( KIO::UDSEntry::UDS_ACCESS_TIME, buff.st_atime );
- entry.insert( KIO::UDSEntry::UDS_CREATION_TIME, buff.st_ctime );
+ fh.data.data_len = m_linkSize;
+ fh.data.data_val = m_linkHandle;
}
-void NFSProtocol::completeBadLinkUDSEntry(UDSEntry& entry, fattr& attributes)
+void NFSFileHandle::toFHLink(nfs_fh& fh) const
{
- // It is a link pointing to nowhere
- completeUDSEntry(entry,attributes);
+ memcpy(fh.data, m_linkHandle, m_size);
+}
+
+NFSFileHandle& NFSFileHandle::operator=(const NFSFileHandle& src)
+{
+ if (src.m_size > 0) {
+ if (m_handle != NULL) {
+ delete [] m_handle;
+ m_handle = NULL;
+ }
+
+ m_size = src.m_size;
+ m_handle = new char[m_size];
+ memcpy(m_handle, src.m_handle, m_size);
+ }
+ if (src.m_linkSize > 0) {
+ if (m_linkHandle != NULL) {
+ delete [] m_linkHandle;
+ m_linkHandle = NULL;
+ }
+
+ m_linkSize = src.m_linkSize;
+ m_linkHandle = new char[m_linkSize];
+ memcpy(m_linkHandle, src.m_linkHandle, m_linkSize);
+ }
- entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFMT - 1 );
- entry.insert( KIO::UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IRWXO );
- entry.insert( KIO::UDSEntry::UDS_SIZE, 0L );
+ m_isInvalid = src.m_isInvalid;
+ m_isLink = src.m_isLink;
+ return *this;
}
-void NFSProtocol::completeUDSEntry(UDSEntry& entry, fattr& attributes)
+NFSFileHandle& NFSFileHandle::operator=(const fhandle3& src)
{
- entry.insert( KIO::UDSEntry::UDS_SIZE, attributes.size );
- entry.insert( KIO::UDSEntry::UDS_MODIFICATION_TIME, attributes.mtime.seconds );
- entry.insert( KIO::UDSEntry::UDS_ACCESS_TIME, attributes.atime.seconds );
- entry.insert( KIO::UDSEntry::UDS_CREATION_TIME, attributes.ctime.seconds );
- entry.insert( KIO::UDSEntry::UDS_ACCESS, (attributes.mode & 07777) );
- entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, attributes.mode & S_IFMT ); // extract file type
-
- uid_t uid = attributes.uid;
- QString str;
- if ( !m_usercache.contains( uid ) )
- {
- struct passwd *user = getpwuid( uid );
- if ( user )
- {
- m_usercache.insert( uid, QString::fromLatin1(user->pw_name) );
- str = user->pw_name;
- }
- else
- str = "???";
- }
- else
- str = m_usercache.value( uid );
-
- entry.insert( KIO::UDSEntry::UDS_USER, str );
-
- gid_t gid = attributes.gid;
-
- if ( !m_groupcache.contains( gid ) )
- {
- struct group *grp = getgrgid( gid );
- if ( grp )
- {
- m_groupcache.insert( gid, QString::fromLatin1(grp->gr_name) );
- str = grp->gr_name;
- }
- else
- str = "???";
- }
- else
- str = m_groupcache.value( gid );
-
- entry.insert( KIO::UDSEntry::UDS_GROUP, str );
-
-/* KIO::UDSEntry::ConstIterator it = entry.begin();
- for( ; it != entry.end(); it++ ) {
- switch (it.key()) {
- case KIO::UDSEntry::UDS_FILE_TYPE:
- qCDebug(LOG_KIO_NFS) << "File Type : " << (mode_t)((*it).m_long);
- break;
- case KIO::UDSEntry::UDS_ACCESS:
- qCDebug(LOG_KIO_NFS) << "Access permissions : " << (mode_t)((*it).m_long);
- break;
- case KIO::UDSEntry::UDS_USER:
- qCDebug(LOG_KIO_NFS) << "User : " << ((*it).m_str.toAscii() );
- break;
- case KIO::UDSEntry::UDS_GROUP:
- qCDebug(LOG_KIO_NFS) << "Group : " << ((*it).m_str.toAscii() );
- break;
- case KIO::UDSEntry::UDS_NAME:
- qCDebug(LOG_KIO_NFS) << "Name : " << ((*it).m_str.toAscii() );
- //m_strText = decodeFileName( (*it).m_str );
- break;
- case KIO::UDSEntry::UDS_URL:
- qCDebug(LOG_KIO_NFS) << "URL : " << ((*it).m_str.toAscii() );
- break;
- case KIO::UDSEntry::UDS_MIME_TYPE:
- qCDebug(LOG_KIO_NFS) << "MimeType : " << ((*it).m_str.toAscii() );
- break;
- case KIO::UDSEntry::UDS_LINK_DEST:
- qCDebug(LOG_KIO_NFS) << "LinkDest : " << ((*it).m_str.toAscii() );
- break;
- }
- }*/
+ if (m_handle != NULL) {
+ delete [] m_handle;
+ m_handle = NULL;
+ }
+
+ m_size = src.fhandle3_len;
+ m_handle = new char[m_size];
+ memcpy(m_handle, src.fhandle3_val, m_size);
+ m_isInvalid = false;
+ return *this;
}
-void NFSProtocol::setHost(const QString& host, quint16 /*port*/, const QString& /*user*/, const QString& /*pass*/)
+NFSFileHandle& NFSFileHandle::operator=(const fhandle& src)
{
- qCDebug(LOG_KIO_NFS) << host;
- if (host.isEmpty())
- {
- error(ERR_UNKNOWN_HOST, QString());
- return;
- }
- if (host==m_currentHost) return;
- m_currentHost=host;
- m_handleCache.clear();
- m_exportedDirs.clear();
- closeConnection();
+ if (m_handle != NULL) {
+ delete [] m_handle;
+ m_handle = NULL;
+ }
+
+ m_size = NFS_FHSIZE;
+ m_handle = new char[m_size];
+ memcpy(m_handle, src, m_size);
+ m_isInvalid = false;
+ return *this;
}
-void NFSProtocol::mkdir( const QUrl& url, int permissions )
+NFSFileHandle& NFSFileHandle::operator=(const nfs_fh3& src)
{
- qCDebug(LOG_KIO_NFS)<<"mkdir";
- QString thePath( url.path());
- stripTrailingSlash(thePath);
- QString dirName, parentDir;
- getLastPart(thePath, dirName, parentDir);
- stripTrailingSlash(parentDir);
- qCDebug(LOG_KIO_NFS)<<"path: -"<<thePath<<"- dir: -"<<dirName<<"- parentDir: -"<<parentDir<<"-";
- if (isRoot(parentDir))
- {
- error(ERR_WRITE_ACCESS_DENIED,thePath);
- return;
- }
- NFSFileHandle fh=getFileHandle(parentDir);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,thePath);
- return;
- }
-
- createargs createArgs;
- memcpy(createArgs.where.dir.data,fh,NFS_FHSIZE);
- QByteArray tmpName=QFile::encodeName(dirName);
- createArgs.where.name=tmpName.data();
- if (permissions==-1) createArgs.attributes.mode=0755;
- else createArgs.attributes.mode=permissions;
-
- diropres dirres;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_MKDIR,
- (xdrproc_t) xdr_createargs, (char*)&createArgs,
- (xdrproc_t) xdr_diropres, (char*)&dirres,total_timeout);
- if (!checkForError(clnt_stat,dirres.status,thePath)) return;
- finished();
+ if (m_handle != NULL) {
+ delete [] m_handle;
+ m_handle = NULL;
+ }
+
+ m_size = src.data.data_len;
+ m_handle = new char[m_size];
+ memcpy(m_handle, src.data.data_val, m_size);
+ m_isInvalid = false;
+ return *this;
}
-bool NFSProtocol::checkForError(int clientStat, int nfsStat, const QString& text)
+NFSFileHandle& NFSFileHandle::operator=(const nfs_fh& src)
{
- if (clientStat!=RPC_SUCCESS)
- {
- qCDebug(LOG_KIO_NFS)<<"rpc error: "<<clientStat;
- //does this mapping make sense ?
- error(ERR_CONNECTION_BROKEN,i18n("An RPC error occurred."));
- return false;
- }
- if (nfsStat!=NFS_OK)
- {
- qCDebug(LOG_KIO_NFS)<<"nfs error: "<<nfsStat;
- switch (nfsStat)
- {
- case NFSERR_PERM:
- error(ERR_ACCESS_DENIED,text);
- break;
- case NFSERR_NOENT:
- error(ERR_DOES_NOT_EXIST,text);
- break;
- //does this mapping make sense ?
- case NFSERR_IO:
- error(ERR_INTERNAL_SERVER,text);
- break;
- //does this mapping make sense ?
- case NFSERR_NXIO:
- error(ERR_DOES_NOT_EXIST,text);
- break;
- case NFSERR_ACCES:
- error(ERR_ACCESS_DENIED,text);
- break;
- case NFSERR_EXIST:
- error(ERR_FILE_ALREADY_EXIST,text);
- break;
- //does this mapping make sense ?
- case NFSERR_NODEV:
- error(ERR_DOES_NOT_EXIST,text);
- break;
- case NFSERR_NOTDIR:
- error(ERR_IS_FILE,text);
- break;
- case NFSERR_ISDIR:
- error(ERR_IS_DIRECTORY,text);
- break;
- //does this mapping make sense ?
- case NFSERR_FBIG:
- error(ERR_INTERNAL_SERVER,text);
- break;
- //does this mapping make sense ?
- case NFSERR_NOSPC:
- error(ERR_INTERNAL_SERVER,i18n("No space left on device"));
- break;
- case NFSERR_ROFS:
- error(ERR_COULD_NOT_WRITE,i18n("Read only file system"));
- break;
- case NFSERR_NAMETOOLONG:
- error(ERR_INTERNAL_SERVER,i18n("Filename too long"));
- break;
- case NFSERR_NOTEMPTY:
- error(ERR_COULD_NOT_RMDIR,text);
- break;
- //does this mapping make sense ?
- case NFSERR_DQUOT:
- error(ERR_INTERNAL_SERVER,i18n("Disk quota exceeded"));
- break;
- case NFSERR_STALE:
- error(ERR_DOES_NOT_EXIST,text);
- break;
- default:
- error(ERR_UNKNOWN,text);
- break;
- }
- return false;
- }
- return true;
+ if (m_handle != NULL) {
+ delete [] m_handle;
+ m_handle = NULL;
+ }
+
+ m_size = NFS_FHSIZE;
+ m_handle = new char[m_size];
+ memcpy(m_handle, src.data, m_size);
+ m_isInvalid = false;
+ return *this;
}
-void NFSProtocol::del( const QUrl& url, bool isfile)
+void NFSFileHandle::setLinkSource(const nfs_fh3& src)
{
- QString thePath( url.path());
- stripTrailingSlash(thePath);
-
- QString fileName, parentDir;
- getLastPart(thePath, fileName, parentDir);
- stripTrailingSlash(parentDir);
- qCDebug(LOG_KIO_NFS)<<"del(): path: -"<<thePath<<"- file -"<<fileName<<"- parentDir: -"<<parentDir<<"-";
- if (isRoot(parentDir))
- {
- error(ERR_ACCESS_DENIED,thePath);
- return;
- }
-
- NFSFileHandle fh=getFileHandle(parentDir);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,thePath);
- return;
- }
-
- if (isfile)
- {
- qCDebug(LOG_KIO_NFS)<<"Deleting file "<<thePath;
- diropargs dirOpArgs;
- memcpy(dirOpArgs.dir.data,fh,NFS_FHSIZE);
- QByteArray tmpName=QFile::encodeName(fileName);
- dirOpArgs.name=tmpName.data();
-
- nfsstat nfsStat;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_REMOVE,
- (xdrproc_t) xdr_diropargs, (char*)&dirOpArgs,
- (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout);
- if (!checkForError(clnt_stat,nfsStat,thePath)) return;
- qCDebug(LOG_KIO_NFS)<<"removing "<<thePath<<" from cache";
- m_handleCache.erase(m_handleCache.find(thePath));
- finished();
- }
- else
- {
- qCDebug(LOG_KIO_NFS)<<"Deleting directory "<<thePath;
- diropargs dirOpArgs;
- memcpy(dirOpArgs.dir.data,fh,NFS_FHSIZE);
- QByteArray tmpName=QFile::encodeName(fileName);
- dirOpArgs.name=tmpName.data();
-
- nfsstat nfsStat;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_RMDIR,
- (xdrproc_t) xdr_diropargs, (char*)&dirOpArgs,
- (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout);
- if (!checkForError(clnt_stat,nfsStat,thePath)) return;
- qCDebug(LOG_KIO_NFS)<<"removing "<<thePath<<" from cache";
- m_handleCache.erase(m_handleCache.find(thePath));
- finished();
- }
+ if (m_linkHandle != NULL) {
+ delete [] m_linkHandle;
+ m_linkHandle = NULL;
+ }
+
+ m_linkSize = src.data.data_len;
+ m_linkHandle = new char[m_linkSize];
+ memcpy(m_linkHandle, src.data.data_val, m_linkSize);
+ m_isLink = true;
}
-void NFSProtocol::chmod( const QUrl& url, int permissions )
+void NFSFileHandle::setLinkSource(const nfs_fh& src)
{
- QString thePath(url.path());
- stripTrailingSlash(thePath);
- qCDebug(LOG_KIO_NFS) << "chmod -"<< thePath << "-";
- if (isRoot(thePath) || isExportedDir(thePath))
- {
- error(ERR_ACCESS_DENIED,thePath);
- return;
- }
-
- NFSFileHandle fh=getFileHandle(thePath);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,thePath);
- return;
- }
-
- sattrargs sAttrArgs;
- memcpy(sAttrArgs.file.data,fh,NFS_FHSIZE);
- sAttrArgs.attributes.uid=(unsigned int)-1;
- sAttrArgs.attributes.gid=(unsigned int)-1;
- sAttrArgs.attributes.size=(unsigned int)-1;
- sAttrArgs.attributes.atime.seconds=(unsigned int)-1;
- sAttrArgs.attributes.atime.useconds=(unsigned int)-1;
- sAttrArgs.attributes.mtime.seconds=(unsigned int)-1;
- sAttrArgs.attributes.mtime.useconds=(unsigned int)-1;
-
- sAttrArgs.attributes.mode=permissions;
-
- nfsstat nfsStat;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_SETATTR,
- (xdrproc_t) xdr_sattrargs, (char*)&sAttrArgs,
- (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout);
- if (!checkForError(clnt_stat,nfsStat,thePath)) return;
-
- finished();
+ if (m_linkHandle != NULL) {
+ delete [] m_linkHandle;
+ m_linkHandle = NULL;
+ }
+
+ m_linkSize = NFS_FHSIZE;
+ m_linkHandle = new char[m_linkSize];
+ memcpy(m_linkHandle, src.data, m_linkSize);
+ m_isLink = true;
}
-void NFSProtocol::get( const QUrl& url )
+
+NFSProtocol::NFSProtocol(NFSSlave* slave)
+ : m_slave(slave)
{
- QString thePath(url.path());
- qCDebug(LOG_KIO_NFS)<<"get() -"<<thePath<<"-";
- NFSFileHandle fh=getFileHandle(thePath);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,thePath);
- return;
- }
- readargs readArgs;
- memcpy(readArgs.file.data,fh,NFS_FHSIZE);
- readArgs.offset=0;
- readArgs.count=NFS_MAXDATA;
- readArgs.totalcount=NFS_MAXDATA;
- readres readRes;
- int offset(0);
- char buf[NFS_MAXDATA];
- readRes.readres_u.reply.data.data_val=buf;
-
- QByteArray array;
- do
- {
- int clnt_stat = clnt_call(m_client, NFSPROC_READ,
- (xdrproc_t) xdr_readargs, (char*)&readArgs,
- (xdrproc_t) xdr_readres, (char*)&readRes,total_timeout);
- if (!checkForError(clnt_stat,readRes.status,thePath)) return;
- if (readArgs.offset==0)
- totalSize(readRes.readres_u.reply.attributes.size);
-
- offset=readRes.readres_u.reply.data.data_len;
- //qCDebug(LOG_KIO_NFS)<<"read "<<offset<<" bytes";
- readArgs.offset+=offset;
- if (offset>0)
- {
- array = QByteArray::fromRawData(readRes.readres_u.reply.data.data_val, offset);
- data( array );
- array.clear();
-
- processedSize(readArgs.offset);
- }
-
- } while (offset>0);
- data( QByteArray() );
- finished();
+
}
-//TODO the partial putting thing is not yet implemented
-void NFSProtocol::put( const QUrl& url, int _mode, KIO::JobFlags flags )
+void NFSProtocol::copy(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags)
{
- QString destPath( url.path());
- qCDebug(LOG_KIO_NFS) << "Put -" << destPath <<"-";
- /*QString dest_part( dest_orig );
- dest_part += ".part";*/
-
- stripTrailingSlash(destPath);
- QString parentDir, fileName;
- getLastPart(destPath,fileName, parentDir);
- if (isRoot(parentDir))
- {
- error(ERR_WRITE_ACCESS_DENIED,destPath);
- return;
+ if (src.isLocalFile()) {
+ copyTo(src, dest, mode, flags);
+ } else if (dest.isLocalFile()) {
+ copyFrom(src, dest, mode, flags);
+ } else {
+ copySame(src, dest, mode, flags);
}
+}
+
+void NFSProtocol::addExportedDir(const QString& path)
+{
+ m_exportedDirs.append(path);
+}
- NFSFileHandle destFH;
- destFH=getFileHandle(destPath);
- qCDebug(LOG_KIO_NFS)<<"file handle for -"<<destPath<<"- is "<<destFH;
+const QStringList& NFSProtocol::getExportedDirs()
+{
+ return m_exportedDirs;
+}
- //the file exists and we don't want to overwrite
- if ((!(flags & KIO::Overwrite)) && (!destFH.isInvalid()))
- {
- error(ERR_FILE_ALREADY_EXIST,destPath);
- return;
+bool NFSProtocol::isExportedDir(const QString& path)
+{
+ // If the path is the root filesystem we always return true.
+ if (QFileInfo(path).isRoot()) {
+ return true;
}
- //TODO: is this correct ?
- //we have to "create" the file anyway, no matter if it already
- //exists or not
- //if we don't create it new, written text will be, hmm, "inserted"
- //in the existing file, i.e. a file could not become smaller, since
- //write only overwrites or extends, but doesn't remove stuff from a file (aleXXX)
-
- qCDebug(LOG_KIO_NFS)<<"creating the file -"<<fileName<<"-";
- NFSFileHandle parentFH;
- parentFH=getFileHandle(parentDir);
- //cerr<<"fh for parent dir: "<<parentFH<<endl;
- //the directory doesn't exist
- if (parentFH.isInvalid())
- {
- qCDebug(LOG_KIO_NFS)<<"parent directory -"<<parentDir<<"- does not exist";
- error(ERR_DOES_NOT_EXIST,parentDir);
- return;
+
+ for (QStringList::const_iterator it = m_exportedDirs.constBegin(); it != m_exportedDirs.constEnd(); ++it) {
+ if (path.length() < (*it).length() && (*it).startsWith(path)) {
+ QString rest = (*it).mid(path.length());
+ if (rest.isEmpty() || rest[0] == QDir::separator()) {
+ qCDebug(LOG_KIO_NFS) << "isExportedDir" << path << "returning true";
+
+ return true;
+ }
+ }
}
- createargs createArgs;
- memcpy(createArgs.where.dir.data,(const char*)parentFH,NFS_FHSIZE);
- QByteArray tmpName=QFile::encodeName(fileName);
- createArgs.where.name=tmpName.data();
-
- //the mode is apparently ignored if the file already exists
- if (_mode==-1) createArgs.attributes.mode=0644;
- else createArgs.attributes.mode=_mode;
- createArgs.attributes.uid=geteuid();
- createArgs.attributes.gid=getegid();
- //this is required, otherwise we are not able to write shorter files
- createArgs.attributes.size=0;
- //hmm, do we need something here ? I don't think so
- createArgs.attributes.atime.seconds=(unsigned int)-1;
- createArgs.attributes.atime.useconds=(unsigned int)-1;
- createArgs.attributes.mtime.seconds=(unsigned int)-1;
- createArgs.attributes.mtime.useconds=(unsigned int)-1;
-
- diropres dirOpRes;
- int clnt_stat = clnt_call(m_client, NFSPROC_CREATE,
- (xdrproc_t) xdr_createargs, (char*)&createArgs,
- (xdrproc_t) xdr_diropres, (char*)&dirOpRes,total_timeout);
- if (!checkForError(clnt_stat,dirOpRes.status,fileName)) return;
- //we created the file successfully
- //destFH=getFileHandle(destPath);
- destFH=dirOpRes.diropres_u.diropres.file.data;
- qCDebug(LOG_KIO_NFS)<<"file -"<<fileName<<"- in dir -"<<parentDir<<"- created successfully";
- //cerr<<"with fh "<<destFH<<endl;
-
- //now we can put
- int result;
- // Loop until we got 0 (end of data)
- writeargs writeArgs;
- memcpy(writeArgs.file.data,(const char*)destFH,NFS_FHSIZE);
- writeArgs.beginoffset=0;
- writeArgs.totalcount=0;
- writeArgs.offset=0;
- attrstat attrStat;
- int bytesWritten(0);
- qCDebug(LOG_KIO_NFS)<<"starting to put";
- do
- {
- QByteArray buffer;
- dataReq(); // Request for data
- result = readData( buffer );
- //qCDebug(LOG_KIO_NFS)<<"received "<<result<<" bytes for putting";
- char * data=buffer.data();
- int bytesToWrite=buffer.size();
- int writeNow(0);
- if (result > 0)
- {
- do
- {
- if (bytesToWrite>NFS_MAXDATA)
- {
- writeNow=NFS_MAXDATA;
- }
- else
- {
- writeNow=bytesToWrite;
- };
- writeArgs.data.data_val=data;
- writeArgs.data.data_len=writeNow;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_WRITE,
- (xdrproc_t) xdr_writeargs, (char*)&writeArgs,
- (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout);
- //qCDebug(LOG_KIO_NFS)<<"written";
- if (!checkForError(clnt_stat,attrStat.status,fileName)) return;
- bytesWritten+=writeNow;
- writeArgs.offset=bytesWritten;
-
- //adjust the pointer
- data=data+writeNow;
- //decrease the rest
- bytesToWrite-=writeNow;
- } while (bytesToWrite>0);
- }
- } while ( result > 0 );
- finished();
+
+ return false;
}
-void NFSProtocol::rename( const QUrl &src, const QUrl &dest, KIO::JobFlags _flags )
+void NFSProtocol::removeExportedDir(const QString& path)
{
- QString srcPath( src.path());
- QString destPath( dest.path());
- stripTrailingSlash(srcPath);
- stripTrailingSlash(destPath);
- qCDebug(LOG_KIO_NFS)<<"renaming -"<<srcPath<<"- to -"<<destPath<<"-";
-
- if (isRoot(srcPath) || isExportedDir(srcPath))
- {
- error(ERR_CANNOT_RENAME,srcPath);
- return;
- }
-
- if (!(_flags & KIO::Overwrite))
- {
- NFSFileHandle testFH;
- testFH=getFileHandle(destPath);
- if (!testFH.isInvalid())
- {
- error(ERR_FILE_ALREADY_EXIST,destPath);
- return;
- }
- }
-
- QString srcFileName, srcParentDir, destFileName, destParentDir;
-
- getLastPart(srcPath, srcFileName, srcParentDir);
- NFSFileHandle srcFH=getFileHandle(srcParentDir);
- if (srcFH.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,srcParentDir);
- return;
- }
- renameargs renameArgs;
- memcpy(renameArgs.from.dir.data,srcFH,NFS_FHSIZE);
- QByteArray tmpName=QFile::encodeName(srcFileName);
- renameArgs.from.name=tmpName.data();
-
- getLastPart(destPath, destFileName, destParentDir);
- NFSFileHandle destFH=getFileHandle(destParentDir);
- if (destFH.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,destParentDir);
- return;
- }
- memcpy(renameArgs.to.dir.data,destFH,NFS_FHSIZE);
- QByteArray tmpName2=QFile::encodeName(destFileName);
- renameArgs.to.name=tmpName2.data();
- nfsstat nfsStat;
-
- int clnt_stat = clnt_call(m_client, NFSPROC_RENAME,
- (xdrproc_t) xdr_renameargs, (char*)&renameArgs,
- (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout);
- if (!checkForError(clnt_stat,nfsStat,destPath)) return;
- finished();
+ m_exportedDirs.removeOne(path);
}
-void NFSProtocol::copy( const QUrl &src, const QUrl &dest, int _mode, KIO::JobFlags _flags )
+void NFSProtocol::addFileHandle(const QString& path, NFSFileHandle fh)
{
- //prepare the source
- QString thePath( src.path());
- stripTrailingSlash(thePath);
- qCDebug(LOG_KIO_NFS) << "Copy to -" << thePath <<"-";
- NFSFileHandle fh=getFileHandle(thePath);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,thePath);
- return;
- };
-
- //create the destination
- QString destPath( dest.path());
- stripTrailingSlash(destPath);
- QString parentDir, fileName;
- getLastPart(destPath,fileName, parentDir);
- if (isRoot(parentDir))
- {
- error(ERR_ACCESS_DENIED,destPath);
- return;
- }
- NFSFileHandle destFH;
- destFH=getFileHandle(destPath);
- qCDebug(LOG_KIO_NFS)<<"file handle for -"<<destPath<<"- is "<<destFH;
-
- //the file exists and we don't want to overwrite
- if ((!(_flags & KIO::Overwrite)) && (!destFH.isInvalid()))
- {
- error(ERR_FILE_ALREADY_EXIST,destPath);
- return;
- }
- //TODO: is this correct ?
- //we have to "create" the file anyway, no matter if it already
- //exists or not
- //if we don't create it new, written text will be, hmm, "inserted"
- //in the existing file, i.e. a file could not become smaller, since
- //write only overwrites or extends, but doesn't remove stuff from a file
-
- qCDebug(LOG_KIO_NFS)<<"creating the file -"<<fileName<<"-";
- NFSFileHandle parentFH;
- parentFH=getFileHandle(parentDir);
- //the directory doesn't exist
- if (parentFH.isInvalid())
- {
- qCDebug(LOG_KIO_NFS)<<"parent directory -"<<parentDir<<"- does not exist";
- error(ERR_DOES_NOT_EXIST,parentDir);
- return;
- };
- createargs createArgs;
- memcpy(createArgs.where.dir.data,(const char*)parentFH,NFS_FHSIZE);
- QByteArray tmpName=QFile::encodeName(fileName);
- createArgs.where.name=tmpName.data();
- if (_mode==-1) createArgs.attributes.mode=0644;
- else createArgs.attributes.mode=_mode;
- createArgs.attributes.uid=geteuid();
- createArgs.attributes.gid=getegid();
- createArgs.attributes.size=0;
- createArgs.attributes.atime.seconds=(unsigned int)-1;
- createArgs.attributes.atime.useconds=(unsigned int)-1;
- createArgs.attributes.mtime.seconds=(unsigned int)-1;
- createArgs.attributes.mtime.useconds=(unsigned int)-1;
-
- diropres dirOpRes;
- int clnt_stat = clnt_call(m_client, NFSPROC_CREATE,
- (xdrproc_t) xdr_createargs, (char*)&createArgs,
- (xdrproc_t) xdr_diropres, (char*)&dirOpRes,total_timeout);
- if (!checkForError(clnt_stat,dirOpRes.status,destPath)) return;
- //we created the file successfully
- destFH=dirOpRes.diropres_u.diropres.file.data;
- qCDebug(LOG_KIO_NFS)<<"file -"<<fileName<<"- in dir -"<<parentDir<<"- created successfully";
-
- char buf[NFS_MAXDATA];
- writeargs writeArgs;
- memcpy(writeArgs.file.data,(const char*)destFH,NFS_FHSIZE);
- writeArgs.beginoffset=0;
- writeArgs.totalcount=0;
- writeArgs.offset=0;
- writeArgs.data.data_val=buf;
- attrstat attrStat;
-
- readargs readArgs;
- memcpy(readArgs.file.data,fh,NFS_FHSIZE);
- readArgs.offset=0;
- readArgs.count=NFS_MAXDATA;
- readArgs.totalcount=NFS_MAXDATA;
- readres readRes;
- readRes.readres_u.reply.data.data_val=buf;
-
- int bytesRead(0);
- do
- {
- //first read
- int clnt_stat = clnt_call(m_client, NFSPROC_READ,
- (xdrproc_t) xdr_readargs, (char*)&readArgs,
- (xdrproc_t) xdr_readres, (char*)&readRes,total_timeout);
- if (!checkForError(clnt_stat,readRes.status,thePath)) return;
- if (readArgs.offset==0)
- totalSize(readRes.readres_u.reply.attributes.size);
-
- bytesRead=readRes.readres_u.reply.data.data_len;
- //qCDebug(LOG_KIO_NFS)<<"read "<<bytesRead<<" bytes";
- //then write
- if (bytesRead>0)
- {
- readArgs.offset+=bytesRead;
-
- writeArgs.data.data_len=bytesRead;
-
- clnt_stat = clnt_call(m_client, NFSPROC_WRITE,
- (xdrproc_t) xdr_writeargs, (char*)&writeArgs,
- (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout);
- //qCDebug(LOG_KIO_NFS)<<"written";
- if (!checkForError(clnt_stat,attrStat.status,destPath)) return;
- writeArgs.offset+=bytesRead;
- }
- } while (bytesRead>0);
-
- finished();
+ m_handleCache.insert(path, fh);
}
-//TODO why isn't this even called ?
-void NFSProtocol::symlink( const QString &target, const QUrl &dest, KIO::JobFlags )
+NFSFileHandle NFSProtocol::getFileHandle(const QString& path)
{
- qCDebug(LOG_KIO_NFS)<<"symlinking ";
- QString destPath=dest.path();
- stripTrailingSlash(destPath);
-
- QString parentDir, fileName;
- getLastPart(destPath,fileName, parentDir);
- qCDebug(LOG_KIO_NFS)<<"symlinking "<<parentDir<<" "<<fileName<<" to "<<target;
- NFSFileHandle fh=getFileHandle(parentDir);
- if (fh.isInvalid())
- {
- error(ERR_DOES_NOT_EXIST,parentDir);
- return;
- }
- if (isRoot(parentDir))
- {
- error(ERR_ACCESS_DENIED,destPath);
- return;
- }
-
- qCDebug(LOG_KIO_NFS)<<"tach";
- QByteArray tmpStr=target.toLatin1();
- symlinkargs symLinkArgs;
- symLinkArgs.to=tmpStr.data();
- memcpy(symLinkArgs.from.dir.data,(const char*)fh,NFS_FHSIZE);
- QByteArray tmpStr2=QFile::encodeName(destPath);
- symLinkArgs.from.name=tmpStr2.data();
-
- nfsstat nfsStat;
- int clnt_stat = clnt_call(m_client, NFSPROC_SYMLINK,
- (xdrproc_t) xdr_symlinkargs, (char*)&symLinkArgs,
- (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout);
- if (!checkForError(clnt_stat,nfsStat,destPath)) return;
-
- finished();
+ if (!isConnected()) {
+ return NFSFileHandle();
+ }
+ if (!isValidPath(path)) {
+ qCDebug(LOG_KIO_NFS) << path << "is not a valid path";
+ return NFSFileHandle();
+ }
+
+ // The handle may already be in the cache, check it now.
+ // The exported dirs are always in the cache.
+ if (m_handleCache.contains(path)) {
+ return m_handleCache[path];
+ }
+
+ // Loop detected, abort.
+ if (QFileInfo(path).path() == path) {
+ return NFSFileHandle();
+ }
+
+ // Look up the file handle from the procotol
+ NFSFileHandle childFH = lookupFileHandle(path);
+ if (!childFH.isInvalid()) {
+ m_handleCache.insert(path, childFH);
+ }
+
+ return childFH;
+}
+
+void NFSProtocol::removeFileHandle(const QString& path)
+{
+ m_handleCache.remove(path);
+}
+
+bool NFSProtocol::isValidPath(const QString& path)
+{
+ if (path.isEmpty() || path == QDir::separator()) {
+ return true;
+ }
+
+ for (QStringList::const_iterator it = m_exportedDirs.constBegin(); it != m_exportedDirs.constEnd(); ++it) {
+ if ((path.length() == (*it).length() && path.startsWith((*it))) || (path.startsWith((*it) + QDir::separator()))) {
+ return true;
+ }
+ }
+
+ return false;
}
bool NFSProtocol::isValidLink(const QString& parentDir, const QString& linkDest)
{
- qCDebug(LOG_KIO_NFS)<<"isValidLink: parent: "<<parentDir<<" link: "<<linkDest;
- if (linkDest.isEmpty()) return false;
- if (isAbsoluteLink(linkDest))
- {
- qCDebug(LOG_KIO_NFS)<<"is an absolute link";
- return QFile::exists(linkDest);
- }
- else
- {
- qCDebug(LOG_KIO_NFS)<<"is a relative link";
- QString absDest=parentDir+'/'+linkDest;
- qCDebug(LOG_KIO_NFS)<<"pointing abs to "<<absDest;
- absDest=removeFirstPart(absDest);
- qCDebug(LOG_KIO_NFS)<<"removed first part "<<absDest;
- absDest=QDir::cleanPath(absDest);
- qCDebug(LOG_KIO_NFS)<<"simplified to "<<absDest;
- if (absDest.indexOf("../")==0)
- return false;
-
- qCDebug(LOG_KIO_NFS)<<"is inside the nfs tree";
- absDest=parentDir+'/'+linkDest;
- absDest=QDir::cleanPath(absDest);
- qCDebug(LOG_KIO_NFS)<<"getting file handle of "<<absDest;
- NFSFileHandle fh=getFileHandle(absDest);
- return (!fh.isInvalid());
- }
- return false;
+ if (linkDest.isEmpty()) {
+ return false;
+ }
+
+ if (QFileInfo(linkDest).isAbsolute()) {
+ return (!getFileHandle(linkDest).isInvalid());
+ } else {
+ QString absDest = QFileInfo(parentDir, linkDest).filePath();
+ absDest = QDir::cleanPath(absDest);
+ return (!getFileHandle(absDest).isInvalid());
+ }
+
+ return false;
+}
+
+int NFSProtocol::openConnection(const QString& host, int prog, int vers, CLIENT*& client, int& sock)
+{
+ if (host.isEmpty()) {
+ return KIO::ERR_UNKNOWN_HOST;
+ }
+ struct sockaddr_in server_addr;
+ if (host[0] >= '0' && host[0] <= '9') {
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_addr.s_addr = inet_addr(host.toLatin1());
+ } else {
+ struct hostent* hp = gethostbyname(host.toLatin1());
+ if (hp == 0) {
+ return KIO::ERR_UNKNOWN_HOST;
+ }
+ server_addr.sin_family = AF_INET;
+ memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length);
+ }
+
+ server_addr.sin_port = 0;
+
+ sock = RPC_ANYSOCK;
+ client = clnttcp_create(&server_addr, prog, vers, &sock, 0, 0);
+ if (client == 0) {
+ server_addr.sin_port = 0;
+ sock = RPC_ANYSOCK;
+
+ timeval pertry_timeout;
+ pertry_timeout.tv_sec = 3;
+ pertry_timeout.tv_usec = 0;
+ client = clntudp_create(&server_addr, prog, vers, pertry_timeout, &sock);
+ if (client == 0) {
+ ::close(sock);
+ return KIO::ERR_COULD_NOT_CONNECT;
+ }
+ }
+
+ QString hostName = QHostInfo::localHostName();
+ QString domainName = QHostInfo::localDomainName();
+ if (!domainName.isEmpty()) {
+ hostName = hostName + QLatin1Char('.') + domainName;
+ }
+
+ client->cl_auth = authunix_create(hostName.toUtf8().data(), geteuid(), getegid(), 0, 0);
+
+ return 0;
+}
+
+bool NFSProtocol::checkForError(int clientStat, int nfsStat, const QString& text)
+{
+ if (clientStat != RPC_SUCCESS) {
+ qCDebug(LOG_KIO_NFS) << "RPC error" << clientStat << text;
+
+ m_slave->error(KIO::ERR_INTERNAL_SERVER, i18n("RPC error %1", clientStat));
+ return false;
+ }
+
+ if (nfsStat != NFS_OK) {
+ qCDebug(LOG_KIO_NFS) << "NFS error:" << nfsStat << text;
+ switch (nfsStat) {
+ case NFSERR_PERM:
+ m_slave->error(KIO::ERR_ACCESS_DENIED, text);
+ break;
+ case NFSERR_NOENT:
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, text);
+ break;
+ //does this mapping make sense ?
+ case NFSERR_IO:
+ m_slave->error(KIO::ERR_INTERNAL_SERVER, text);
+ break;
+ //does this mapping make sense ?
+ case NFSERR_NXIO:
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, text);
+ break;
+ case NFSERR_ACCES:
+ m_slave->error(KIO::ERR_ACCESS_DENIED, text);
+ break;
+ case NFSERR_EXIST:
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, text);
+ break;
+ //does this mapping make sense ?
+ case NFSERR_NODEV:
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, text);
+ break;
+ case NFSERR_NOTDIR:
+ m_slave->error(KIO::ERR_IS_FILE, text);
+ break;
+ case NFSERR_ISDIR:
+ m_slave->error(KIO::ERR_IS_DIRECTORY, text);
+ break;
+ //does this mapping make sense ?
+ case NFSERR_FBIG:
+ m_slave->error(KIO::ERR_INTERNAL_SERVER, text);
+ break;
+ //does this mapping make sense ?
+ case NFSERR_NOSPC:
+ m_slave->error(KIO::ERR_INTERNAL_SERVER, i18n("No space left on device"));
+ break;
+ case NFSERR_ROFS:
+ m_slave->error(KIO::ERR_COULD_NOT_WRITE, i18n("Read only file system"));
+ break;
+ case NFSERR_NAMETOOLONG:
+ m_slave->error(KIO::ERR_INTERNAL_SERVER, i18n("Filename too long"));
+ break;
+ case NFSERR_NOTEMPTY:
+ m_slave->error(KIO::ERR_COULD_NOT_RMDIR, text);
+ break;
+ //does this mapping make sense ?
+ case NFSERR_DQUOT:
+ m_slave->error(KIO::ERR_INTERNAL_SERVER, i18n("Disk quota exceeded"));
+ break;
+ case NFSERR_STALE:
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, text);
+ break;
+ default:
+ m_slave->error(KIO::ERR_UNKNOWN, i18n("NFS error %1 - %2", nfsStat, text));
+ break;
+ }
+ return false;
+ }
+ return true;
+}
+
+void NFSProtocol::createVirtualDirEntry(UDSEntry& entry)
+{
+ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
+ entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+ entry.insert(KIO::UDSEntry::UDS_USER, QString::fromLatin1("root"));
+ entry.insert(KIO::UDSEntry::UDS_GROUP, QString::fromLatin1("root"));
+ // Dummy size.
+ entry.insert(KIO::UDSEntry::UDS_SIZE, 0);
}
+#include "moc_kio_nfs.cpp"
diff --git a/nfs/kio_nfs.h b/nfs/kio_nfs.h
index 62522aa4f0e5c0c7d539538b865a75eb11f36731..9943daf670e665121ea51419ea77599ec4d8d4f5 100644
--- a/nfs/kio_nfs.h
+++ b/nfs/kio_nfs.h
@@ -1,5 +1,6 @@
/* This file is part of the KDE project
- Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org>
+ Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org>,
+ 2014 Mathias Tillman <master.homer@gmail.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -22,90 +23,189 @@
#include <kio/slavebase.h>
#include <kio/global.h>
+#include <kconfiggroup.h>
#include <QtCore/QHash>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QTimer>
+#include <QLoggingCategory>
-#define PORTMAP //this seems to be required to compile on Solaris
-#include <rpc/rpc.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/time.h>
+#include "rpc_mnt2.h"
+#include "rpc_mnt3.h"
+#include "rpc_nfs2_prot.h"
+#include "rpc_nfs3_prot.h"
-#include "nfs_prot.h"
+Q_DECLARE_LOGGING_CATEGORY(LOG_KIO_NFS);
-class NFSFileHandle
+class NFSProtocol;
+
+class NFSSlave : public QObject, public KIO::SlaveBase
{
- public:
- NFSFileHandle();
- NFSFileHandle(const NFSFileHandle & handle);
- ~NFSFileHandle();
- NFSFileHandle& operator= (const NFSFileHandle& src);
- NFSFileHandle& operator= (const char* src);
- operator const char* () const {return m_handle;}
- bool isInvalid() const {return m_isInvalid;}
- void setInvalid() {m_isInvalid=true;}
-// time_t age() const;
- protected:
- char m_handle[NFS_FHSIZE+1];
- bool m_isInvalid;
-// time_t m_detectTime;
+ Q_OBJECT
+
+public:
+ NFSSlave(const QByteArray& pool, const QByteArray& app);
+ ~NFSSlave();
+
+ void openConnection() Q_DECL_OVERRIDE;
+ void closeConnection() Q_DECL_OVERRIDE;
+
+ void setHost(const QString& host, quint16 port, const QString& user, const QString& pass) Q_DECL_OVERRIDE;
+
+ void put(const QUrl& url, int _mode, KIO::JobFlags _flags) Q_DECL_OVERRIDE;
+ void get(const QUrl& url) Q_DECL_OVERRIDE;
+ void listDir(const QUrl& url) Q_DECL_OVERRIDE;
+ void symlink(const QString& target, const QUrl& dest, KIO::JobFlags) Q_DECL_OVERRIDE;
+ void stat(const QUrl& url) Q_DECL_OVERRIDE;
+ void mkdir(const QUrl& url, int permissions) Q_DECL_OVERRIDE;
+ void del(const QUrl& url, bool isfile) Q_DECL_OVERRIDE;
+ void chmod(const QUrl& url, int permissions) Q_DECL_OVERRIDE;
+ void rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+ void copy(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+
+protected:
+ // Verifies the current protocol and connection state, returns true if valid.
+ bool verifyProtocol();
+
+private:
+ NFSProtocol* m_protocol;
+
+ // We need to cache this because the @openConnection call is responsible
+ // for creating the protocol, and the @setHost call might happen before that.
+ QString m_host;
};
-//ostream& operator<<(ostream&, const NFSFileHandle&);
-typedef QMap<QString,NFSFileHandle> NFSFileHandleMap;
+class NFSFileHandle
+{
+public:
+ NFSFileHandle();
+ NFSFileHandle(const NFSFileHandle& handle);
+ NFSFileHandle(const fhandle3& src);
+ NFSFileHandle(const fhandle& src);
+ NFSFileHandle(const nfs_fh3& src);
+ NFSFileHandle(const nfs_fh& src);
+ ~NFSFileHandle();
+
+ // Copies the handle data to an nfs file handle
+ void toFH(nfs_fh3& fh) const;
+ void toFH(nfs_fh& fh) const;
+
+ // Copies the source link handle data to an nfs file handle
+ void toFHLink(nfs_fh3& fh) const;
+ void toFHLink(nfs_fh& fh) const;
+
+ NFSFileHandle& operator=(const NFSFileHandle& src);
+ NFSFileHandle& operator=(const fhandle3& src);
+ NFSFileHandle& operator=(const fhandle& src);
+ NFSFileHandle& operator=(const nfs_fh3& src);
+ NFSFileHandle& operator=(const nfs_fh& src);
+
+ bool isInvalid() const
+ {
+ return m_isInvalid;
+ }
+ void setInvalid()
+ {
+ m_isInvalid = true;
+ }
+
+ bool isLink() const
+ {
+ return m_isLink;
+ }
+ bool isBadLink() const
+ {
+ return (m_isLink && m_linkSize == 0);
+ }
+
+ void setLinkSource(const nfs_fh3& src);
+ void setLinkSource(const nfs_fh& src);
+ void setBadLink()
+ {
+ m_isLink = true;
+ m_linkSize = 0;
+ }
+
+protected:
+ char* m_handle;
+ unsigned int m_size;
+
+ // Set to the link source's handle.
+ char* m_linkHandle;
+ unsigned int m_linkSize;
+
+ bool m_isInvalid;
+ bool m_isLink;
+};
+typedef QMap<QString, NFSFileHandle> NFSFileHandleMap;
-class NFSProtocol : public KIO::SlaveBase
+class NFSProtocol
{
- public:
- NFSProtocol (const QByteArray &pool, const QByteArray &app );
- virtual ~NFSProtocol();
-
- virtual void openConnection();
- virtual void closeConnection();
-
- virtual void setHost( const QString& host, quint16 port, const QString& user, const QString& pass );
-
- virtual void put( const QUrl& url, int _mode, KIO::JobFlags _flags );
- virtual void get( const QUrl& url );
- virtual void listDir( const QUrl& url);
- virtual void symlink( const QString &target, const QUrl &dest, KIO::JobFlags );
- virtual void stat( const QUrl & url);
- virtual void mkdir( const QUrl& url, int permissions );
- virtual void del( const QUrl& url, bool isfile);
- virtual void chmod(const QUrl& url, int permissions );
- virtual void rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags);
- virtual void copy( const QUrl& src, const QUrl &dest, int mode, KIO::JobFlags flags );
- protected:
-// void createVirtualDirEntry(KIO::UDSEntry & entry);
- bool checkForError(int clientStat, int nfsStat, const QString& text);
- bool isExportedDir(const QString& path);
- void completeUDSEntry(KIO::UDSEntry& entry, fattr& attributes);
- void completeBadLinkUDSEntry(KIO::UDSEntry& entry, fattr& attributes);
- void completeAbsoluteLinkUDSEntry(KIO::UDSEntry& entry, const QByteArray& path);
- bool isValidLink(const QString& parentDir, const QString& linkDest);
-// bool isAbsoluteLink(const QString& path);
-
- NFSFileHandle getFileHandle(QString path);
-
- NFSFileHandleMap m_handleCache;
- QHash<long, QString> m_usercache; // maps long ==> QString *
- QHash<long, QString> m_groupcache;
-
- QStringList m_exportedDirs;
- QString m_currentHost;
- CLIENT *m_client;
- CLIENT *m_nfsClient;
- timeval total_timeout;
- timeval pertry_timeout;
- int m_sock;
- time_t m_lastCheck;
- void checkForOldFHs();
+public:
+ NFSProtocol(NFSSlave* slave);
+ virtual ~NFSProtocol() {}
+
+ virtual bool isCompatible(bool &connectionError) = 0;
+ virtual bool isConnected() const = 0;
+
+ virtual void openConnection() = 0;
+ virtual void closeConnection() = 0;
+
+ virtual void setHost(const QString& host) = 0;
+
+ virtual void put(const QUrl& url, int _mode, KIO::JobFlags _flags) = 0;
+ virtual void get(const QUrl& url) = 0;
+ virtual void listDir(const QUrl& url) = 0;
+ virtual void symlink(const QString& target, const QUrl& dest, KIO::JobFlags) = 0;
+ virtual void stat(const QUrl& url) = 0;
+ virtual void mkdir(const QUrl& url, int permissions) = 0;
+ virtual void del(const QUrl& url, bool isfile) = 0;
+ virtual void chmod(const QUrl& url, int permissions) = 0;
+ virtual void rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags) = 0;
+
+ void copy(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags);
+
+protected:
+ // Copy from NFS to NFS
+ virtual void copySame(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) = 0;
+ // Copy from NFS to local
+ virtual void copyFrom(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) = 0;
+ // Copy from local to NFS
+ virtual void copyTo(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) = 0;
+
+ // Look up a file handle
+ virtual NFSFileHandle lookupFileHandle(const QString& path) = 0;
+
+ // Modify the exported dirs.
+ void addExportedDir(const QString& path);
+ const QStringList& getExportedDirs();
+ bool isExportedDir(const QString& path);
+ void removeExportedDir(const QString& path);
+
+ // File handle cache functions.
+ void addFileHandle(const QString& path, NFSFileHandle fh);
+ NFSFileHandle getFileHandle(const QString& path);
+ void removeFileHandle(const QString& path);
+
+ // Make sure that the path is actually a part of an nfs share.
+ bool isValidPath(const QString& path);
+ bool isValidLink(const QString& parentDir, const QString& linkDest);
+
+ int openConnection(const QString& host, int prog, int vers, CLIENT*& client, int& sock);
+
+ bool checkForError(int clientStat, int nfsStat, const QString& text);
+
+ void createVirtualDirEntry(KIO::UDSEntry& entry);
+
+private:
+ NFSSlave* m_slave;
+
+ NFSFileHandleMap m_handleCache;
+ QStringList m_exportedDirs;
};
#endif
diff --git a/nfs/mount.h b/nfs/mount.h
deleted file mode 100644
index c3b8c217f3574c8afd2410ad2b50ec98828e31bb..0000000000000000000000000000000000000000
--- a/nfs/mount.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#ifndef _MOUNT_H_RPCGEN
-#define _MOUNT_H_RPCGEN
-
-#include <rpc/rpc.h>
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-#ifndef _rpcsvc_mount_h
-#define _rpcsvc_mount_h
-#define MNTPATHLEN 1024
-#define MNTNAMLEN 255
-#define FHSIZE 32
-
-typedef char fhandle[FHSIZE];
-#ifdef __cplusplus
-extern "C" bool_t xdr_fhandle(XDR *, fhandle);
-#elif __STDC__
-extern bool_t xdr_fhandle(XDR *, fhandle);
-#else /* Old Style C */
-bool_t xdr_fhandle();
-#endif /* Old Style C */
-
-
-struct fhstatus {
- u_int fhs_status;
- union {
- fhandle fhs_fhandle;
- } fhstatus_u;
-};
-typedef struct fhstatus fhstatus;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*);
-#elif __STDC__
-extern bool_t xdr_fhstatus(XDR *, fhstatus*);
-#else /* Old Style C */
-bool_t xdr_fhstatus();
-#endif /* Old Style C */
-
-
-typedef char *dirpath;
-#ifdef __cplusplus
-extern "C" bool_t xdr_dirpath(XDR *, dirpath*);
-#elif __STDC__
-extern bool_t xdr_dirpath(XDR *, dirpath*);
-#else /* Old Style C */
-bool_t xdr_dirpath();
-#endif /* Old Style C */
-
-
-typedef char *name;
-#ifdef __cplusplus
-extern "C" bool_t xdr_name(XDR *, name*);
-#elif __STDC__
-extern bool_t xdr_name(XDR *, name*);
-#else /* Old Style C */
-bool_t xdr_name();
-#endif /* Old Style C */
-
-
-typedef struct mountbody *mountlist;
-#ifdef __cplusplus
-extern "C" bool_t xdr_mountlist(XDR *, mountlist*);
-#elif __STDC__
-extern bool_t xdr_mountlist(XDR *, mountlist*);
-#else /* Old Style C */
-bool_t xdr_mountlist();
-#endif /* Old Style C */
-
-
-struct mountbody {
- name ml_hostname;
- dirpath ml_directory;
- mountlist ml_next;
-};
-typedef struct mountbody mountbody;
-#ifdef __cplusplus
-extern "C" bool_t xdr_mountbody(XDR *, mountbody*);
-#elif __STDC__
-extern bool_t xdr_mountbody(XDR *, mountbody*);
-#else /* Old Style C */
-bool_t xdr_mountbody();
-#endif /* Old Style C */
-
-
-typedef struct groupnode *groups;
-#ifdef __cplusplus
-extern "C" bool_t xdr_groups(XDR *, groups*);
-#elif __STDC__
-extern bool_t xdr_groups(XDR *, groups*);
-#else /* Old Style C */
-bool_t xdr_groups();
-#endif /* Old Style C */
-
-
-struct groupnode {
- name gr_name;
- groups gr_next;
-};
-typedef struct groupnode groupnode;
-#ifdef __cplusplus
-extern "C" bool_t xdr_groupnode(XDR *, groupnode*);
-#elif __STDC__
-extern bool_t xdr_groupnode(XDR *, groupnode*);
-#else /* Old Style C */
-bool_t xdr_groupnode();
-#endif /* Old Style C */
-
-
-typedef struct exportnode *exports;
-#ifdef __cplusplus
-extern "C" bool_t xdr_exports(XDR *, exports*);
-#elif __STDC__
-extern bool_t xdr_exports(XDR *, exports*);
-#else /* Old Style C */
-bool_t xdr_exports();
-#endif /* Old Style C */
-
-
-struct exportnode {
- dirpath ex_dir;
- groups ex_groups;
- exports ex_next;
-};
-typedef struct exportnode exportnode;
-#ifdef __cplusplus
-extern "C" bool_t xdr_exportnode(XDR *, exportnode*);
-#elif __STDC__
-extern bool_t xdr_exportnode(XDR *, exportnode*);
-#else /* Old Style C */
-bool_t xdr_exportnode();
-#endif /* Old Style C */
-
-
-struct ppathcnf {
- int pc_link_max;
- short pc_max_canon;
- short pc_max_input;
- short pc_name_max;
- short pc_path_max;
- short pc_pipe_buf;
- u_char pc_vdisable;
- char pc_xxx;
- short pc_mask[2];
-};
-typedef struct ppathcnf ppathcnf;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#elif __STDC__
-extern bool_t xdr_ppathcnf(XDR *, ppathcnf*);
-#else /* Old Style C */
-bool_t xdr_ppathcnf();
-#endif /* Old Style C */
-
-#endif /*!_rpcsvc_mount_h*/
-
-#define MOUNTPROG ((u_long)100005)
-#define MOUNTVERS ((u_long)1)
-
-#ifdef __cplusplus
-#define MOUNTPROC_NULL ((u_long)0)
-extern "C" void * mountproc_null_1(void *, CLIENT *);
-extern "C" void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern "C" mountlist * mountproc_dump_1(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern "C" void * mountproc_umntall_1(void *, CLIENT *);
-extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern "C" exports * mountproc_export_1(void *, CLIENT *);
-extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern "C" exports * mountproc_exportall_1(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#elif __STDC__
-#define MOUNTPROC_NULL ((u_long)0)
-extern void * mountproc_null_1(void *, CLIENT *);
-extern void * mountproc_null_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_MNT ((u_long)1)
-extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
-extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_DUMP ((u_long)2)
-extern mountlist * mountproc_dump_1(void *, CLIENT *);
-extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_UMNT ((u_long)3)
-extern void * mountproc_umnt_1(dirpath *, CLIENT *);
-extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern void * mountproc_umntall_1(void *, CLIENT *);
-extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern exports * mountproc_export_1(void *, CLIENT *);
-extern exports * mountproc_export_1_svc(void *, struct svc_req *);
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern exports * mountproc_exportall_1(void *, CLIENT *);
-extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
-
-#else /* Old Style C */
-#define MOUNTPROC_NULL ((u_long)0)
-extern void * mountproc_null_1();
-extern void * mountproc_null_1_svc();
-#define MOUNTPROC_MNT ((u_long)1)
-extern fhstatus * mountproc_mnt_1();
-extern fhstatus * mountproc_mnt_1_svc();
-#define MOUNTPROC_DUMP ((u_long)2)
-extern mountlist * mountproc_dump_1();
-extern mountlist * mountproc_dump_1_svc();
-#define MOUNTPROC_UMNT ((u_long)3)
-extern void * mountproc_umnt_1();
-extern void * mountproc_umnt_1_svc();
-#define MOUNTPROC_UMNTALL ((u_long)4)
-extern void * mountproc_umntall_1();
-extern void * mountproc_umntall_1_svc();
-#define MOUNTPROC_EXPORT ((u_long)5)
-extern exports * mountproc_export_1();
-extern exports * mountproc_export_1_svc();
-#define MOUNTPROC_EXPORTALL ((u_long)6)
-extern exports * mountproc_exportall_1();
-extern exports * mountproc_exportall_1_svc();
-#endif /* Old Style C */
-#define MOUNTVERS_POSIX ((u_long)2)
-
-#ifdef __cplusplus
-extern "C" void * mountproc_null_2(void *, CLIENT *);
-extern "C" void * mountproc_null_2_svc(void *, struct svc_req *);
-extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern "C" mountlist * mountproc_dump_2(void *, CLIENT *);
-extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern "C" void * mountproc_umntall_2(void *, CLIENT *);
-extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_export_2(void *, CLIENT *);
-extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern "C" exports * mountproc_exportall_2(void *, CLIENT *);
-extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#elif __STDC__
-extern void * mountproc_null_2(void *, CLIENT *);
-extern void * mountproc_null_2_svc(void *, struct svc_req *);
-extern fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
-extern fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
-extern mountlist * mountproc_dump_2(void *, CLIENT *);
-extern mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
-extern void * mountproc_umnt_2(dirpath *, CLIENT *);
-extern void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
-extern void * mountproc_umntall_2(void *, CLIENT *);
-extern void * mountproc_umntall_2_svc(void *, struct svc_req *);
-extern exports * mountproc_export_2(void *, CLIENT *);
-extern exports * mountproc_export_2_svc(void *, struct svc_req *);
-extern exports * mountproc_exportall_2(void *, CLIENT *);
-extern exports * mountproc_exportall_2_svc(void *, struct svc_req *);
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
-extern ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
-
-#else /* Old Style C */
-extern void * mountproc_null_2();
-extern void * mountproc_null_2_svc();
-extern fhstatus * mountproc_mnt_2();
-extern fhstatus * mountproc_mnt_2_svc();
-extern mountlist * mountproc_dump_2();
-extern mountlist * mountproc_dump_2_svc();
-extern void * mountproc_umnt_2();
-extern void * mountproc_umnt_2_svc();
-extern void * mountproc_umntall_2();
-extern void * mountproc_umntall_2_svc();
-extern exports * mountproc_export_2();
-extern exports * mountproc_export_2_svc();
-extern exports * mountproc_exportall_2();
-extern exports * mountproc_exportall_2_svc();
-#define MOUNTPROC_PATHCONF ((u_long)7)
-extern ppathcnf * mountproc_pathconf_2();
-extern ppathcnf * mountproc_pathconf_2_svc();
-#endif /* Old Style C */
-
-#endif /* !_MOUNT_H_RPCGEN */
diff --git a/nfs/mount.x b/nfs/mount.x
deleted file mode 100644
index 4aaf97de9ade2655cd48ae460ba24ee322b57183..0000000000000000000000000000000000000000
--- a/nfs/mount.x
+++ /dev/null
@@ -1,255 +0,0 @@
-%/*
-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-% * unrestricted use provided that this legend is included on all tape
-% * media and as a part of the software program in whole or part. Users
-% * may copy or modify Sun RPC without charge, but are not authorized
-% * to license or distribute it to anyone else except as part of a product or
-% * program developed by the user or with the express written consent of
-% * Sun Microsystems, Inc.
-% *
-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-% *
-% * Sun RPC is provided with no support and without any obligation on the
-% * part of Sun Microsystems, Inc. to assist in its use, correction,
-% * modification or enhancement.
-% *
-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-% * OR ANY PART THEREOF.
-% *
-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-% * or profits or other special, indirect and consequential damages, even if
-% * Sun has been advised of the possibility of such damages.
-% *
-% * Sun Microsystems, Inc.
-% * 2550 Garcia Avenue
-% * Mountain View, California 94043
-% */
-
-%/*
-% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
-% */
-%
-%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-/*
- * Protocol description for the mount program
- */
-
-#ifdef RPC_HDR
-%#ifndef _rpcsvc_mount_h
-%#define _rpcsvc_mount_h
-#endif
-
-const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
-const MNTNAMLEN = 255; /* maximum bytes in a name argument */
-const FHSIZE = 32; /* size in bytes of a file handle */
-
-/*
- * The fhandle is the file handle that the server passes to the client.
- * All file operations are done using the file handles to refer to a file
- * or a directory. The file handle can contain whatever information the
- * server needs to distinguish an individual file.
- */
-typedef opaque fhandle[FHSIZE];
-
-/*
- * If a status of zero is returned, the call completed successfully, and
- * a file handle for the directory follows. A non-zero status indicates
- * some sort of error. The status corresponds with UNIX error numbers.
- */
-union fhstatus switch (unsigned fhs_status) {
-case 0:
- fhandle fhs_fhandle;
-default:
- void;
-};
-
-/*
- * The type dirpath is the pathname of a directory
- */
-typedef string dirpath<MNTPATHLEN>;
-
-/*
- * The type name is used for arbitrary names (hostnames, groupnames)
- */
-typedef string name<MNTNAMLEN>;
-
-/*
- * A list of who has what mounted
- */
-typedef struct mountbody *mountlist;
-struct mountbody {
- name ml_hostname;
- dirpath ml_directory;
- mountlist ml_next;
-};
-
-/*
- * A list of netgroups
- */
-typedef struct groupnode *groups;
-struct groupnode {
- name gr_name;
- groups gr_next;
-};
-
-/*
- * A list of what is exported and to whom
- */
-typedef struct exportnode *exports;
-struct exportnode {
- dirpath ex_dir;
- groups ex_groups;
- exports ex_next;
-};
-
-/*
- * POSIX pathconf information
- */
-struct ppathcnf {
- int pc_link_max; /* max links allowed */
- short pc_max_canon; /* max line len for a tty */
- short pc_max_input; /* input a tty can eat all at once */
- short pc_name_max; /* max file name length (dir entry) */
- short pc_path_max; /* max path name length (/x/y/x/.. ) */
- short pc_pipe_buf; /* size of a pipe (bytes) */
- u_char pc_vdisable; /* safe char to turn off c_cc[i] */
- char pc_xxx; /* alignment padding; cc_t == char */
- short pc_mask[2]; /* validity and boolean bits */
-};
-
-program MOUNTPROG {
- /*
- * Version one of the mount protocol communicates with version two
- * of the NFS protocol. The only connecting point is the fhandle
- * structure, which is the same for both protocols.
- */
- version MOUNTVERS {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- fhstatus
- MOUNTPROC_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC_EXPORT(void) = 5;
-
- /*
- * Identical to MOUNTPROC_EXPORT above
- */
- exports
- MOUNTPROC_EXPORTALL(void) = 6;
- } = 1;
-
- /*
- * Version two of the mount protocol communicates with version two
- * of the NFS protocol.
- * The only difference from version one is the addition of a POSIX
- * pathconf call.
- */
- version MOUNTVERS_POSIX {
- /*
- * Does no work. It is made available in all RPC services
- * to allow server reponse testing and timing
- */
- void
- MOUNTPROC_NULL(void) = 0;
-
- /*
- * If fhs_status is 0, then fhs_fhandle contains the
- * file handle for the directory. This file handle may
- * be used in the NFS protocol. This procedure also adds
- * a new entry to the mount list for this client mounting
- * the directory.
- * Unix authentication required.
- */
- fhstatus
- MOUNTPROC_MNT(dirpath) = 1;
-
- /*
- * Returns the list of remotely mounted filesystems. The
- * mountlist contains one entry for each hostname and
- * directory pair.
- */
- mountlist
- MOUNTPROC_DUMP(void) = 2;
-
- /*
- * Removes the mount list entry for the directory
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNT(dirpath) = 3;
-
- /*
- * Removes all of the mount list entries for this client
- * Unix authentication required.
- */
- void
- MOUNTPROC_UMNTALL(void) = 4;
-
- /*
- * Returns a list of all the exported filesystems, and which
- * machines are allowed to import it.
- */
- exports
- MOUNTPROC_EXPORT(void) = 5;
-
- /*
- * Identical to MOUNTPROC_EXPORT above
- */
- exports
- MOUNTPROC_EXPORTALL(void) = 6;
-
- /*
- * POSIX pathconf info (Sun hack)
- */
- ppathcnf
- MOUNTPROC_PATHCONF(dirpath) = 7;
- } = 2;
-} = 100005;
-
-#ifdef RPC_HDR
-%#endif /*!_rpcsvc_mount_h*/
-#endif
diff --git a/nfs/mount_xdr.c b/nfs/mount_xdr.c
deleted file mode 100644
index 433a8596884bdb4fe05795c74de21767ed88d6eb..0000000000000000000000000000000000000000
--- a/nfs/mount_xdr.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- * --- Well, it was hand-edited now, to fix compilation on other systems.... ---
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <arpa/inet.h>
-
-#include <stdint.h>
-
-/* David: added the #defines below to fix compilation on Mac OS 10.3.9, whose rpc/xdr.h has no int32 macros, only long, short etc. */
-
-#ifndef IXDR_GET_INT32
-#define IXDR_GET_INT32(buf) ((int32_t)ntohl((uint32_t)*(buf)++))
-#endif
-#ifndef IXDR_GET_U_INT32
-#define IXDR_GET_U_INT32(buf) ((uint32_t)IXDR_GET_INT32(buf))
-#endif
-#ifndef IXDR_PUT_INT32
-#define IXDR_PUT_INT32(buf, v) (*(buf)++ = (int32_t)htonl((uint32_t)(v)))
-#endif
-#ifndef IXDR_PUT_U_INT32
-#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32(buf, (int32_t)(v))
-#endif
-
-#include "mount.h"
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
-
-bool_t
-xdr_fhandle(XDR *xdrs, fhandle objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_opaque(xdrs, objp, FHSIZE)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_fhstatus(XDR *xdrs, fhstatus *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_u_int(xdrs, &objp->fhs_status)) {
- return (FALSE);
- }
- switch (objp->fhs_status) {
- case 0:
- if (!xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_dirpath(XDR *xdrs, dirpath *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_string(xdrs, objp, MNTPATHLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_name(XDR *xdrs, name *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_string(xdrs, objp, MNTNAMLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_mountlist(XDR *xdrs, mountlist *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct mountbody), (xdrproc_t)xdr_mountbody)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_mountbody(XDR *xdrs, mountbody *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_name(xdrs, &objp->ml_hostname)) {
- return (FALSE);
- }
- if (!xdr_dirpath(xdrs, &objp->ml_directory)) {
- return (FALSE);
- }
- if (!xdr_mountlist(xdrs, &objp->ml_next)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_groups(XDR *xdrs, groups *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct groupnode), (xdrproc_t)xdr_groupnode)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_groupnode(XDR *xdrs, groupnode *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_name(xdrs, &objp->gr_name)) {
- return (FALSE);
- }
- if (!xdr_groups(xdrs, &objp->gr_next)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_exports(XDR *xdrs, exports *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_pointer(xdrs, (char **)objp, sizeof(struct exportnode), (xdrproc_t)xdr_exportnode)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_exportnode(XDR *xdrs, exportnode *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_dirpath(xdrs, &objp->ex_dir)) {
- return (FALSE);
- }
- if (!xdr_groups(xdrs, &objp->ex_groups)) {
- return (FALSE);
- }
- if (!xdr_exports(xdrs, &objp->ex_next)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_ppathcnf(XDR *xdrs, ppathcnf *objp)
-{
-
- register int32_t *buf=buf;
-
- int i=i;
-
- if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE(xdrs, 6 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_U_INT32(buf,objp->pc_link_max);
- IXDR_PUT_SHORT(buf,objp->pc_max_canon);
- IXDR_PUT_SHORT(buf,objp->pc_max_input);
- IXDR_PUT_SHORT(buf,objp->pc_name_max);
- IXDR_PUT_SHORT(buf,objp->pc_path_max);
- IXDR_PUT_SHORT(buf,objp->pc_pipe_buf);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
-
- }
- else {
- { register short *genp;
- for ( i = 0,genp=objp->pc_mask;
- i < 2; i++){
- IXDR_PUT_SHORT(buf,*genp++);
- }
- };
- }
-
- return (TRUE);
- } else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE(xdrs,6 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
-
- }
- else {
- objp->pc_link_max = IXDR_GET_U_INT32(buf);
- objp->pc_max_canon = IXDR_GET_SHORT(buf);
- objp->pc_max_input = IXDR_GET_SHORT(buf);
- objp->pc_name_max = IXDR_GET_SHORT(buf);
- objp->pc_path_max = IXDR_GET_SHORT(buf);
- objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
-
- }
- else {
- { register short *genp;
- for ( i = 0,genp=objp->pc_mask;
- i < 2; i++){
- *genp++ = IXDR_GET_SHORT(buf);
- }
- };
- }
- return(TRUE);
- }
-
- if (!xdr_int(xdrs, &objp->pc_link_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_canon)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_max_input)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_name_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_path_max)) {
- return (FALSE);
- }
- if (!xdr_short(xdrs, &objp->pc_pipe_buf)) {
- return (FALSE);
- }
- if (!xdr_u_char(xdrs, &objp->pc_vdisable)) {
- return (FALSE);
- }
- if (!xdr_char(xdrs, &objp->pc_xxx)) {
- return (FALSE);
- }
- if (!xdr_vector(xdrs, (char *)objp->pc_mask, 2, sizeof(short), (xdrproc_t)xdr_short)) {
- return (FALSE);
- }
- return (TRUE);
-}
diff --git a/nfs/nfs.protocol b/nfs/nfs.protocol
index 85cf2035e44bf7bfe65d4e2b62d1f44fa05d6001..1eaf07243155cc47a0ffd657778d5d1699d6f3c6 100644
--- a/nfs/nfs.protocol
+++ b/nfs/nfs.protocol
@@ -10,6 +10,10 @@ makedir=true
deleting=true
linking=true
moving=true
+copyToFile=true
+copyFromFile=true
+maxInstances=20
+maxInstancesPerHost=5
X-DocPath=kioslave5/nfs/index.html
Icon=folder-remote
Class=:internet
diff --git a/nfs/nfs_prot.h b/nfs/nfs_prot.h
deleted file mode 100644
index 5ed218f20d2fda219adda6899a1321fc3d384d1e..0000000000000000000000000000000000000000
--- a/nfs/nfs_prot.h
+++ /dev/null
@@ -1,699 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#ifndef _NFS_PROT_H_RPCGEN
-#define _NFS_PROT_H_RPCGEN
-
-#include <rpc/rpc.h>
-
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1987, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */
-#ifndef _rpcsvc_nfs_prot_h
-#define _rpcsvc_nfs_prot_h
-#define NFS_PORT 2049
-#define NFS_MAXDATA 8192
-#define NFS_MAXPATHLEN 1024
-#define NFS_MAXNAMLEN 255
-#define NFS_FHSIZE 32
-#define NFS_COOKIESIZE 4
-#define NFS_FIFO_DEV -1
-#define NFSMODE_FMT 0170000
-#define NFSMODE_DIR 0040000
-#define NFSMODE_CHR 0020000
-#define NFSMODE_BLK 0060000
-#define NFSMODE_REG 0100000
-#define NFSMODE_LNK 0120000
-#define NFSMODE_SOCK 0140000
-#define NFSMODE_FIFO 0010000
-
-enum nfsstat {
- NFS_OK = 0,
- NFSERR_PERM = 1,
- NFSERR_NOENT = 2,
- NFSERR_IO = 5,
- NFSERR_NXIO = 6,
- NFSERR_ACCES = 13,
- NFSERR_EXIST = 17,
- NFSERR_NODEV = 19,
- NFSERR_NOTDIR = 20,
- NFSERR_ISDIR = 21,
- NFSERR_INVAL = 22,
- NFSERR_FBIG = 27,
- NFSERR_NOSPC = 28,
- NFSERR_ROFS = 30,
- NFSERR_NAMETOOLONG = 63,
- NFSERR_NOTEMPTY = 66,
- NFSERR_DQUOT = 69,
- NFSERR_STALE = 70,
- NFSERR_WFLUSH = 99
-};
-typedef enum nfsstat nfsstat;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nfsstat(XDR *, nfsstat*);
-#elif __STDC__
-extern bool_t xdr_nfsstat(XDR *, nfsstat*);
-#else /* Old Style C */
-bool_t xdr_nfsstat();
-#endif /* Old Style C */
-
-
-enum ftype {
- NFNON = 0,
- NFREG = 1,
- NFDIR = 2,
- NFBLK = 3,
- NFCHR = 4,
- NFLNK = 5,
- NFSOCK = 6,
- NFBAD = 7,
- NFFIFO = 8
-};
-typedef enum ftype ftype;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ftype(XDR *, ftype*);
-#elif __STDC__
-extern bool_t xdr_ftype(XDR *, ftype*);
-#else /* Old Style C */
-bool_t xdr_ftype();
-#endif /* Old Style C */
-
-
-struct nfs_fh {
- char data[NFS_FHSIZE];
-};
-typedef struct nfs_fh nfs_fh;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nfs_fh(XDR *, nfs_fh*);
-#elif __STDC__
-extern bool_t xdr_nfs_fh(XDR *, nfs_fh*);
-#else /* Old Style C */
-bool_t xdr_nfs_fh();
-#endif /* Old Style C */
-
-
-struct nfstime {
- u_int seconds;
- u_int useconds;
-};
-typedef struct nfstime nfstime;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nfstime(XDR *, nfstime*);
-#elif __STDC__
-extern bool_t xdr_nfstime(XDR *, nfstime*);
-#else /* Old Style C */
-bool_t xdr_nfstime();
-#endif /* Old Style C */
-
-
-struct fattr {
- ftype type;
- u_int mode;
- u_int nlink;
- u_int uid;
- u_int gid;
- u_int size;
- u_int blocksize;
- u_int rdev;
- u_int blocks;
- u_int fsid;
- u_int fileid;
- nfstime atime;
- nfstime mtime;
- nfstime ctime;
-};
-typedef struct fattr fattr;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fattr(XDR *, fattr*);
-#elif __STDC__
-extern bool_t xdr_fattr(XDR *, fattr*);
-#else /* Old Style C */
-bool_t xdr_fattr();
-#endif /* Old Style C */
-
-
-struct sattr {
- u_int mode;
- u_int uid;
- u_int gid;
- u_int size;
- nfstime atime;
- nfstime mtime;
-};
-typedef struct sattr sattr;
-#ifdef __cplusplus
-extern "C" bool_t xdr_sattr(XDR *, sattr*);
-#elif __STDC__
-extern bool_t xdr_sattr(XDR *, sattr*);
-#else /* Old Style C */
-bool_t xdr_sattr();
-#endif /* Old Style C */
-
-
-typedef char *filename;
-#ifdef __cplusplus
-extern "C" bool_t xdr_filename(XDR *, filename*);
-#elif __STDC__
-extern bool_t xdr_filename(XDR *, filename*);
-#else /* Old Style C */
-bool_t xdr_filename();
-#endif /* Old Style C */
-
-
-typedef char *nfspath;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nfspath(XDR *, nfspath*);
-#elif __STDC__
-extern bool_t xdr_nfspath(XDR *, nfspath*);
-#else /* Old Style C */
-bool_t xdr_nfspath();
-#endif /* Old Style C */
-
-
-struct attrstat {
- nfsstat status;
- union {
- fattr attributes;
- } attrstat_u;
-};
-typedef struct attrstat attrstat;
-#ifdef __cplusplus
-extern "C" bool_t xdr_attrstat(XDR *, attrstat*);
-#elif __STDC__
-extern bool_t xdr_attrstat(XDR *, attrstat*);
-#else /* Old Style C */
-bool_t xdr_attrstat();
-#endif /* Old Style C */
-
-
-struct sattrargs {
- nfs_fh file;
- sattr attributes;
-};
-typedef struct sattrargs sattrargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_sattrargs(XDR *, sattrargs*);
-#elif __STDC__
-extern bool_t xdr_sattrargs(XDR *, sattrargs*);
-#else /* Old Style C */
-bool_t xdr_sattrargs();
-#endif /* Old Style C */
-
-
-struct diropargs {
- nfs_fh dir;
- filename name;
-};
-typedef struct diropargs diropargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_diropargs(XDR *, diropargs*);
-#elif __STDC__
-extern bool_t xdr_diropargs(XDR *, diropargs*);
-#else /* Old Style C */
-bool_t xdr_diropargs();
-#endif /* Old Style C */
-
-
-struct diropokres {
- nfs_fh file;
- fattr attributes;
-};
-typedef struct diropokres diropokres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_diropokres(XDR *, diropokres*);
-#elif __STDC__
-extern bool_t xdr_diropokres(XDR *, diropokres*);
-#else /* Old Style C */
-bool_t xdr_diropokres();
-#endif /* Old Style C */
-
-
-struct diropres {
- nfsstat status;
- union {
- diropokres diropres;
- } diropres_u;
-};
-typedef struct diropres diropres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_diropres(XDR *, diropres*);
-#elif __STDC__
-extern bool_t xdr_diropres(XDR *, diropres*);
-#else /* Old Style C */
-bool_t xdr_diropres();
-#endif /* Old Style C */
-
-
-struct readlinkres {
- nfsstat status;
- union {
- nfspath data;
- } readlinkres_u;
-};
-typedef struct readlinkres readlinkres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_readlinkres(XDR *, readlinkres*);
-#elif __STDC__
-extern bool_t xdr_readlinkres(XDR *, readlinkres*);
-#else /* Old Style C */
-bool_t xdr_readlinkres();
-#endif /* Old Style C */
-
-
-struct readargs {
- nfs_fh file;
- u_int offset;
- u_int count;
- u_int totalcount;
-};
-typedef struct readargs readargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_readargs(XDR *, readargs*);
-#elif __STDC__
-extern bool_t xdr_readargs(XDR *, readargs*);
-#else /* Old Style C */
-bool_t xdr_readargs();
-#endif /* Old Style C */
-
-
-struct readokres {
- fattr attributes;
- struct {
- u_int data_len;
- char *data_val;
- } data;
-};
-typedef struct readokres readokres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_readokres(XDR *, readokres*);
-#elif __STDC__
-extern bool_t xdr_readokres(XDR *, readokres*);
-#else /* Old Style C */
-bool_t xdr_readokres();
-#endif /* Old Style C */
-
-
-struct readres {
- nfsstat status;
- union {
- readokres reply;
- } readres_u;
-};
-typedef struct readres readres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_readres(XDR *, readres*);
-#elif __STDC__
-extern bool_t xdr_readres(XDR *, readres*);
-#else /* Old Style C */
-bool_t xdr_readres();
-#endif /* Old Style C */
-
-
-struct writeargs {
- nfs_fh file;
- u_int beginoffset;
- u_int offset;
- u_int totalcount;
- struct {
- u_int data_len;
- char *data_val;
- } data;
-};
-typedef struct writeargs writeargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_writeargs(XDR *, writeargs*);
-#elif __STDC__
-extern bool_t xdr_writeargs(XDR *, writeargs*);
-#else /* Old Style C */
-bool_t xdr_writeargs();
-#endif /* Old Style C */
-
-
-struct createargs {
- diropargs where;
- sattr attributes;
-};
-typedef struct createargs createargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_createargs(XDR *, createargs*);
-#elif __STDC__
-extern bool_t xdr_createargs(XDR *, createargs*);
-#else /* Old Style C */
-bool_t xdr_createargs();
-#endif /* Old Style C */
-
-
-struct renameargs {
- diropargs from;
- diropargs to;
-};
-typedef struct renameargs renameargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_renameargs(XDR *, renameargs*);
-#elif __STDC__
-extern bool_t xdr_renameargs(XDR *, renameargs*);
-#else /* Old Style C */
-bool_t xdr_renameargs();
-#endif /* Old Style C */
-
-
-struct linkargs {
- nfs_fh from;
- diropargs to;
-};
-typedef struct linkargs linkargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_linkargs(XDR *, linkargs*);
-#elif __STDC__
-extern bool_t xdr_linkargs(XDR *, linkargs*);
-#else /* Old Style C */
-bool_t xdr_linkargs();
-#endif /* Old Style C */
-
-
-struct symlinkargs {
- diropargs from;
- nfspath to;
- sattr attributes;
-};
-typedef struct symlinkargs symlinkargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_symlinkargs(XDR *, symlinkargs*);
-#elif __STDC__
-extern bool_t xdr_symlinkargs(XDR *, symlinkargs*);
-#else /* Old Style C */
-bool_t xdr_symlinkargs();
-#endif /* Old Style C */
-
-
-typedef char nfscookie[NFS_COOKIESIZE];
-#ifdef __cplusplus
-extern "C" bool_t xdr_nfscookie(XDR *, nfscookie);
-#elif __STDC__
-extern bool_t xdr_nfscookie(XDR *, nfscookie);
-#else /* Old Style C */
-bool_t xdr_nfscookie();
-#endif /* Old Style C */
-
-
-struct readdirargs {
- nfs_fh dir;
- nfscookie cookie;
- u_int count;
-};
-typedef struct readdirargs readdirargs;
-#ifdef __cplusplus
-extern "C" bool_t xdr_readdirargs(XDR *, readdirargs*);
-#elif __STDC__
-extern bool_t xdr_readdirargs(XDR *, readdirargs*);
-#else /* Old Style C */
-bool_t xdr_readdirargs();
-#endif /* Old Style C */
-
-
-struct entry {
- u_int fileid;
- filename name;
- nfscookie cookie;
- struct entry *nextentry;
-};
-typedef struct entry entry;
-#ifdef __cplusplus
-extern "C" bool_t xdr_entry(XDR *, entry*);
-#elif __STDC__
-extern bool_t xdr_entry(XDR *, entry*);
-#else /* Old Style C */
-bool_t xdr_entry();
-#endif /* Old Style C */
-
-
-struct dirlist {
- entry *entries;
- bool_t eof;
-};
-typedef struct dirlist dirlist;
-#ifdef __cplusplus
-extern "C" bool_t xdr_dirlist(XDR *, dirlist*);
-#elif __STDC__
-extern bool_t xdr_dirlist(XDR *, dirlist*);
-#else /* Old Style C */
-bool_t xdr_dirlist();
-#endif /* Old Style C */
-
-
-struct readdirres {
- nfsstat status;
- union {
- dirlist reply;
- } readdirres_u;
-};
-typedef struct readdirres readdirres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_readdirres(XDR *, readdirres*);
-#elif __STDC__
-extern bool_t xdr_readdirres(XDR *, readdirres*);
-#else /* Old Style C */
-bool_t xdr_readdirres();
-#endif /* Old Style C */
-
-
-struct statfsokres {
- u_int tsize;
- u_int bsize;
- u_int blocks;
- u_int bfree;
- u_int bavail;
-};
-typedef struct statfsokres statfsokres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_statfsokres(XDR *, statfsokres*);
-#elif __STDC__
-extern bool_t xdr_statfsokres(XDR *, statfsokres*);
-#else /* Old Style C */
-bool_t xdr_statfsokres();
-#endif /* Old Style C */
-
-
-struct statfsres {
- nfsstat status;
- union {
- statfsokres reply;
- } statfsres_u;
-};
-typedef struct statfsres statfsres;
-#ifdef __cplusplus
-extern "C" bool_t xdr_statfsres(XDR *, statfsres*);
-#elif __STDC__
-extern bool_t xdr_statfsres(XDR *, statfsres*);
-#else /* Old Style C */
-bool_t xdr_statfsres();
-#endif /* Old Style C */
-
-#endif /*!_rpcsvc_nfs_prot_h*/
-
-#define NFS_PROGRAM ((u_long)100003)
-#define NFS_VERSION ((u_long)2)
-
-#ifdef __cplusplus
-#define NFSPROC_NULL ((u_long)0)
-extern "C" void * nfsproc_null_2(void *, CLIENT *);
-extern "C" void * nfsproc_null_2_svc(void *, struct svc_req *);
-#define NFSPROC_GETATTR ((u_long)1)
-extern "C" attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *);
-extern "C" attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *);
-#define NFSPROC_SETATTR ((u_long)2)
-extern "C" attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *);
-extern "C" attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *);
-#define NFSPROC_ROOT ((u_long)3)
-extern "C" void * nfsproc_root_2(void *, CLIENT *);
-extern "C" void * nfsproc_root_2_svc(void *, struct svc_req *);
-#define NFSPROC_LOOKUP ((u_long)4)
-extern "C" diropres * nfsproc_lookup_2(diropargs *, CLIENT *);
-extern "C" diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_READLINK ((u_long)5)
-extern "C" readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *);
-extern "C" readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *);
-#define NFSPROC_READ ((u_long)6)
-extern "C" readres * nfsproc_read_2(readargs *, CLIENT *);
-extern "C" readres * nfsproc_read_2_svc(readargs *, struct svc_req *);
-#define NFSPROC_WRITECACHE ((u_long)7)
-extern "C" void * nfsproc_writecache_2(void *, CLIENT *);
-extern "C" void * nfsproc_writecache_2_svc(void *, struct svc_req *);
-#define NFSPROC_WRITE ((u_long)8)
-extern "C" attrstat * nfsproc_write_2(writeargs *, CLIENT *);
-extern "C" attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *);
-#define NFSPROC_CREATE ((u_long)9)
-extern "C" diropres * nfsproc_create_2(createargs *, CLIENT *);
-extern "C" diropres * nfsproc_create_2_svc(createargs *, struct svc_req *);
-#define NFSPROC_REMOVE ((u_long)10)
-extern "C" nfsstat * nfsproc_remove_2(diropargs *, CLIENT *);
-extern "C" nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_RENAME ((u_long)11)
-extern "C" nfsstat * nfsproc_rename_2(renameargs *, CLIENT *);
-extern "C" nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *);
-#define NFSPROC_LINK ((u_long)12)
-extern "C" nfsstat * nfsproc_link_2(linkargs *, CLIENT *);
-extern "C" nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *);
-#define NFSPROC_SYMLINK ((u_long)13)
-extern "C" nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *);
-extern "C" nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *);
-#define NFSPROC_MKDIR ((u_long)14)
-extern "C" diropres * nfsproc_mkdir_2(createargs *, CLIENT *);
-extern "C" diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *);
-#define NFSPROC_RMDIR ((u_long)15)
-extern "C" nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *);
-extern "C" nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_READDIR ((u_long)16)
-extern "C" readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *);
-extern "C" readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *);
-#define NFSPROC_STATFS ((u_long)17)
-extern "C" statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *);
-extern "C" statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *);
-
-#elif __STDC__
-#define NFSPROC_NULL ((u_long)0)
-extern void * nfsproc_null_2(void *, CLIENT *);
-extern void * nfsproc_null_2_svc(void *, struct svc_req *);
-#define NFSPROC_GETATTR ((u_long)1)
-extern attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *);
-extern attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *);
-#define NFSPROC_SETATTR ((u_long)2)
-extern attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *);
-extern attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *);
-#define NFSPROC_ROOT ((u_long)3)
-extern void * nfsproc_root_2(void *, CLIENT *);
-extern void * nfsproc_root_2_svc(void *, struct svc_req *);
-#define NFSPROC_LOOKUP ((u_long)4)
-extern diropres * nfsproc_lookup_2(diropargs *, CLIENT *);
-extern diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_READLINK ((u_long)5)
-extern readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *);
-extern readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *);
-#define NFSPROC_READ ((u_long)6)
-extern readres * nfsproc_read_2(readargs *, CLIENT *);
-extern readres * nfsproc_read_2_svc(readargs *, struct svc_req *);
-#define NFSPROC_WRITECACHE ((u_long)7)
-extern void * nfsproc_writecache_2(void *, CLIENT *);
-extern void * nfsproc_writecache_2_svc(void *, struct svc_req *);
-#define NFSPROC_WRITE ((u_long)8)
-extern attrstat * nfsproc_write_2(writeargs *, CLIENT *);
-extern attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *);
-#define NFSPROC_CREATE ((u_long)9)
-extern diropres * nfsproc_create_2(createargs *, CLIENT *);
-extern diropres * nfsproc_create_2_svc(createargs *, struct svc_req *);
-#define NFSPROC_REMOVE ((u_long)10)
-extern nfsstat * nfsproc_remove_2(diropargs *, CLIENT *);
-extern nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_RENAME ((u_long)11)
-extern nfsstat * nfsproc_rename_2(renameargs *, CLIENT *);
-extern nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *);
-#define NFSPROC_LINK ((u_long)12)
-extern nfsstat * nfsproc_link_2(linkargs *, CLIENT *);
-extern nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *);
-#define NFSPROC_SYMLINK ((u_long)13)
-extern nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *);
-extern nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *);
-#define NFSPROC_MKDIR ((u_long)14)
-extern diropres * nfsproc_mkdir_2(createargs *, CLIENT *);
-extern diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *);
-#define NFSPROC_RMDIR ((u_long)15)
-extern nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *);
-extern nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *);
-#define NFSPROC_READDIR ((u_long)16)
-extern readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *);
-extern readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *);
-#define NFSPROC_STATFS ((u_long)17)
-extern statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *);
-extern statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *);
-
-#else /* Old Style C */
-#define NFSPROC_NULL ((u_long)0)
-extern void * nfsproc_null_2();
-extern void * nfsproc_null_2_svc();
-#define NFSPROC_GETATTR ((u_long)1)
-extern attrstat * nfsproc_getattr_2();
-extern attrstat * nfsproc_getattr_2_svc();
-#define NFSPROC_SETATTR ((u_long)2)
-extern attrstat * nfsproc_setattr_2();
-extern attrstat * nfsproc_setattr_2_svc();
-#define NFSPROC_ROOT ((u_long)3)
-extern void * nfsproc_root_2();
-extern void * nfsproc_root_2_svc();
-#define NFSPROC_LOOKUP ((u_long)4)
-extern diropres * nfsproc_lookup_2();
-extern diropres * nfsproc_lookup_2_svc();
-#define NFSPROC_READLINK ((u_long)5)
-extern readlinkres * nfsproc_readlink_2();
-extern readlinkres * nfsproc_readlink_2_svc();
-#define NFSPROC_READ ((u_long)6)
-extern readres * nfsproc_read_2();
-extern readres * nfsproc_read_2_svc();
-#define NFSPROC_WRITECACHE ((u_long)7)
-extern void * nfsproc_writecache_2();
-extern void * nfsproc_writecache_2_svc();
-#define NFSPROC_WRITE ((u_long)8)
-extern attrstat * nfsproc_write_2();
-extern attrstat * nfsproc_write_2_svc();
-#define NFSPROC_CREATE ((u_long)9)
-extern diropres * nfsproc_create_2();
-extern diropres * nfsproc_create_2_svc();
-#define NFSPROC_REMOVE ((u_long)10)
-extern nfsstat * nfsproc_remove_2();
-extern nfsstat * nfsproc_remove_2_svc();
-#define NFSPROC_RENAME ((u_long)11)
-extern nfsstat * nfsproc_rename_2();
-extern nfsstat * nfsproc_rename_2_svc();
-#define NFSPROC_LINK ((u_long)12)
-extern nfsstat * nfsproc_link_2();
-extern nfsstat * nfsproc_link_2_svc();
-#define NFSPROC_SYMLINK ((u_long)13)
-extern nfsstat * nfsproc_symlink_2();
-extern nfsstat * nfsproc_symlink_2_svc();
-#define NFSPROC_MKDIR ((u_long)14)
-extern diropres * nfsproc_mkdir_2();
-extern diropres * nfsproc_mkdir_2_svc();
-#define NFSPROC_RMDIR ((u_long)15)
-extern nfsstat * nfsproc_rmdir_2();
-extern nfsstat * nfsproc_rmdir_2_svc();
-#define NFSPROC_READDIR ((u_long)16)
-extern readdirres * nfsproc_readdir_2();
-extern readdirres * nfsproc_readdir_2_svc();
-#define NFSPROC_STATFS ((u_long)17)
-extern statfsres * nfsproc_statfs_2();
-extern statfsres * nfsproc_statfs_2_svc();
-#endif /* Old Style C */
-
-#endif /* !_NFS_PROT_H_RPCGEN */
diff --git a/nfs/nfs_prot.x b/nfs/nfs_prot.x
deleted file mode 100644
index cd21123c7b57040d97245f22038153945abe88ee..0000000000000000000000000000000000000000
--- a/nfs/nfs_prot.x
+++ /dev/null
@@ -1,365 +0,0 @@
-%/*
-% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
-% * unrestricted use provided that this legend is included on all tape
-% * media and as a part of the software program in whole or part. Users
-% * may copy or modify Sun RPC without charge, but are not authorized
-% * to license or distribute it to anyone else except as part of a product or
-% * program developed by the user or with the express written consent of
-% * Sun Microsystems, Inc.
-% *
-% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
-% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
-% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
-% *
-% * Sun RPC is provided with no support and without any obligation on the
-% * part of Sun Microsystems, Inc. to assist in its use, correction,
-% * modification or enhancement.
-% *
-% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
-% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
-% * OR ANY PART THEREOF.
-% *
-% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
-% * or profits or other special, indirect and consequential damages, even if
-% * Sun has been advised of the possibility of such damages.
-% *
-% * Sun Microsystems, Inc.
-% * 2550 Garcia Avenue
-% * Mountain View, California 94043
-% */
-
-%/*
-% * Copyright (c) 1987, 1990 by Sun Microsystems, Inc.
-% */
-%
-%/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */
-
-#ifdef RPC_HDR
-%#ifndef _rpcsvc_nfs_prot_h
-%#define _rpcsvc_nfs_prot_h
-#endif
-
-const NFS_PORT = 2049;
-const NFS_MAXDATA = 8192;
-const NFS_MAXPATHLEN = 1024;
-const NFS_MAXNAMLEN = 255;
-const NFS_FHSIZE = 32;
-const NFS_COOKIESIZE = 4;
-const NFS_FIFO_DEV = -1; /* size kludge for named pipes */
-
-/*
- * File types
- */
-const NFSMODE_FMT = 0170000; /* type of file */
-const NFSMODE_DIR = 0040000; /* directory */
-const NFSMODE_CHR = 0020000; /* character special */
-const NFSMODE_BLK = 0060000; /* block special */
-const NFSMODE_REG = 0100000; /* regular */
-const NFSMODE_LNK = 0120000; /* symbolic link */
-const NFSMODE_SOCK = 0140000; /* socket */
-const NFSMODE_FIFO = 0010000; /* fifo */
-
-/*
- * Error status
- */
-enum nfsstat {
- NFS_OK= 0, /* no error */
- NFSERR_PERM=1, /* Not owner */
- NFSERR_NOENT=2, /* No such file or directory */
- NFSERR_IO=5, /* I/O error */
- NFSERR_NXIO=6, /* No such device or address */
- NFSERR_ACCES=13, /* Permission denied */
- NFSERR_EXIST=17, /* File exists */
- NFSERR_NODEV=19, /* No such device */
- NFSERR_NOTDIR=20, /* Not a directory*/
- NFSERR_ISDIR=21, /* Is a directory */
- NFSERR_INVAL=22, /* invalid argument */
- NFSERR_FBIG=27, /* File too large */
- NFSERR_NOSPC=28, /* No space left on device */
- NFSERR_ROFS=30, /* Read-only file system */
- NFSERR_NAMETOOLONG=63, /* File name too long */
- NFSERR_NOTEMPTY=66, /* Directory not empty */
- NFSERR_DQUOT=69, /* Disc quota exceeded */
- NFSERR_STALE=70, /* Stale NFS file handle */
- NFSERR_WFLUSH=99 /* write cache flushed */
-};
-
-/*
- * File types
- */
-enum ftype {
- NFNON = 0, /* non-file */
- NFREG = 1, /* regular file */
- NFDIR = 2, /* directory */
- NFBLK = 3, /* block special */
- NFCHR = 4, /* character special */
- NFLNK = 5, /* symbolic link */
- NFSOCK = 6, /* unix domain sockets */
- NFBAD = 7, /* unused */
- NFFIFO = 8 /* named pipe */
-};
-
-/*
- * File access handle
- */
-struct nfs_fh {
- opaque data[NFS_FHSIZE];
-};
-
-/*
- * Timeval
- */
-struct nfstime {
- unsigned seconds;
- unsigned useconds;
-};
-
-
-/*
- * File attributes
- */
-struct fattr {
- ftype type; /* file type */
- unsigned mode; /* protection mode bits */
- unsigned nlink; /* # hard links */
- unsigned uid; /* owner user id */
- unsigned gid; /* owner group id */
- unsigned size; /* file size in bytes */
- unsigned blocksize; /* prefered block size */
- unsigned rdev; /* special device # */
- unsigned blocks; /* Kb of disk used by file */
- unsigned fsid; /* device # */
- unsigned fileid; /* inode # */
- nfstime atime; /* time of last access */
- nfstime mtime; /* time of last modification */
- nfstime ctime; /* time of last change */
-};
-
-/*
- * File attributes which can be set
- */
-struct sattr {
- unsigned mode; /* protection mode bits */
- unsigned uid; /* owner user id */
- unsigned gid; /* owner group id */
- unsigned size; /* file size in bytes */
- nfstime atime; /* time of last access */
- nfstime mtime; /* time of last modification */
-};
-
-
-typedef string filename<NFS_MAXNAMLEN>;
-typedef string nfspath<NFS_MAXPATHLEN>;
-
-/*
- * Reply status with file attributes
- */
-union attrstat switch (nfsstat status) {
-case NFS_OK:
- fattr attributes;
-default:
- void;
-};
-
-struct sattrargs {
- nfs_fh file;
- sattr attributes;
-};
-
-/*
- * Arguments for directory operations
- */
-struct diropargs {
- nfs_fh dir; /* directory file handle */
- filename name; /* name (up to NFS_MAXNAMLEN bytes) */
-};
-
-struct diropokres {
- nfs_fh file;
- fattr attributes;
-};
-
-/*
- * Results from directory operation
- */
-union diropres switch (nfsstat status) {
-case NFS_OK:
- diropokres diropres;
-default:
- void;
-};
-
-union readlinkres switch (nfsstat status) {
-case NFS_OK:
- nfspath data;
-default:
- void;
-};
-
-/*
- * Arguments to remote read
- */
-struct readargs {
- nfs_fh file; /* handle for file */
- unsigned offset; /* byte offset in file */
- unsigned count; /* immediate read count */
- unsigned totalcount; /* total read count (from this offset)*/
-};
-
-/*
- * Status OK portion of remote read reply
- */
-struct readokres {
- fattr attributes; /* attributes, need for pagin*/
- opaque data<NFS_MAXDATA>;
-};
-
-union readres switch (nfsstat status) {
-case NFS_OK:
- readokres reply;
-default:
- void;
-};
-
-/*
- * Arguments to remote write
- */
-struct writeargs {
- nfs_fh file; /* handle for file */
- unsigned beginoffset; /* beginning byte offset in file */
- unsigned offset; /* current byte offset in file */
- unsigned totalcount; /* total write count (to this offset)*/
- opaque data<NFS_MAXDATA>;
-};
-
-struct createargs {
- diropargs where;
- sattr attributes;
-};
-
-struct renameargs {
- diropargs from;
- diropargs to;
-};
-
-struct linkargs {
- nfs_fh from;
- diropargs to;
-};
-
-struct symlinkargs {
- diropargs from;
- nfspath to;
- sattr attributes;
-};
-
-
-typedef opaque nfscookie[NFS_COOKIESIZE];
-
-/*
- * Arguments to readdir
- */
-struct readdirargs {
- nfs_fh dir; /* directory handle */
- nfscookie cookie;
- unsigned count; /* number of directory bytes to read */
-};
-
-struct entry {
- unsigned fileid;
- filename name;
- nfscookie cookie;
- entry *nextentry;
-};
-
-struct dirlist {
- entry *entries;
- bool eof;
-};
-
-union readdirres switch (nfsstat status) {
-case NFS_OK:
- dirlist reply;
-default:
- void;
-};
-
-struct statfsokres {
- unsigned tsize; /* preferred transfer size in bytes */
- unsigned bsize; /* fundamental file system block size */
- unsigned blocks; /* total blocks in file system */
- unsigned bfree; /* free blocks in fs */
- unsigned bavail; /* free blocks avail to non-superuser */
-};
-
-union statfsres switch (nfsstat status) {
-case NFS_OK:
- statfsokres reply;
-default:
- void;
-};
-
-/*
- * Remote file service routines
- */
-program NFS_PROGRAM {
- version NFS_VERSION {
- void
- NFSPROC_NULL(void) = 0;
-
- attrstat
- NFSPROC_GETATTR(nfs_fh) = 1;
-
- attrstat
- NFSPROC_SETATTR(sattrargs) = 2;
-
- void
- NFSPROC_ROOT(void) = 3;
-
- diropres
- NFSPROC_LOOKUP(diropargs) = 4;
-
- readlinkres
- NFSPROC_READLINK(nfs_fh) = 5;
-
- readres
- NFSPROC_READ(readargs) = 6;
-
- void
- NFSPROC_WRITECACHE(void) = 7;
-
- attrstat
- NFSPROC_WRITE(writeargs) = 8;
-
- diropres
- NFSPROC_CREATE(createargs) = 9;
-
- nfsstat
- NFSPROC_REMOVE(diropargs) = 10;
-
- nfsstat
- NFSPROC_RENAME(renameargs) = 11;
-
- nfsstat
- NFSPROC_LINK(linkargs) = 12;
-
- nfsstat
- NFSPROC_SYMLINK(symlinkargs) = 13;
-
- diropres
- NFSPROC_MKDIR(createargs) = 14;
-
- nfsstat
- NFSPROC_RMDIR(diropargs) = 15;
-
- readdirres
- NFSPROC_READDIR(readdirargs) = 16;
-
- statfsres
- NFSPROC_STATFS(nfs_fh) = 17;
- } = 2;
-} = 100003;
-
-#ifdef RPC_HDR
-%#endif /*!_rpcsvc_nfs_prot_h*/
-#endif
diff --git a/nfs/nfs_prot_xdr.c b/nfs/nfs_prot_xdr.c
deleted file mode 100644
index cd1354668d40616a0a0864bc6b3d68ccc5ef3e4f..0000000000000000000000000000000000000000
--- a/nfs/nfs_prot_xdr.c
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Please do not edit this file.
- * It was generated using rpcgen.
- */
-
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <arpa/inet.h>
-
-#include "nfs_prot.h"
-/*
- * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
- * unrestricted use provided that this legend is included on all tape
- * media and as a part of the software program in whole or part. Users
- * may copy or modify Sun RPC without charge, but are not authorized
- * to license or distribute it to anyone else except as part of a product or
- * program developed by the user or with the express written consent of
- * Sun Microsystems, Inc.
- *
- * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
- * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun RPC is provided with no support and without any obligation on the
- * part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-/*
- * Copyright (c) 1987, 1990 by Sun Microsystems, Inc.
- */
-
-/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */
-
-bool_t
-xdr_nfsstat(XDR *xdrs, nfsstat *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_enum(xdrs, (enum_t *)objp)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_ftype(XDR *xdrs, ftype *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_enum(xdrs, (enum_t *)objp)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_nfs_fh(XDR *xdrs, nfs_fh *objp)
-{
-
- register int32_t *buf=buf;
-
- int i=i;
- if (!xdr_opaque(xdrs, objp->data, NFS_FHSIZE)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_nfstime(XDR *xdrs, nfstime *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_u_int(xdrs, &objp->seconds)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->useconds)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_fattr(XDR *xdrs, fattr *objp)
-{
-
- register int32_t *buf=buf;
-
-
- if (xdrs->x_op == XDR_ENCODE) {
- if (!xdr_ftype(xdrs, &objp->type)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs,10 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->mode)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->nlink)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->uid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->gid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->size)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocksize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->rdev)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocks)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->fsid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->fileid)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_U_LONG(buf,objp->mode);
- IXDR_PUT_U_LONG(buf,objp->nlink);
- IXDR_PUT_U_LONG(buf,objp->uid);
- IXDR_PUT_U_LONG(buf,objp->gid);
- IXDR_PUT_U_LONG(buf,objp->size);
- IXDR_PUT_U_LONG(buf,objp->blocksize);
- IXDR_PUT_U_LONG(buf,objp->rdev);
- IXDR_PUT_U_LONG(buf,objp->blocks);
- IXDR_PUT_U_LONG(buf,objp->fsid);
- IXDR_PUT_U_LONG(buf,objp->fileid);
- }
- if (!xdr_nfstime(xdrs, &objp->atime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->mtime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->ctime)) {
- return (FALSE);
- }
-
- return (TRUE);
- } else if (xdrs->x_op == XDR_DECODE) {
- if (!xdr_ftype(xdrs, &objp->type)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs,10 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->mode)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->nlink)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->uid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->gid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->size)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocksize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->rdev)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocks)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->fsid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->fileid)) {
- return (FALSE);
- }
-
- }
- else {
- objp->mode = IXDR_GET_U_LONG(buf);
- objp->nlink = IXDR_GET_U_LONG(buf);
- objp->uid = IXDR_GET_U_LONG(buf);
- objp->gid = IXDR_GET_U_LONG(buf);
- objp->size = IXDR_GET_U_LONG(buf);
- objp->blocksize = IXDR_GET_U_LONG(buf);
- objp->rdev = IXDR_GET_U_LONG(buf);
- objp->blocks = IXDR_GET_U_LONG(buf);
- objp->fsid = IXDR_GET_U_LONG(buf);
- objp->fileid = IXDR_GET_U_LONG(buf);
- }
- if (!xdr_nfstime(xdrs, &objp->atime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->mtime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->ctime)) {
- return (FALSE);
- }
- return(TRUE);
- }
-
- if (!xdr_ftype(xdrs, &objp->type)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->mode)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->nlink)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->uid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->gid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->size)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocksize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->rdev)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocks)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->fsid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->fileid)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->atime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->mtime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->ctime)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_sattr(XDR *xdrs, sattr *objp)
-{
-
- register int32_t *buf=buf;
-
-
- if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE(xdrs,4 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->mode)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->uid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->gid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->size)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_U_LONG(buf,objp->mode);
- IXDR_PUT_U_LONG(buf,objp->uid);
- IXDR_PUT_U_LONG(buf,objp->gid);
- IXDR_PUT_U_LONG(buf,objp->size);
- }
- if (!xdr_nfstime(xdrs, &objp->atime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->mtime)) {
- return (FALSE);
- }
-
- return (TRUE);
- } else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE(xdrs,4 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->mode)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->uid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->gid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->size)) {
- return (FALSE);
- }
-
- }
- else {
- objp->mode = IXDR_GET_U_LONG(buf);
- objp->uid = IXDR_GET_U_LONG(buf);
- objp->gid = IXDR_GET_U_LONG(buf);
- objp->size = IXDR_GET_U_LONG(buf);
- }
- if (!xdr_nfstime(xdrs, &objp->atime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->mtime)) {
- return (FALSE);
- }
- return(TRUE);
- }
-
- if (!xdr_u_int(xdrs, &objp->mode)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->uid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->gid)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->size)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->atime)) {
- return (FALSE);
- }
- if (!xdr_nfstime(xdrs, &objp->mtime)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_filename(XDR *xdrs, filename *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_string(xdrs, objp, NFS_MAXNAMLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_nfspath(XDR *xdrs, nfspath *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_attrstat(XDR *xdrs, attrstat *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfsstat(xdrs, &objp->status)) {
- return (FALSE);
- }
- switch (objp->status) {
- case NFS_OK:
- if (!xdr_fattr(xdrs, &objp->attrstat_u.attributes)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_sattrargs(XDR *xdrs, sattrargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfs_fh(xdrs, &objp->file)) {
- return (FALSE);
- }
- if (!xdr_sattr(xdrs, &objp->attributes)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_diropargs(XDR *xdrs, diropargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfs_fh(xdrs, &objp->dir)) {
- return (FALSE);
- }
- if (!xdr_filename(xdrs, &objp->name)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_diropokres(XDR *xdrs, diropokres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfs_fh(xdrs, &objp->file)) {
- return (FALSE);
- }
- if (!xdr_fattr(xdrs, &objp->attributes)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_diropres(XDR *xdrs, diropres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfsstat(xdrs, &objp->status)) {
- return (FALSE);
- }
- switch (objp->status) {
- case NFS_OK:
- if (!xdr_diropokres(xdrs, &objp->diropres_u.diropres)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_readlinkres(XDR *xdrs, readlinkres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfsstat(xdrs, &objp->status)) {
- return (FALSE);
- }
- switch (objp->status) {
- case NFS_OK:
- if (!xdr_nfspath(xdrs, &objp->readlinkres_u.data)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_readargs(XDR *xdrs, readargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfs_fh(xdrs, &objp->file)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->offset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->count)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->totalcount)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_readokres(XDR *xdrs, readokres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_fattr(xdrs, &objp->attributes)) {
- return (FALSE);
- }
- if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_readres(XDR *xdrs, readres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfsstat(xdrs, &objp->status)) {
- return (FALSE);
- }
- switch (objp->status) {
- case NFS_OK:
- if (!xdr_readokres(xdrs, &objp->readres_u.reply)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_writeargs(XDR *xdrs, writeargs *objp)
-{
-
- register int32_t *buf=buf;
-
-
- if (xdrs->x_op == XDR_ENCODE) {
- if (!xdr_nfs_fh(xdrs, &objp->file)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs,3 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->beginoffset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->offset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->totalcount)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_U_LONG(buf,objp->beginoffset);
- IXDR_PUT_U_LONG(buf,objp->offset);
- IXDR_PUT_U_LONG(buf,objp->totalcount);
- }
- if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) {
- return (FALSE);
- }
-
- return (TRUE);
- } else if (xdrs->x_op == XDR_DECODE) {
- if (!xdr_nfs_fh(xdrs, &objp->file)) {
- return (FALSE);
- }
- buf = XDR_INLINE(xdrs,3 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->beginoffset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->offset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->totalcount)) {
- return (FALSE);
- }
-
- }
- else {
- objp->beginoffset = IXDR_GET_U_LONG(buf);
- objp->offset = IXDR_GET_U_LONG(buf);
- objp->totalcount = IXDR_GET_U_LONG(buf);
- }
- if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) {
- return (FALSE);
- }
- return(TRUE);
- }
-
- if (!xdr_nfs_fh(xdrs, &objp->file)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->beginoffset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->offset)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->totalcount)) {
- return (FALSE);
- }
- if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_createargs(XDR *xdrs, createargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_diropargs(xdrs, &objp->where)) {
- return (FALSE);
- }
- if (!xdr_sattr(xdrs, &objp->attributes)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_renameargs(XDR *xdrs, renameargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_diropargs(xdrs, &objp->from)) {
- return (FALSE);
- }
- if (!xdr_diropargs(xdrs, &objp->to)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_linkargs(XDR *xdrs, linkargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfs_fh(xdrs, &objp->from)) {
- return (FALSE);
- }
- if (!xdr_diropargs(xdrs, &objp->to)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_symlinkargs(XDR *xdrs, symlinkargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_diropargs(xdrs, &objp->from)) {
- return (FALSE);
- }
- if (!xdr_nfspath(xdrs, &objp->to)) {
- return (FALSE);
- }
- if (!xdr_sattr(xdrs, &objp->attributes)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_nfscookie(XDR *xdrs, nfscookie objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_opaque(xdrs, objp, NFS_COOKIESIZE)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_readdirargs(XDR *xdrs, readdirargs *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfs_fh(xdrs, &objp->dir)) {
- return (FALSE);
- }
- if (!xdr_nfscookie(xdrs, objp->cookie)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->count)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_entry(XDR *xdrs, entry *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_u_int(xdrs, &objp->fileid)) {
- return (FALSE);
- }
- if (!xdr_filename(xdrs, &objp->name)) {
- return (FALSE);
- }
- if (!xdr_nfscookie(xdrs, objp->cookie)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs, (char **)&objp->nextentry, sizeof(entry), (xdrproc_t)xdr_entry)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_dirlist(XDR *xdrs, dirlist *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_pointer(xdrs, (char **)&objp->entries, sizeof(entry), (xdrproc_t)xdr_entry)) {
- return (FALSE);
- }
- if (!xdr_bool(xdrs, &objp->eof)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_readdirres(XDR *xdrs, readdirres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfsstat(xdrs, &objp->status)) {
- return (FALSE);
- }
- switch (objp->status) {
- case NFS_OK:
- if (!xdr_dirlist(xdrs, &objp->readdirres_u.reply)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
-
-bool_t
-xdr_statfsokres(XDR *xdrs, statfsokres *objp)
-{
-
- register int32_t *buf=buf;
-
-
- if (xdrs->x_op == XDR_ENCODE) {
- buf = XDR_INLINE(xdrs,5 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->tsize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bsize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocks)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bfree)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bavail)) {
- return (FALSE);
- }
-
- }
- else {
- IXDR_PUT_U_LONG(buf,objp->tsize);
- IXDR_PUT_U_LONG(buf,objp->bsize);
- IXDR_PUT_U_LONG(buf,objp->blocks);
- IXDR_PUT_U_LONG(buf,objp->bfree);
- IXDR_PUT_U_LONG(buf,objp->bavail);
- }
-
- return (TRUE);
- } else if (xdrs->x_op == XDR_DECODE) {
- buf = XDR_INLINE(xdrs,5 * BYTES_PER_XDR_UNIT);
- if (buf == NULL) {
- if (!xdr_u_int(xdrs, &objp->tsize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bsize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocks)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bfree)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bavail)) {
- return (FALSE);
- }
-
- }
- else {
- objp->tsize = IXDR_GET_U_LONG(buf);
- objp->bsize = IXDR_GET_U_LONG(buf);
- objp->blocks = IXDR_GET_U_LONG(buf);
- objp->bfree = IXDR_GET_U_LONG(buf);
- objp->bavail = IXDR_GET_U_LONG(buf);
- }
- return(TRUE);
- }
-
- if (!xdr_u_int(xdrs, &objp->tsize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bsize)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->blocks)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bfree)) {
- return (FALSE);
- }
- if (!xdr_u_int(xdrs, &objp->bavail)) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-bool_t
-xdr_statfsres(XDR *xdrs, statfsres *objp)
-{
-
- register int32_t *buf=buf;
-
- if (!xdr_nfsstat(xdrs, &objp->status)) {
- return (FALSE);
- }
- switch (objp->status) {
- case NFS_OK:
- if (!xdr_statfsokres(xdrs, &objp->statfsres_u.reply)) {
- return (FALSE);
- }
- break;
- default:
- break;
- }
- return (TRUE);
-}
diff --git a/nfs/nfsv2.cpp b/nfs/nfsv2.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..67a5ed1a48e6c4908354c79aff5d96fda75ff604
--- /dev/null
+++ b/nfs/nfsv2.cpp
@@ -0,0 +1,1858 @@
+/* This file is part of the KDE project
+
+ Copyright(C) 2000 Alexander Neundorf <neundorf@kde.org>,
+ 2014 Mathias Tillman <master.homer@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <config-runtime.h>
+
+#include <arpa/inet.h>
+
+// This is needed on Solaris so that rpc.h defines clnttcp_create etc.
+#ifndef PORTMAP
+#define PORTMAP
+#endif
+#include <rpc/rpc.h> // for rpc calls
+
+#include <errno.h>
+#include <grp.h>
+#include <memory.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+#include <QLoggingCategory>
+#include <QMimeDatabase>
+#include <QMimeType>
+
+#include <KLocalizedString>
+#include <kio/global.h>
+#include <kio/ioslave_defaults.h>
+#include <iostream>
+
+#include "nfsv2.h"
+
+// This is for NFS version 2.
+#define NFSPROG 100003UL
+#define NFSVERS 2UL
+
+
+NFSProtocolV2::NFSProtocolV2(NFSSlave* slave)
+ : NFSProtocol(slave),
+ m_slave(slave),
+ m_mountClient(0),
+ m_mountSock(-1),
+ m_nfsClient(0),
+ m_nfsSock(-1)
+{
+ qCDebug(LOG_KIO_NFS) << "NFS2::NFS2";
+
+ clnt_timeout.tv_sec = 20;
+ clnt_timeout.tv_usec = 0;
+}
+
+NFSProtocolV2::~NFSProtocolV2()
+{
+ closeConnection();
+}
+
+bool NFSProtocolV2::isCompatible(bool& connectionError)
+{
+ int ret = -1;
+
+ CLIENT* client = NULL;
+ int sock = 0;
+ if (NFSProtocol::openConnection(m_currentHost, NFSPROG, NFSVERS, client, sock) == 0) {
+ // Check if the NFS version is compatible
+ ret = clnt_call(client, NFSPROC_NULL,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_void, NULL, clnt_timeout);
+
+ connectionError = false;
+ } else {
+ qCDebug(LOG_KIO_NFS) << "openConnection failed";
+ connectionError = true;
+ }
+
+ if (sock != -1) {
+ ::close(sock);
+ }
+
+ if (client != NULL) {
+ CLNT_DESTROY(client);
+ }
+
+ qCDebug(LOG_KIO_NFS) << ret;
+ return (ret == RPC_SUCCESS);
+}
+
+bool NFSProtocolV2::isConnected() const
+{
+ return (m_nfsClient != 0);
+}
+
+void NFSProtocolV2::closeConnection()
+{
+ qCDebug(LOG_KIO_NFS);
+
+ // Unmount all exported dirs(if any)
+ if (m_mountClient != 0) {
+ clnt_call(m_mountClient, MOUNTPROC_UMNTALL,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_void, NULL,
+ clnt_timeout);
+ }
+
+ if (m_mountSock >= 0) {
+ ::close(m_mountSock);
+ m_mountSock = -1;
+ }
+ if (m_nfsSock >= 0) {
+ ::close(m_nfsSock);
+ m_nfsSock = -1;
+ }
+
+ if (m_mountClient != 0) {
+ CLNT_DESTROY(m_mountClient);
+ m_mountClient = 0;
+ }
+ if (m_nfsClient != 0) {
+ CLNT_DESTROY(m_nfsClient);
+ m_nfsClient = 0;
+ }
+}
+
+NFSFileHandle NFSProtocolV2::lookupFileHandle(const QString& path)
+{
+ int rpcStatus;
+ diropres res;
+ if (lookupHandle(path, rpcStatus, res)) {
+ NFSFileHandle fh = res.diropres_u.diropres.file;
+
+ // It it a link? Get the link target.
+ if (res.diropres_u.diropres.attributes.type == NFLNK) {
+ nfs_fh readLinkArgs;
+ fh.toFH(readLinkArgs);
+
+ char dataBuffer[NFS_MAXPATHLEN];
+
+ readlinkres readLinkRes;
+ memset(&readLinkRes, 0, sizeof(readLinkRes));
+ readLinkRes.readlinkres_u.data = dataBuffer;
+
+ int rpcStatus = clnt_call(m_nfsClient, NFSPROC_READLINK,
+ (xdrproc_t) xdr_nfs_fh, reinterpret_cast<caddr_t>(&readLinkArgs),
+ (xdrproc_t) xdr_readlinkres, reinterpret_cast<caddr_t>(&readLinkRes),
+ clnt_timeout);
+
+ if (rpcStatus == RPC_SUCCESS && readLinkRes.status == NFS_OK) {
+ const QString linkDest = QString::fromLocal8Bit(readLinkRes.readlinkres_u.data);
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(QFileInfo(path).path(), linkDest).absoluteFilePath();
+ }
+
+ diropres linkRes;
+ if (lookupHandle(linkPath, rpcStatus, linkRes)) {
+ NFSFileHandle linkFH = linkRes.diropres_u.diropres.file;
+ linkFH.setLinkSource(res.diropres_u.diropres.file);
+
+ qCDebug(LOG_KIO_NFS) << "Found target -" << linkPath;
+
+ return linkFH;
+ }
+ }
+
+ // If we have reached this point the file is a link, but we failed to get the target.
+ fh.setBadLink();
+ }
+
+ return fh;
+ }
+
+ return NFSFileHandle();
+}
+
+/* Open connection connects to the mount daemon on the server side.
+ In order to do this it needs authentication and calls auth_unix_create().
+ Then it asks the mount daemon for the exported shares. Then it tries
+ to mount all these shares. If this succeeded for at least one of them,
+ a client for the nfs daemon is created.
+ */
+void NFSProtocolV2::openConnection()
+{
+ qCDebug(LOG_KIO_NFS) << m_currentHost;
+
+ int connErr;
+ if ((connErr = NFSProtocol::openConnection(m_currentHost, MOUNTPROG, MOUNTVERS, m_mountClient, m_mountSock)) != 0) {
+ // Close the connection and send the error id to the slave
+ closeConnection();
+ m_slave->error(connErr, m_currentHost);
+ return;
+ }
+
+ exports exportlist;
+ memset(&exportlist, 0, sizeof(exportlist));
+
+ int clnt_stat = clnt_call(m_mountClient, MOUNTPROC_EXPORT,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_exports, reinterpret_cast<caddr_t>(&exportlist),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, 0, m_currentHost.toLatin1())) {
+ return;
+ }
+
+ int exportsCount = 0;
+ QStringList failList;
+
+ fhstatus fhStatus;
+ for (; exportlist != 0; exportlist = exportlist->ex_next, exportsCount++) {
+ memset(&fhStatus, 0, sizeof(fhStatus));
+
+ clnt_stat = clnt_call(m_mountClient, MOUNTPROC_MNT,
+ (xdrproc_t) xdr_dirpath, reinterpret_cast<caddr_t>(&exportlist->ex_dir),
+ (xdrproc_t) xdr_fhstatus, reinterpret_cast<caddr_t>(&fhStatus),
+ clnt_timeout);
+
+ if (fhStatus.fhs_status == 0) {
+ QString fname = QFileInfo(QDir("/"), exportlist->ex_dir).filePath();
+
+ // Check if the dir is already exported
+ if (NFSProtocol::isExportedDir(fname)) {
+ continue;
+ }
+
+ addFileHandle(fname, static_cast<NFSFileHandle>(fhStatus.fhstatus_u.fhs_fhandle));
+ addExportedDir(fname);
+ } else {
+ failList.append(exportlist->ex_dir);
+ }
+ }
+
+ // Check if some exported dirs failed to mount
+ if (failList.size() > 0) {
+ m_slave->error(KIO::ERR_COULD_NOT_MOUNT, i18n("Failed to mount %1", failList.join(", ")));
+
+ // All exports failed to mount, fail
+ if (failList.size() == exportsCount) {
+ closeConnection();
+ return;
+ }
+ }
+
+ if ((connErr = NFSProtocol::openConnection(m_currentHost, NFSPROG, NFSVERS, m_nfsClient, m_nfsSock)) != 0) {
+ closeConnection();
+ m_slave->error(connErr, m_currentHost);
+ }
+
+ m_slave->connected();
+
+ qCDebug(LOG_KIO_NFS) << "openConnection succeeded";
+}
+
+void NFSProtocolV2::listDir(const QUrl& url)
+{
+ // We should always be connected if it reaches this point,
+ // but better safe than sorry!
+ if (!isConnected()) {
+ return;
+ }
+
+ if (url.isEmpty()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, url.path());
+
+ return;
+ }
+
+ const QString path(url.path());
+
+ // The root "directory" is just a list of the exported directories,
+ // so list them here.
+ if (isExportedDir(path)) {
+ qCDebug(LOG_KIO_NFS) << "Listing exported dir";
+
+ QStringList virtualList;
+ for (QStringList::const_iterator it = getExportedDirs().constBegin(); it != getExportedDirs().constEnd(); ++it) {
+ // When an export is multiple levels deep(mnt/nfs for example) we only
+ // want to display one level at a time.
+ QString name = (*it);
+ name = name.remove(0, path.length());
+ if (name.startsWith('/')) {
+ name = name.mid(1);
+ }
+ if (name.indexOf('/') != -1) {
+ name.truncate(name.indexOf('/'));
+ }
+
+ if (!virtualList.contains(name)) {
+ virtualList.append(name);
+ }
+ }
+
+ for (QStringList::const_iterator it = virtualList.constBegin(); it != virtualList.constEnd(); ++it) {
+ qCDebug(LOG_KIO_NFS) << (*it) << "found in exported dir";
+
+ KIO::UDSEntry entry;
+ entry.insert(KIO::UDSEntry::UDS_NAME, (*it));
+
+ createVirtualDirEntry(entry);
+ m_slave->listEntry(entry);
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ readdirargs listargs;
+ memset(&listargs, 0, sizeof(listargs));
+ listargs.count = 1024 * sizeof(entry);
+ fh.toFH(listargs.dir);
+
+ readdirres listres;
+
+ QStringList filesToList;
+ entry* lastEntry = 0;
+ do {
+ memset(&listres, 0, sizeof(listres));
+ // In case that we didn't get all entries we need to set the cookie to the last one we actually received.
+ if (lastEntry != 0) {
+ memcpy(listargs.cookie, lastEntry->cookie, NFS_COOKIESIZE);
+ }
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_READDIR,
+ (xdrproc_t) xdr_readdirargs, reinterpret_cast<caddr_t>(&listargs),
+ (xdrproc_t) xdr_readdirres, reinterpret_cast<caddr_t>(&listres),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, listres.status, path)) {
+ return;
+ }
+
+ for (entry* dirEntry = listres.readdirres_u.reply.entries; dirEntry != 0; dirEntry = dirEntry->nextentry) {
+ if (dirEntry->name != QString(".") && dirEntry->name != QString("..")) {
+ filesToList.append(QFile::decodeName(dirEntry->name));
+ }
+
+ lastEntry = dirEntry;
+ }
+ } while (!listres.readdirres_u.reply.eof);
+
+ KIO::UDSEntry entry;
+ for (QStringList::const_iterator it = filesToList.constBegin(); it != filesToList.constEnd(); ++it) {
+ QString filePath = QFileInfo(QDir(path), (*it)).filePath();
+
+ int rpcStatus;
+ diropres dirres;
+ if (!lookupHandle(filePath, rpcStatus, dirres)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to lookup" << filePath << ", rpc:" << rpcStatus << ", nfs:" << dirres.status;
+ // Try the next file instead of failing
+ continue;
+ }
+
+ entry.clear();
+ entry.insert(KIO::UDSEntry::UDS_NAME, (*it));
+
+ //is it a symlink ?
+ if (dirres.diropres_u.diropres.attributes.type == NFLNK) {
+ int rpcStatus;
+ readlinkres readLinkRes;
+ char nameBuf[NFS_MAXPATHLEN];
+ if (readLink(filePath, rpcStatus, readLinkRes, nameBuf)) {
+ const QString linkDest = QString::fromLocal8Bit(readLinkRes.readlinkres_u.data);
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, linkDest);
+
+ bool badLink = true;
+ NFSFileHandle linkFH;
+ if (isValidLink(path, linkDest)) {
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(path, linkDest).absoluteFilePath();
+ }
+
+ int rpcStatus;
+ diropres lookupRes;
+ if (lookupHandle(linkPath, rpcStatus, lookupRes)) {
+ attrstat attrAndStat;
+ if (getAttr(linkPath, rpcStatus, attrAndStat)) {
+ badLink = false;
+
+ linkFH = lookupRes.diropres_u.diropres.file;
+ linkFH.setLinkSource(dirres.diropres_u.diropres.file);
+
+ completeUDSEntry(entry, attrAndStat.attrstat_u.attributes);
+ }
+ }
+
+ }
+
+ if (badLink) {
+ linkFH = dirres.diropres_u.diropres.file;
+ linkFH.setBadLink();
+
+ completeBadLinkUDSEntry(entry, dirres.diropres_u.diropres.attributes);
+ }
+
+ addFileHandle(filePath, linkFH);
+ } else {
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, i18n("Unknown target"));
+ completeBadLinkUDSEntry(entry, dirres.diropres_u.diropres.attributes);
+ }
+ } else {
+ addFileHandle(filePath, dirres.diropres_u.diropres.file);
+ completeUDSEntry(entry, dirres.diropres_u.diropres.attributes);
+ }
+
+ m_slave->listEntry(entry);
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::stat(const QUrl& url)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+ if (isExportedDir(path)) {
+ KIO::UDSEntry entry;
+
+ entry.insert(KIO::UDSEntry::UDS_NAME, path);
+ createVirtualDirEntry(entry);
+
+ m_slave->statEntry(entry);
+ m_slave->finished();
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid()) {
+ qCDebug(LOG_KIO_NFS) << "File handle is invalid";
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ int rpcStatus;
+ attrstat attrAndStat;
+ if (!getAttr(path, rpcStatus, attrAndStat)) {
+ checkForError(rpcStatus, attrAndStat.status, path);
+ return;
+ }
+
+ const QFileInfo fileInfo(path);
+
+ KIO::UDSEntry entry;
+ entry.insert(KIO::UDSEntry::UDS_NAME, fileInfo.fileName());
+
+ // Is it a symlink?
+ if (attrAndStat.attrstat_u.attributes.type == NFLNK) {
+ qCDebug(LOG_KIO_NFS) << "It's a symlink";
+
+ QString linkDest;
+
+ int rpcStatus;
+ readlinkres readLinkRes;
+ char nameBuf[NFS_MAXPATHLEN];
+ if (readLink(path, rpcStatus, readLinkRes, nameBuf)) {
+ linkDest = QString::fromLocal8Bit(readLinkRes.readlinkres_u.data);
+ } else {
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, i18n("Unknown target"));
+ completeBadLinkUDSEntry(entry, attrAndStat.attrstat_u.attributes);
+
+ m_slave->statEntry(entry);
+ m_slave->finished();
+ return;
+ }
+
+ qCDebug(LOG_KIO_NFS) << "link dest is" << linkDest;
+
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, linkDest);
+ if (!isValidLink(fileInfo.path(), linkDest)) {
+ completeBadLinkUDSEntry(entry, attrAndStat.attrstat_u.attributes);
+ } else {
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(fileInfo.path(), linkDest).absoluteFilePath();
+ }
+
+ int rpcStatus;
+ attrstat attrAndStat;
+ if (!getAttr(linkPath, rpcStatus, attrAndStat)) {
+ checkForError(rpcStatus, attrAndStat.status, linkPath);
+ return;
+ }
+
+ completeUDSEntry(entry, attrAndStat.attrstat_u.attributes);
+ }
+ } else {
+ completeUDSEntry(entry, attrAndStat.attrstat_u.attributes);
+ }
+
+ m_slave->statEntry(entry);
+ m_slave->finished();
+}
+
+void NFSProtocolV2::setHost(const QString& host)
+{
+ qCDebug(LOG_KIO_NFS) << host;
+ if (host.isEmpty()) {
+ m_slave->error(KIO::ERR_UNKNOWN_HOST, QString());
+ return;
+ }
+
+ if (host == m_currentHost) {
+ return;
+ }
+
+ // Set the new host and close the current connection
+ m_currentHost = host;
+ closeConnection();
+}
+
+void NFSProtocolV2::mkdir(const QUrl& url, int permissions)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+ const QFileInfo fileInfo(path);
+ if (isExportedDir(fileInfo.path())) {
+ m_slave->error(KIO::ERR_WRITE_ACCESS_DENIED, path);
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(fileInfo.path());
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ createargs createArgs;
+ fh.toFH(createArgs.where.dir);
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+ createArgs.where.name = tmpName.data();
+
+ if (permissions == -1) {
+ createArgs.attributes.mode = 0755;
+ } else {
+ createArgs.attributes.mode = permissions;
+ }
+
+ diropres dirres;
+ memset(&dirres, 0, sizeof(diropres));
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_MKDIR,
+ (xdrproc_t) xdr_createargs, reinterpret_cast<caddr_t>(&createArgs),
+ (xdrproc_t) xdr_diropres, reinterpret_cast<caddr_t>(&dirres),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, dirres.status, path)) {
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::del(const QUrl& url, bool)
+{
+ int rpcStatus;
+ nfsstat nfsStatus;
+ if (!remove(url.path(), rpcStatus, nfsStatus)) {
+ checkForError(rpcStatus, nfsStatus, url.path());
+
+ qCDebug(LOG_KIO_NFS) << "Could not delete" << url;
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::chmod(const QUrl& url, int permissions)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+ if (isExportedDir(path)) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, path);
+ return;
+ }
+
+ sattr attributes;
+ memset(&attributes, 0xFF, sizeof(attributes));
+ attributes.mode = permissions;
+
+ int rpcStatus;
+ nfsstat result;
+ if (!setAttr(path, attributes, rpcStatus, result)) {
+ checkForError(rpcStatus, result, path);
+ return;
+ }
+
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::get(const QUrl& url)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ readargs readArgs;
+ fh.toFH(readArgs.file);
+ readArgs.offset = 0;
+ readArgs.count = NFS_MAXDATA;
+ readArgs.totalcount = NFS_MAXDATA;
+
+ readres readRes;
+ memset(&readRes, 0, sizeof(readres));
+
+ char buf[NFS_MAXDATA];
+ readRes.readres_u.reply.data.data_val = buf;
+
+ bool validRead = false;
+ int offset = 0;
+ QByteArray readBuffer;
+ do {
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_READ,
+ (xdrproc_t) xdr_readargs, reinterpret_cast<caddr_t>(&readArgs),
+ (xdrproc_t) xdr_readres, reinterpret_cast<caddr_t>(&readRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, readRes.status, path)) {
+ return;
+ }
+
+ if (readArgs.offset == 0) {
+ m_slave->totalSize(readRes.readres_u.reply.attributes.size);
+
+ const QMimeDatabase db;
+ const QMimeType type = db.mimeTypeForFileNameAndData(url.fileName(), readBuffer);
+ m_slave->mimeType(type.name());
+ }
+
+ offset = readRes.readres_u.reply.data.data_len;
+ readArgs.offset += offset;
+ if (offset > 0) {
+ validRead = true;
+
+ readBuffer = QByteArray::fromRawData(readRes.readres_u.reply.data.data_val, offset);
+ m_slave->data(readBuffer);
+ readBuffer.clear();
+
+ m_slave->processedSize(readArgs.offset);
+ }
+
+ } while (offset > 0);
+
+ if (validRead) {
+ m_slave->data(QByteArray());
+ m_slave->processedSize(readArgs.offset);
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::put(const QUrl& url, int _mode, KIO::JobFlags flags)
+{
+ qCDebug(LOG_KIO_NFS) << url << _mode;
+
+ const QString destPath(url.path());
+
+ const QFileInfo fileInfo(destPath);
+ if (isExportedDir(fileInfo.path())) {
+ m_slave->error(KIO::ERR_WRITE_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ NFSFileHandle destFH = getFileHandle(destPath);
+ if (destFH.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, destPath);
+ return;
+ }
+
+ //the file exists and we don't want to overwrite
+ if (!destFH.isInvalid() && (!(flags & KIO::Overwrite))) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ int rpcStatus;
+ diropres dirOpRes;
+ if (!create(destPath, _mode, rpcStatus, dirOpRes)) {
+ checkForError(rpcStatus, dirOpRes.status, fileInfo.fileName());
+ return;
+ }
+
+ destFH = dirOpRes.diropres_u.diropres.file.data;
+
+ writeargs writeArgs;
+ memset(&writeArgs, 0, sizeof(writeargs));
+ destFH.toFH(writeArgs.file);
+ writeArgs.beginoffset = 0;
+ writeArgs.totalcount = 0;
+ writeArgs.offset = 0;
+
+ attrstat attrStat;
+
+ int result = 0, bytesWritten = 0;
+ do {
+ // Request new data
+ m_slave->dataReq();
+
+ QByteArray buffer;
+ result = m_slave->readData(buffer);
+
+ char* data = buffer.data();
+ int bytesToWrite = buffer.size(), writeNow = 0;
+ if (result > 0) {
+ do {
+ if (bytesToWrite > NFS_MAXDATA) {
+ writeNow = NFS_MAXDATA;
+ } else {
+ writeNow = bytesToWrite;
+ }
+
+ writeArgs.data.data_val = data;
+ writeArgs.data.data_len = writeNow;
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_WRITE,
+ (xdrproc_t) xdr_writeargs, reinterpret_cast<caddr_t>(&writeArgs),
+ (xdrproc_t) xdr_attrstat, reinterpret_cast<caddr_t>(&attrStat),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, attrStat.status, fileInfo.fileName())) {
+ return;
+ }
+
+ bytesWritten += writeNow;
+ writeArgs.offset = bytesWritten;
+
+ data = data + writeNow;
+ bytesToWrite -= writeNow;
+ } while (bytesToWrite > 0);
+ }
+ } while (result > 0);
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::rename(const QUrl& src, const QUrl& dest, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ const QString srcPath(src.path());
+ if (isExportedDir(srcPath)) {
+ m_slave->error(KIO::ERR_CANNOT_RENAME, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+ if (isExportedDir(destPath)) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ if (!getFileHandle(destPath).isInvalid() && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ int rpcStatus;
+ nfsstat nfsStatus;
+ if (!rename(src.path(), destPath, rpcStatus, nfsStatus)) {
+ if (!checkForError(rpcStatus, nfsStatus, destPath)) {
+ return;
+ }
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV2::copySame(const QUrl& src, const QUrl& dest, int _mode, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ const QString srcPath(src.path());
+
+ const NFSFileHandle srcFH = getFileHandle(srcPath);
+ if (srcFH.isInvalid()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString destPath = dest.path();
+ if (isExportedDir(QFileInfo(destPath).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ // The file exists and we don't want to overwrite
+ if (!getFileHandle(destPath).isInvalid() && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Is it a link? No need to copy the data then, just copy the link destination.
+ if (srcFH.isLink()) {
+ //get the link dest
+ int rpcStatus;
+ readlinkres readLinkRes;
+ char nameBuf[NFS_MAXPATHLEN];
+ if (!readLink(srcPath, rpcStatus, readLinkRes, nameBuf)) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString linkPath = QString::fromLocal8Bit(readLinkRes.readlinkres_u.data);
+
+ nfsstat linkRes;
+ if (!symLink(linkPath, destPath, rpcStatus, linkRes)) {
+ checkForError(rpcStatus, linkRes, linkPath);
+ return;
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ unsigned long resumeOffset = 0;
+ bool bResume = false;
+ const QString partFilePath = destPath + QLatin1String(".part");
+ const NFSFileHandle partFH = getFileHandle(partFilePath);
+ const bool bPartExists = !partFH.isInvalid();
+ const bool bMarkPartial = m_slave->config()->readEntry("MarkPartial", true);
+
+ if (bPartExists) {
+ int rpcStatus;
+ diropres partRes;
+ if (lookupHandle(partFilePath, rpcStatus, partRes)) {
+ if (bMarkPartial && partRes.diropres_u.diropres.attributes.size > 0) {
+ if (partRes.diropres_u.diropres.attributes.type == NFDIR) {
+ m_slave->error(KIO::ERR_IS_DIRECTORY, partFilePath);
+ return;
+ }
+
+ bResume = m_slave->canResume(partRes.diropres_u.diropres.attributes.size);
+ if (bResume) {
+ resumeOffset = partRes.diropres_u.diropres.attributes.size;
+ }
+ }
+ }
+
+ // Remove the part file if we are not resuming
+ if (!bResume) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+
+ // Create the file if we are not resuming a parted transfer,
+ // or if we are not using part files(bResume is false in that case)
+ NFSFileHandle destFH;
+ if (!bResume) {
+ QString createPath;
+ if (bMarkPartial) {
+ createPath = partFilePath;
+ } else {
+ createPath = destPath;
+ }
+
+ int rpcStatus;
+ diropres dirOpRes;
+ if (!create(createPath, _mode, rpcStatus, dirOpRes)) {
+ checkForError(rpcStatus, dirOpRes.status, createPath);
+ return;
+ }
+
+ destFH = dirOpRes.diropres_u.diropres.file.data;
+ } else {
+ // Since we are resuming it's implied that we are using a part file,
+ // which should exist at this point.
+ destFH = getFileHandle(partFilePath);
+
+ qCDebug(LOG_KIO_NFS) << "Resuming old transfer";
+ }
+
+ char buf[NFS_MAXDATA];
+
+ writeargs writeArgs;
+ destFH.toFH(writeArgs.file);
+ writeArgs.beginoffset = 0;
+ writeArgs.totalcount = 0;
+ writeArgs.offset = 0;
+ writeArgs.data.data_val = buf;
+
+ readargs readArgs;
+ srcFH.toFH(readArgs.file);
+ readArgs.offset = 0;
+ readArgs.count = NFS_MAXDATA;
+ readArgs.totalcount = NFS_MAXDATA;
+
+ if (bResume) {
+ writeArgs.offset = resumeOffset;
+ readArgs.offset = resumeOffset;
+ }
+
+ readres readRes;
+ memset(&readRes, 0, sizeof(readres));
+ readRes.readres_u.reply.data.data_val = buf;
+
+ attrstat attrStat;
+ memset(&attrStat, 0, sizeof(attrstat));
+
+ bool error = false;
+ int bytesRead = 0;
+ do {
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_READ,
+ (xdrproc_t) xdr_readargs, reinterpret_cast<caddr_t>(&readArgs),
+ (xdrproc_t) xdr_readres, reinterpret_cast<caddr_t>(&readRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, readRes.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ bytesRead = readRes.readres_u.reply.data.data_len;
+
+ // We should only send out the total size and mimetype at the start of the transfer
+ if (readArgs.offset == 0 || (bResume && writeArgs.offset == resumeOffset)) {
+ m_slave->totalSize(readRes.readres_u.reply.attributes.size);
+
+ QMimeDatabase db;
+ QMimeType type = db.mimeTypeForFileNameAndData(src.fileName(), QByteArray::fromRawData(writeArgs.data.data_val, bytesRead));
+ m_slave->mimeType(type.name());
+ }
+
+
+ if (bytesRead > 0) {
+ readArgs.offset += bytesRead;
+
+ writeArgs.data.data_len = bytesRead;
+
+ clnt_stat = clnt_call(m_nfsClient, NFSPROC_WRITE,
+ (xdrproc_t) xdr_writeargs, reinterpret_cast<caddr_t>(&writeArgs),
+ (xdrproc_t) xdr_attrstat, reinterpret_cast<caddr_t>(&attrStat),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, attrStat.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ writeArgs.offset += bytesRead;
+
+ m_slave->processedSize(readArgs.offset);
+ }
+ } while (bytesRead > 0);
+
+ if (error) {
+ if (bMarkPartial) {
+ // Remove the part file if it's smaller than the minimum keep size.
+ const unsigned int size = m_slave->config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
+ if (writeArgs.offset < size) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+ } else {
+ // Rename partial file to its original name.
+ if (bMarkPartial) {
+ // Remove the destination file(if it exists)
+ if (!getFileHandle(destPath).isInvalid() && !remove(destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove destination file" << destPath << ", ignoring...";
+ }
+
+ if (!rename(partFilePath, destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to rename" << partFilePath << "to" << destPath;
+ m_slave->error(KIO::ERR_CANNOT_RENAME_PARTIAL, partFilePath);
+ return;
+ }
+ }
+
+ // Restore modification time
+ int rpcStatus;
+ attrstat attrRes;
+ if (getAttr(srcPath, rpcStatus, attrRes)) {
+ sattr attributes;
+ memset(&attributes, 0xFF, sizeof(attributes));
+ attributes.mtime.seconds = attrRes.attrstat_u.attributes.mtime.seconds;
+ attributes.mtime.useconds = attrRes.attrstat_u.attributes.mtime.useconds;
+
+ nfsstat attrSetRes;
+ if (!setAttr(destPath, attributes, rpcStatus, attrSetRes)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to restore mtime, ignoring..." << rpcStatus << attrSetRes;
+ }
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Copied" << writeArgs.offset << "bytes of data";
+
+ m_slave->processedSize(readArgs.offset);
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV2::copyFrom(const QUrl& src, const QUrl& dest, int _mode, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ const QString srcPath(src.path());
+
+ const NFSFileHandle srcFH = getFileHandle(srcPath);
+ if (srcFH.isInvalid()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+
+ // The file exists and we don't want to overwrite
+ if (QFile::exists(destPath) && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Is it a link? No need to copy the data then, just copy the link destination.
+ if (srcFH.isLink()) {
+ qCDebug(LOG_KIO_NFS) << "Is a link";
+
+ int rpcStatus;
+ readlinkres readLinkRes;
+ char nameBuf[NFS_MAXPATHLEN];
+ if (!readLink(srcPath, rpcStatus, readLinkRes, nameBuf)) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ QFile::link(QString::fromLocal8Bit(readLinkRes.readlinkres_u.data), destPath);
+
+ m_slave->finished();
+ return;
+ }
+
+ bool bResume = false;
+ const QFileInfo partInfo(destPath + QLatin1String(".part"));
+ const bool bPartExists = partInfo.exists();
+ const bool bMarkPartial = m_slave->config()->readEntry("MarkPartial", true);
+
+ if (bMarkPartial && bPartExists && partInfo.size() > 0) {
+ if (partInfo.isDir()) {
+ m_slave->error(KIO::ERR_IS_DIRECTORY, partInfo.absoluteFilePath());
+ return;
+ }
+
+ bResume = m_slave->canResume(partInfo.size());
+ }
+
+ if (bPartExists && !bResume) {
+ QFile::remove(partInfo.absoluteFilePath());
+ }
+
+ QFile::OpenMode openMode;
+ QString outFileName;
+ if (bResume) {
+ outFileName = partInfo.absoluteFilePath();
+ openMode = QFile::WriteOnly | QFile::Append;
+ } else {
+ outFileName = (bMarkPartial ? partInfo.absoluteFilePath() : destPath);
+ openMode = QFile::WriteOnly | QFile::Truncate;
+ }
+
+ QFile destFile(outFileName);
+ if (!bResume) {
+ QFile::Permissions perms;
+ if (_mode == -1) {
+ perms = QFile::ReadOwner | QFile::WriteOwner;
+ } else {
+ perms = KIO::convertPermissions(_mode | QFile::WriteOwner);
+ }
+ destFile.setPermissions(perms);
+ }
+
+ if (!destFile.open(openMode)) {
+ switch (destFile.error()) {
+ case QFile::OpenError:
+ if (bResume) {
+ m_slave->error(KIO::ERR_CANNOT_RESUME, destPath);
+ } else {
+ m_slave->error(KIO::ERR_CANNOT_OPEN_FOR_WRITING, destPath);
+ }
+ break;
+ case QFile::PermissionsError:
+ m_slave->error(KIO::ERR_WRITE_ACCESS_DENIED, destPath);
+ break;
+ default:
+ m_slave->error(KIO::ERR_CANNOT_OPEN_FOR_WRITING, destPath);
+ break;
+ }
+ return;
+ }
+
+ char buf[NFS_MAXDATA];
+
+ readargs readArgs;
+ srcFH.toFH(readArgs.file);
+ if (bResume) {
+ readArgs.offset = partInfo.size();
+ } else {
+ readArgs.offset = 0;
+ }
+ readArgs.count = NFS_MAXDATA;
+ readArgs.totalcount = NFS_MAXDATA;
+
+ readres readRes;
+ memset(&readRes, 0, sizeof(readres));
+ readRes.readres_u.reply.data.data_val = buf;
+
+ attrstat attrStat;
+ memset(&attrStat, 0, sizeof(attrstat));
+
+ bool error = false;
+ int bytesRead = 0;
+ do {
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_READ,
+ (xdrproc_t) xdr_readargs, reinterpret_cast<caddr_t>(&readArgs),
+ (xdrproc_t) xdr_readres, reinterpret_cast<caddr_t>(&readRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, readRes.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ bytesRead = readRes.readres_u.reply.data.data_len;
+
+ if (readArgs.offset == 0) {
+ m_slave->totalSize(readRes.readres_u.reply.attributes.size);
+
+ QMimeDatabase db;
+ QMimeType type = db.mimeTypeForFileNameAndData(src.fileName(), QByteArray::fromRawData(readRes.readres_u.reply.data.data_val, bytesRead));
+ m_slave->mimeType(type.name());
+ }
+
+
+ if (bytesRead > 0) {
+ readArgs.offset += bytesRead;
+
+ if (destFile.write(readRes.readres_u.reply.data.data_val, bytesRead) != bytesRead) {
+ m_slave->error(KIO::ERR_COULD_NOT_WRITE, destPath);
+
+ error = true;
+ break;
+ }
+
+ m_slave->processedSize(readArgs.offset);
+ }
+ } while (bytesRead > 0);
+
+ // Close the file so we can modify the modification time later.
+ destFile.close();
+
+ if (error) {
+ if (bMarkPartial) {
+ // Remove the part file if it's smaller than the minimum keep
+ const int size = m_slave->config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
+ if (partInfo.size() < size) {
+ QFile::remove(partInfo.absoluteFilePath());
+ }
+ }
+ } else {
+ // Rename partial file to its original name.
+ if (bMarkPartial) {
+ const QString sPart = partInfo.absoluteFilePath();
+ if (QFile::exists(destPath)) {
+ QFile::remove(destPath);
+ }
+ if (!QFile::rename(sPart, destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to rename" << sPart << "to" << destPath;
+ m_slave->error(KIO::ERR_CANNOT_RENAME_PARTIAL, sPart);
+ return;
+ }
+ }
+
+ // Restore the mtime on the file.
+ const QString mtimeStr = m_slave->metaData("modified");
+ if (!mtimeStr.isEmpty()) {
+ QDateTime dt = QDateTime::fromString(mtimeStr, Qt::ISODate);
+ if (dt.isValid()) {
+ qCDebug(LOG_KIO_NFS) << "Setting modification time to" << dt.toTime_t();
+
+ struct utimbuf utbuf;
+ utbuf.actime = QFileInfo(destPath).lastRead().toTime_t(); // access time, unchanged
+ utbuf.modtime = dt.toTime_t(); // modification time
+ utime(QFile::encodeName(destPath).constData(), &utbuf);
+ }
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Copied" << readArgs.offset << "bytes of data";
+
+ m_slave->processedSize(readArgs.offset);
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV2::copyTo(const QUrl& src, const QUrl& dest, int _mode, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ // The source does not exist, how strange.
+ const QString srcPath(src.path());
+ if (!QFile::exists(srcPath)) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+ if (isExportedDir(destPath)) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ // The file exists and we don't want to overwrite.
+ if (!getFileHandle(destPath).isInvalid() && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Is it a link? No need to copy the data then, just copy the link destination.
+ const QString symlinkTarget = QFile::symLinkTarget(srcPath);
+ if (!symlinkTarget.isEmpty()) {
+ int rpcStatus;
+ nfsstat linkRes;
+ if (!symLink(symlinkTarget, destPath, rpcStatus, linkRes)) {
+ checkForError(rpcStatus, linkRes, symlinkTarget);
+ return;
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ unsigned long resumeOffset = 0;
+ bool bResume = false;
+ const QString partFilePath = destPath + QLatin1String(".part");
+ const NFSFileHandle partFH = getFileHandle(partFilePath);
+ const bool bPartExists = !partFH.isInvalid();
+ const bool bMarkPartial = m_slave->config()->readEntry("MarkPartial", true);
+
+ if (bPartExists) {
+ int rpcStatus;
+ diropres partRes;
+ if (lookupHandle(partFilePath, rpcStatus, partRes)) {
+ if (bMarkPartial && partRes.diropres_u.diropres.attributes.size > 0) {
+ if (partRes.diropres_u.diropres.attributes.type == NFDIR) {
+ m_slave->error(KIO::ERR_IS_DIRECTORY, partFilePath);
+ return;
+ }
+
+ bResume = m_slave->canResume(partRes.diropres_u.diropres.attributes.size);
+ if (bResume) {
+ resumeOffset = partRes.diropres_u.diropres.attributes.size;
+ }
+ }
+ }
+
+ // Remove the part file if we are not resuming
+ if (!bResume) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+
+ // Open the source file
+ QFile srcFile(srcPath);
+ if (!srcFile.open(QIODevice::ReadOnly)) {
+ m_slave->error(KIO::ERR_CANNOT_OPEN_FOR_READING, srcPath);
+ return;
+ }
+
+ // Create the file if we are not resuming a parted transfer,
+ // or if we are not using part files(bResume is false in that case)
+ NFSFileHandle destFH;
+ if (!bResume) {
+ QString createPath;
+ if (bMarkPartial) {
+ createPath = partFilePath;
+ } else {
+ createPath = destPath;
+ }
+
+ int rpcStatus;
+ diropres dirOpRes;
+ if (!create(createPath, _mode, rpcStatus, dirOpRes)) {
+ checkForError(rpcStatus, dirOpRes.status, createPath);
+ return;
+ }
+
+ destFH = dirOpRes.diropres_u.diropres.file.data;
+ } else {
+ // Since we are resuming it's implied that we are using a part file,
+ // which should exist at this point.
+ destFH = getFileHandle(partFilePath);
+
+ qCDebug(LOG_KIO_NFS) << "Resuming old transfer";
+ }
+
+ // Send the total size to the slave.
+ m_slave->totalSize(srcFile.size());
+
+ // Set up write arguments.
+ char buf[NFS_MAXDATA];
+
+ writeargs writeArgs;
+ memset(&writeArgs, 0, sizeof(writeargs));
+ destFH.toFH(writeArgs.file);
+ writeArgs.data.data_val = buf;
+ writeArgs.beginoffset = 0;
+ writeArgs.totalcount = 0;
+ if (bResume) {
+ writeArgs.offset = resumeOffset;
+ } else {
+ writeArgs.offset = 0;
+ }
+
+ attrstat attrStat;
+ memset(&attrStat, 0, sizeof(attrstat));
+
+ bool error = false;
+ int bytesRead = 0;
+ do {
+ bytesRead = srcFile.read(writeArgs.data.data_val, NFS_MAXDATA);
+ if (bytesRead < 0) {
+ m_slave->error(KIO::ERR_COULD_NOT_READ, srcPath);
+
+ error = true;
+ break;
+ }
+
+ if (bytesRead > 0) {
+ writeArgs.data.data_len = bytesRead;
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC_WRITE,
+ (xdrproc_t) xdr_writeargs, reinterpret_cast<caddr_t>(&writeArgs),
+ (xdrproc_t) xdr_attrstat, reinterpret_cast<caddr_t>(&attrStat),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, attrStat.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ writeArgs.offset += bytesRead;
+
+ m_slave->processedSize(writeArgs.offset);
+ }
+ } while (bytesRead > 0);
+
+ if (error) {
+ if (bMarkPartial) {
+ // Remove the part file if it's smaller than the minimum keep size.
+ const unsigned int size = m_slave->config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
+ if (writeArgs.offset < size) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+ } else {
+ // Rename partial file to its original name.
+ if (bMarkPartial) {
+ // Remove the destination file(if it exists)
+ if (!getFileHandle(destPath).isInvalid() && !remove(destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove destination file" << destPath << ", ignoring...";
+ }
+
+ if (!rename(partFilePath, destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to rename" << partFilePath << "to" << destPath;
+ m_slave->error(KIO::ERR_CANNOT_RENAME_PARTIAL, partFilePath);
+ return;
+ }
+ }
+
+ // Restore the mtime on the file.
+ const QString mtimeStr = m_slave->metaData("modified");
+ if (!mtimeStr.isEmpty()) {
+ QDateTime dt = QDateTime::fromString(mtimeStr, Qt::ISODate);
+ if (dt.isValid()) {
+ sattr attributes;
+ memset(&attributes, 0xFF, sizeof(attributes));
+ attributes.mtime.seconds = dt.toTime_t();
+ attributes.mtime.useconds = attributes.mtime.seconds * 1000000ULL;
+
+ int rpcStatus;
+ nfsstat attrSetRes;
+ if (!setAttr(destPath, attributes, rpcStatus, attrSetRes)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to restore mtime, ignoring..." << rpcStatus << attrSetRes;
+ }
+ }
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Copied" << writeArgs.offset << "bytes of data";
+
+ m_slave->processedSize(writeArgs.offset);
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV2::symlink(const QString& target, const QUrl& dest, KIO::JobFlags flags)
+{
+ const QString destPath(dest.path());
+ if (isExportedDir(QFileInfo(destPath).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ if (!getFileHandle(destPath).isInvalid() && (flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ int rpcStatus;
+ nfsstat res;
+ if (!symLink(target, destPath, rpcStatus, res)) {
+ checkForError(rpcStatus, res, destPath);
+ return;
+ }
+
+ m_slave->finished();
+
+}
+
+
+bool NFSProtocolV2::create(const QString& path, int mode, int& rpcStatus, diropres& result)
+{
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFSERR_ACCES;
+ return false;
+ }
+
+ const QFileInfo fileInfo(path);
+ if (isExportedDir(fileInfo.path())) {
+ result.status = NFSERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle directoryFH = getFileHandle(fileInfo.path());
+ if (directoryFH.isInvalid()) {
+ result.status = NFSERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+
+ createargs args;
+ directoryFH.toFH(args.where.dir);
+ args.where.name = tmpName.data();
+
+ memset(&args.attributes, 0xFF, sizeof(sattr));
+ if (mode == -1) {
+ args.attributes.mode = 0644;
+ } else {
+ args.attributes.mode = mode;
+ }
+ args.attributes.uid = geteuid();
+ args.attributes.gid = getegid();
+ args.attributes.size = 0;
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_CREATE,
+ (xdrproc_t) xdr_createargs, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_diropres, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS_OK);
+}
+
+bool NFSProtocolV2::getAttr(const QString& path, int& rpcStatus, attrstat& result)
+{
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFSERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle fileFH = getFileHandle(path);
+ if (fileFH.isInvalid()) {
+ result.status = NFSERR_NOENT;
+ return false;
+ }
+
+ nfs_fh fh;
+ fileFH.toFH(fh);
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_GETATTR,
+ (xdrproc_t) xdr_nfs_fh, reinterpret_cast<caddr_t>(&fh),
+ (xdrproc_t) xdr_attrstat, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS_OK);
+}
+
+bool NFSProtocolV2::lookupHandle(const QString& path, int& rpcStatus, diropres& result)
+{
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFSERR_ACCES;
+ return false;
+ }
+
+ const QFileInfo fileInfo(path);
+
+ const NFSFileHandle parentFH = getFileHandle(fileInfo.path());
+ if (parentFH.isInvalid()) {
+ result.status = NFSERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+
+ diropargs dirargs;
+ memset(&dirargs, 0, sizeof(diropargs));
+ parentFH.toFH(dirargs.dir);
+ dirargs.name = tmpName.data();
+
+ memset(&result, 0, sizeof(diropres));
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_LOOKUP,
+ (xdrproc_t) xdr_diropargs, reinterpret_cast<caddr_t>(&dirargs),
+ (xdrproc_t) xdr_diropres, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS_OK);
+}
+
+bool NFSProtocolV2::readLink(const QString& path, int& rpcStatus, readlinkres& result, char* dataBuffer)
+{
+ const NFSFileHandle fh = getFileHandle(path);
+
+ nfs_fh nfsFH;
+ if (fh.isLink() && !fh.isBadLink()) {
+ fh.toFHLink(nfsFH);
+ } else {
+ fh.toFH(nfsFH);
+ }
+
+ result.readlinkres_u.data = dataBuffer;
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_READLINK,
+ (xdrproc_t) xdr_nfs_fh, reinterpret_cast<caddr_t>(&nfsFH),
+ (xdrproc_t) xdr_readlinkres, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS_OK);
+}
+
+bool NFSProtocolV2::remove(const QString& path)
+{
+ int rpcStatus;
+ nfsstat nfsStatus;
+
+ return remove(path, rpcStatus, nfsStatus);
+}
+
+bool NFSProtocolV2::remove(const QString& path, int& rpcStatus, nfsstat& result)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result = NFSERR_PERM;
+ return false;
+ }
+
+ const QFileInfo fileInfo(path);
+ if (isExportedDir(fileInfo.path())) {
+ result = NFSERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle directoryFH = getFileHandle(fileInfo.path());
+ if (directoryFH.isInvalid()) {
+ result = NFSERR_NOENT;
+ return false;
+ }
+
+ int rpcLookupStatus;
+ diropres lookupRes;
+ if (!lookupHandle(path, rpcLookupStatus, lookupRes)) {
+ result = NFSERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+
+ diropargs dirargs;
+ memset(&dirargs, 0, sizeof(diropargs));
+ directoryFH.toFH(dirargs.dir);
+ dirargs.name = tmpName.data();
+
+ if (lookupRes.diropres_u.diropres.attributes.type != NFDIR) {
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_REMOVE,
+ (xdrproc_t) xdr_diropargs, reinterpret_cast<caddr_t>(&dirargs),
+ (xdrproc_t) xdr_nfsstat, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+ } else {
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_RMDIR,
+ (xdrproc_t) xdr_diropargs, reinterpret_cast<caddr_t>(&dirargs),
+ (xdrproc_t) xdr_nfsstat, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+ }
+
+ bool ret = (rpcStatus == RPC_SUCCESS && result == NFS_OK);
+ if (ret) {
+ removeFileHandle(path);
+ }
+
+ return ret;
+}
+
+bool NFSProtocolV2::rename(const QString& src, const QString& dest)
+{
+ int rpcStatus;
+ nfsstat result;
+
+ return rename(src, dest, rpcStatus, result);
+}
+
+bool NFSProtocolV2::rename(const QString& src, const QString& dest, int& rpcStatus, nfsstat& result)
+{
+ qCDebug(LOG_KIO_NFS) << src << dest;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ const QFileInfo srcFileInfo(src);
+ if (isExportedDir(srcFileInfo.path())) {
+ result = NFSERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle srcDirectoryFH = getFileHandle(srcFileInfo.path());
+ if (srcDirectoryFH.isInvalid()) {
+ result = NFSERR_NOENT;
+ return false;
+ }
+
+ const QFileInfo destFileInfo(dest);
+ if (isExportedDir(destFileInfo.path())) {
+ result = NFSERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle destDirectoryFH = getFileHandle(destFileInfo.path());
+ if (destDirectoryFH.isInvalid()) {
+ result = NFSERR_NOENT;
+ return false;
+ }
+
+ renameargs renameArgs;
+ memset(&renameArgs, 0, sizeof(renameargs));
+
+ QByteArray srcByteName = QFile::encodeName(srcFileInfo.fileName());
+ srcDirectoryFH.toFH(renameArgs.from.dir);
+ renameArgs.from.name = srcByteName.data();
+
+ QByteArray destByteName = QFile::encodeName(destFileInfo.fileName());
+ destDirectoryFH.toFH(renameArgs.to.dir);
+ renameArgs.to.name = destByteName.data();
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_RENAME,
+ (xdrproc_t) xdr_renameargs, reinterpret_cast<caddr_t>(&renameArgs),
+ (xdrproc_t) xdr_nfsstat, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ bool ret = (rpcStatus == RPC_SUCCESS && result == NFS_OK);
+ if (ret) {
+ // Can we actually find the new handle?
+ int lookupStatus;
+ diropres lookupRes;
+ if (lookupHandle(dest, lookupStatus, lookupRes)) {
+ // Remove the old file, and add the new one
+ removeFileHandle(src);
+ addFileHandle(dest, lookupRes.diropres_u.diropres.file);
+ }
+ }
+
+ return ret;
+}
+
+bool NFSProtocolV2::setAttr(const QString& path, const sattr& attributes, int& rpcStatus, nfsstat& result)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid()) {
+ result = NFSERR_NOENT;
+ return false;
+ }
+
+ sattrargs sAttrArgs;
+ fh.toFH(sAttrArgs.file);
+ memcpy(&sAttrArgs.attributes, &attributes, sizeof(attributes));
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_SETATTR,
+ (xdrproc_t) xdr_sattrargs, reinterpret_cast<caddr_t>(&sAttrArgs),
+ (xdrproc_t) xdr_nfsstat, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result == NFS_OK);
+}
+
+bool NFSProtocolV2::symLink(const QString& target, const QString& dest, int& rpcStatus, nfsstat& result)
+{
+ qCDebug(LOG_KIO_NFS) << target << dest;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ // Remove dest first, we don't really care about the return value at this point,
+ // the symlink call will fail if dest was not removed correctly.
+ remove(dest);
+
+
+ const QFileInfo fileInfo(dest);
+ if (isExportedDir(fileInfo.path())) {
+ result = NFSERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle fh = getFileHandle(fileInfo.path());
+ if (fh.isInvalid()) {
+ result = NFSERR_NOENT;
+ return false;
+ }
+
+ QByteArray fromBytes = QFile::encodeName(fileInfo.fileName());
+ QByteArray toBytes = QFile::encodeName(target);
+
+ symlinkargs symLinkArgs;
+ memset(&symLinkArgs, 0, sizeof(symLinkArgs));
+
+ fh.toFH(symLinkArgs.from.dir);
+ symLinkArgs.from.name = fromBytes.data();
+ symLinkArgs.to = toBytes.data();
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC_SYMLINK,
+ (xdrproc_t) xdr_symlinkargs, reinterpret_cast<caddr_t>(&symLinkArgs),
+ (xdrproc_t) xdr_nfsstat, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ // Add the new handle to the cache
+ NFSFileHandle destFH = getFileHandle(dest);
+ if (!destFH.isInvalid()) {
+ addFileHandle(dest, destFH);
+ }
+
+ return (rpcStatus == RPC_SUCCESS && result == NFS_OK);
+}
+
+
+void NFSProtocolV2::completeUDSEntry(KIO::UDSEntry& entry, const fattr& attributes)
+{
+ entry.insert(KIO::UDSEntry::UDS_SIZE, attributes.size);
+ entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, attributes.mtime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS_TIME, attributes.atime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, attributes.ctime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, (attributes.mode & 07777));
+ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, attributes.mode & S_IFMT); // extract file type
+
+ QString str;
+
+ const uid_t uid = attributes.uid;
+ if (!m_usercache.contains(uid)) {
+ struct passwd* user = getpwuid(uid);
+ if (user) {
+ m_usercache.insert(uid, QString::fromLatin1(user->pw_name));
+ str = user->pw_name;
+ } else {
+ str = QString::number(uid);
+ }
+ } else {
+ str = m_usercache.value(uid);
+ }
+
+ entry.insert(KIO::UDSEntry::UDS_USER, str);
+
+ const gid_t gid = attributes.gid;
+ if (!m_groupcache.contains(gid)) {
+ struct group* grp = getgrgid(gid);
+ if (grp) {
+ m_groupcache.insert(gid, QString::fromLatin1(grp->gr_name));
+ str = grp->gr_name;
+ } else {
+ str = QString::number(gid);
+ }
+ } else {
+ str = m_groupcache.value(gid);
+ }
+
+ entry.insert(KIO::UDSEntry::UDS_GROUP, str);
+}
+
+void NFSProtocolV2::completeBadLinkUDSEntry(KIO::UDSEntry& entry, const fattr& attributes)
+{
+ entry.insert(KIO::UDSEntry::UDS_SIZE, 0LL);
+ entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, attributes.mtime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS_TIME, attributes.atime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, attributes.ctime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFMT - 1);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IRWXO);
+ entry.insert(KIO::UDSEntry::UDS_USER, attributes.uid);
+ entry.insert(KIO::UDSEntry::UDS_GROUP, attributes.gid);
+}
diff --git a/nfs/nfsv2.h b/nfs/nfsv2.h
new file mode 100644
index 0000000000000000000000000000000000000000..d82c1adf4425a3d003e3b8e063a56f03d84fd6cb
--- /dev/null
+++ b/nfs/nfsv2.h
@@ -0,0 +1,103 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org>,
+ 2014 Mathias Tillman <master.homer@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KIO_NFSV2_H
+#define KIO_NFSV2_H
+
+#include "kio_nfs.h"
+
+#define PORTMAP //this seems to be required to compile on Solaris
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+class NFSProtocolV2 : public NFSProtocol
+{
+public:
+ NFSProtocolV2(NFSSlave* slave);
+ ~NFSProtocolV2();
+
+ bool isCompatible(bool& connectionError) Q_DECL_OVERRIDE;
+ bool isConnected() const Q_DECL_OVERRIDE;
+
+ void openConnection() Q_DECL_OVERRIDE;
+ void closeConnection() Q_DECL_OVERRIDE;
+
+ void setHost(const QString& host) Q_DECL_OVERRIDE;
+
+ void put(const QUrl& url, int _mode, KIO::JobFlags _flags) Q_DECL_OVERRIDE;
+ void get(const QUrl& url) Q_DECL_OVERRIDE;
+ void listDir(const QUrl& url) Q_DECL_OVERRIDE;
+ void symlink(const QString& target, const QUrl& dest, KIO::JobFlags) Q_DECL_OVERRIDE;
+ void stat(const QUrl& url) Q_DECL_OVERRIDE;
+ void mkdir(const QUrl& url, int permissions) Q_DECL_OVERRIDE;
+ void del(const QUrl& url, bool isfile) Q_DECL_OVERRIDE;
+ void chmod(const QUrl& url, int permissions) Q_DECL_OVERRIDE;
+ void rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+
+protected:
+ void copySame(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+ void copyFrom(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+ void copyTo(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+
+ NFSFileHandle lookupFileHandle(const QString& path) Q_DECL_OVERRIDE;
+
+private:
+ bool create(const QString& path, int mode, int& rpcStatus, diropres& result);
+
+ bool getAttr(const QString& path, int& rpcStatus, attrstat& result);
+
+ bool lookupHandle(const QString& path, int& rpcStatus, diropres& result);
+
+ bool readLink(const QString& path, int& rpcStatus, readlinkres& result, char* dataBuffer);
+
+ // Calls @remove, but with dummy rpcStatus and result arguments
+ bool remove(const QString& path);
+ bool remove(const QString& path, int& rpcStatus, nfsstat& result);
+
+ // Calls @rename, but with dummy rpcStatus and result arguments
+ bool rename(const QString& src, const QString& dest);
+ bool rename(const QString& src, const QString& dest, int& rpcStatus, nfsstat& result);
+
+ bool setAttr(const QString& path, const sattr& attributes, int& rpcStatus, nfsstat& result);
+
+ bool symLink(const QString& target, const QString& dest, int& rpcStatus, nfsstat& result);
+
+ // UDS helper functions
+ void completeUDSEntry(KIO::UDSEntry& entry, const fattr& attributes);
+ void completeBadLinkUDSEntry(KIO::UDSEntry& entry, const fattr& attributes);
+
+ NFSSlave* m_slave;
+
+ QString m_currentHost;
+
+ CLIENT* m_mountClient;
+ int m_mountSock;
+ CLIENT* m_nfsClient;
+ int m_nfsSock;
+
+ timeval clnt_timeout;
+
+ QHash<long, QString> m_usercache;
+ QHash<long, QString> m_groupcache;
+};
+
+#endif
diff --git a/nfs/nfsv3.cpp b/nfs/nfsv3.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..368a61febc778688507ffb3954caaf69fc18d371
--- /dev/null
+++ b/nfs/nfsv3.cpp
@@ -0,0 +1,2195 @@
+/* This file is part of the KDE project
+
+ Copyright(C) 2000 Alexander Neundorf <neundorf@kde.org>,
+ 2014 Mathias Tillman <master.homer@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <config-runtime.h>
+
+#include <arpa/inet.h>
+
+// This is needed on Solaris so that rpc.h defines clnttcp_create etc.
+#ifndef PORTMAP
+#define PORTMAP
+#endif
+#include <rpc/rpc.h> // for rpc calls
+
+#include <errno.h>
+#include <grp.h>
+#include <memory.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+
+#include <QFile>
+#include <QDir>
+#include <QDebug>
+#include <QLoggingCategory>
+#include <QMimeType>
+#include <QMimeDatabase>
+
+#include <KLocalizedString>
+#include <kio/global.h>
+#include <kio/ioslave_defaults.h>
+
+#include "nfsv3.h"
+
+// This ioslave is for NFS version 3.
+#define NFSPROG 100003UL
+#define NFSVERS 3UL
+
+#define NFS3_MAXDATA 32768
+#define NFS3_MAXPATHLEN PATH_MAX
+
+NFSProtocolV3::NFSProtocolV3(NFSSlave* slave)
+ : NFSProtocol(slave),
+ m_slave(slave),
+ m_mountClient(0),
+ m_mountSock(-1),
+ m_nfsClient(0),
+ m_nfsSock(-1),
+ m_readBufferSize(0),
+ m_writeBufferSize(0),
+ m_readDirSize(0)
+{
+ qCDebug(LOG_KIO_NFS) << "NFS3::NFS3";
+
+ clnt_timeout.tv_sec = 20;
+ clnt_timeout.tv_usec = 0;
+}
+
+NFSProtocolV3::~NFSProtocolV3()
+{
+ closeConnection();
+}
+
+bool NFSProtocolV3::isCompatible(bool& connectionError)
+{
+ qCDebug(LOG_KIO_NFS);
+
+ int ret = -1;
+
+ CLIENT* client = NULL;
+ int sock = 0;
+ if (NFSProtocol::openConnection(m_currentHost, NFSPROG, NFSVERS, client, sock) == 0) {
+ timeval check_timeout;
+ check_timeout.tv_sec = 20;
+ check_timeout.tv_usec = 0;
+
+ // Check if the NFS version is compatible
+ ret = clnt_call(client, NFSPROC3_NULL,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_void, NULL,
+ check_timeout);
+
+ connectionError = false;
+ } else {
+ qCDebug(LOG_KIO_NFS) << "openConnection failed";
+ connectionError = true;
+ }
+
+ if (sock != -1) {
+ ::close(sock);
+ }
+
+ if (client != NULL) {
+ CLNT_DESTROY(client);
+ }
+
+ qCDebug(LOG_KIO_NFS) << ret;
+
+ return (ret == RPC_SUCCESS);
+}
+
+bool NFSProtocolV3::isConnected() const
+{
+ return (m_nfsClient != 0);
+}
+
+void NFSProtocolV3::closeConnection()
+{
+ qCDebug(LOG_KIO_NFS);
+
+ // Unmount all exported dirs(if any)
+ if (m_mountClient != 0) {
+ clnt_call(m_mountClient, MOUNTPROC3_UMNTALL,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_void, NULL,
+ clnt_timeout);
+ }
+
+ if (m_mountSock >= 0) {
+ ::close(m_mountSock);
+ m_mountSock = -1;
+ }
+ if (m_nfsSock >= 0) {
+ ::close(m_nfsSock);
+ m_nfsSock = -1;
+ }
+
+ if (m_mountClient != 0) {
+ CLNT_DESTROY(m_mountClient);
+ m_mountClient = 0;
+ }
+ if (m_nfsClient != 0) {
+ CLNT_DESTROY(m_nfsClient);
+ m_nfsClient = 0;
+ }
+}
+
+NFSFileHandle NFSProtocolV3::lookupFileHandle(const QString& path)
+{
+ int rpcStatus;
+ LOOKUP3res res;
+ if (lookupHandle(path, rpcStatus, res)) {
+ NFSFileHandle fh = res.LOOKUP3res_u.resok.object;
+
+ // Is it a link? Get the link target.
+ if (res.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.type == NF3LNK) {
+ READLINK3args readLinkArgs;
+ memset(&readLinkArgs, 0, sizeof(readLinkArgs));
+ fh.toFH(readLinkArgs.symlink);
+
+ char dataBuffer[NFS3_MAXPATHLEN];
+
+ READLINK3res readLinkRes;
+ memset(&readLinkRes, 0, sizeof(readLinkRes));
+ readLinkRes.READLINK3res_u.resok.data = dataBuffer;
+
+ int rpcStatus = clnt_call(m_nfsClient, NFSPROC3_READLINK,
+ (xdrproc_t) xdr_READLINK3args, reinterpret_cast<caddr_t>(&readLinkArgs),
+ (xdrproc_t) xdr_READLINK3res, reinterpret_cast<caddr_t>(&readLinkRes),
+ clnt_timeout);
+
+ if (rpcStatus == RPC_SUCCESS && readLinkRes.status == NFS3_OK) {
+ const QString linkDest = QString::fromLocal8Bit(readLinkRes.READLINK3res_u.resok.data);
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(QFileInfo(path).path(), linkDest).absoluteFilePath();
+ }
+
+ LOOKUP3res linkRes;
+ if (lookupHandle(linkPath, rpcStatus, linkRes)) {
+ // It's a link, so return the target file handle, and add the link source to it.
+ NFSFileHandle linkFh = linkRes.LOOKUP3res_u.resok.object;
+ linkFh.setLinkSource(res.LOOKUP3res_u.resok.object);
+
+ qCDebug(LOG_KIO_NFS) << "Found target -" << linkPath;
+
+ return linkFh;
+ }
+ }
+
+ // If we have reached this point the file is a link, but we failed to get the target.
+ fh.setBadLink();
+ qCDebug(LOG_KIO_NFS) << path << "is an invalid link!!";
+ }
+
+ return fh;
+ }
+
+ return NFSFileHandle();
+}
+
+/* Open connection connects to the mount daemon on the server side.
+ In order to do this it needs authentication and calls auth_unix_create().
+ Then it asks the mount daemon for the exported shares. Then it tries
+ to mount all these shares. If this succeeded for at least one of them,
+ a client for the nfs daemon is created.
+ */
+void NFSProtocolV3::openConnection()
+{
+ qCDebug(LOG_KIO_NFS) << m_currentHost;
+
+ // Destroy the old connection first
+ closeConnection();
+
+ int connErr;
+ if ((connErr = NFSProtocol::openConnection(m_currentHost, MOUNT_PROGRAM, MOUNT_V3, m_mountClient, m_mountSock)) != 0) {
+ closeConnection();
+ m_slave->error(connErr, m_currentHost);
+ return;
+ }
+
+ exports3 exportlist;
+ memset(&exportlist, 0, sizeof(exportlist));
+
+ int clnt_stat = clnt_call(m_mountClient, MOUNTPROC3_EXPORT,
+ (xdrproc_t) xdr_void, NULL,
+ (xdrproc_t) xdr_exports3, reinterpret_cast<caddr_t>(&exportlist),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, 0, m_currentHost.toLatin1())) {
+ closeConnection();
+ return;
+ }
+
+ int exportsCount = 0;
+ QStringList failList;
+
+ mountres3 fhStatus;
+ for (; exportlist != 0; exportlist = exportlist->ex_next, exportsCount++) {
+ memset(&fhStatus, 0, sizeof(fhStatus));
+ clnt_stat = clnt_call(m_mountClient, MOUNTPROC3_MNT,
+ (xdrproc_t) xdr_dirpath3, reinterpret_cast<caddr_t>(&exportlist->ex_dir),
+ (xdrproc_t) xdr_mountres3, reinterpret_cast<caddr_t>(&fhStatus),
+ clnt_timeout);
+
+ if (fhStatus.fhs_status == 0) {
+ QString fname = QFileInfo(QDir("/"), exportlist->ex_dir).filePath();
+
+ // Check if the dir is already exported
+ if (NFSProtocol::isExportedDir(fname)) {
+ continue;
+ }
+
+ addFileHandle(fname, static_cast<NFSFileHandle>(fhStatus.mountres3_u.mountinfo.fhandle));
+ addExportedDir(fname);
+ } else {
+ failList.append(exportlist->ex_dir);
+ }
+ }
+ if (failList.size() > 0) {
+ m_slave->error(KIO::ERR_COULD_NOT_MOUNT, i18n("Failed to mount %1", failList.join(", ")));
+
+ // All exports failed to mount, fail
+ if (failList.size() == exportsCount) {
+ closeConnection();
+ return;
+ }
+ }
+
+ if ((connErr = NFSProtocol::openConnection(m_currentHost, NFSPROG, NFSVERS, m_nfsClient, m_nfsSock)) != 0) {
+ closeConnection();
+ m_slave->error(connErr, m_currentHost);
+ }
+
+ m_slave->connected();
+
+ qCDebug(LOG_KIO_NFS) << "openConnection succeeded";
+}
+
+void NFSProtocolV3::listDir(const QUrl& url)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ // We should always be connected if it reaches this point,
+ // but better safe than sorry!
+ if (!isConnected()) {
+ return;
+ }
+
+ if (url.isEmpty()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, url.path());
+ return;
+ }
+
+ const QString path(url.path());
+
+ // Is it part of an exported(virtual) dir?
+ if (isExportedDir(path)) {
+ qCDebug(LOG_KIO_NFS) << "Listing virtual dir" << path;
+
+ QStringList virtualList;
+ for (QStringList::const_iterator it = getExportedDirs().constBegin(); it != getExportedDirs().constEnd(); ++it) {
+ // When an export is multiple levels deep(/mnt/nfs for example) we only
+ // want to display one level at a time.
+ QString name = (*it);
+ name = name.remove(0, path.length());
+ if (name.startsWith(QDir::separator())) {
+ name = name.mid(1);
+ }
+ if (name.indexOf(QDir::separator()) != -1) {
+ name.truncate(name.indexOf(QDir::separator()));
+ }
+
+ if (!virtualList.contains(name)) {
+ virtualList.append(name);
+ }
+ }
+
+ for (QStringList::const_iterator it = virtualList.constBegin(); it != virtualList.constEnd(); ++it) {
+ qCDebug(LOG_KIO_NFS) << "Found " << (*it) << "in exported dir";
+
+ KIO::UDSEntry entry;
+ entry.insert(KIO::UDSEntry::UDS_NAME, (*it));
+ createVirtualDirEntry(entry);
+ m_slave->listEntry(entry);
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(path);
+
+ // There doesn't seem to be an invalid link error code in KIO, so this will have to do.
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ // Get the preferred read dir size from the server
+ if (m_readDirSize == 0) {
+ initPreferredSizes(fh);
+ }
+
+ READDIRPLUS3args listargs;
+ memset(&listargs, 0, sizeof(listargs));
+ listargs.dircount = m_readDirSize;
+ listargs.maxcount = sizeof(entryplus3) * m_readDirSize; // Not really sure what this should be set to.
+
+ fh.toFH(listargs.dir);
+
+ READDIRPLUS3res listres;
+ memset(&listres, 0, sizeof(listres));
+
+ entryplus3* lastEntry = 0;
+ do {
+ memset(&listres, 0, sizeof(listres));
+
+ // In case that we didn't get all entries we need to set the cookie to the last one we actually received.
+ if (lastEntry != 0) {
+ listargs.cookie = lastEntry->cookie;
+ }
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_READDIRPLUS,
+ (xdrproc_t) xdr_READDIRPLUS3args, reinterpret_cast<caddr_t>(&listargs),
+ (xdrproc_t) xdr_READDIRPLUS3res, reinterpret_cast<caddr_t>(&listres),
+ clnt_timeout);
+
+ // Not a supported call? Try the old READDIR method.
+ if (listres.status == NFS3ERR_NOTSUPP) {
+ listDirCompat(url);
+ return;
+ }
+
+ // Do we have an error? There's not much more we can do but to abort at this point.
+ if (!checkForError(clnt_stat, listres.status, path)) {
+ return;
+ }
+
+ for (entryplus3* dirEntry = listres.READDIRPLUS3res_u.resok.reply.entries; dirEntry != 0; dirEntry = dirEntry->nextentry) {
+ if (dirEntry->name == QString(".") || dirEntry->name == QString("..")) {
+ continue;
+ }
+
+ const QString& filePath = QFileInfo(QDir(path), dirEntry->name).filePath();
+
+ KIO::UDSEntry entry;
+ entry.insert(KIO::UDSEntry::UDS_NAME, dirEntry->name);
+
+ // Is it a symlink ?
+ if (dirEntry->name_attributes.post_op_attr_u.attributes.type == NF3LNK) {
+ int rpcStatus;
+ READLINK3res readLinkRes;
+ char nameBuf[NFS3_MAXPATHLEN];
+ if (readLink(filePath, rpcStatus, readLinkRes, nameBuf)) {
+ QString linkDest = QString::fromLocal8Bit(readLinkRes.READLINK3res_u.resok.data);
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, linkDest);
+
+ bool badLink = true;
+ NFSFileHandle linkFH;
+ if (isValidLink(path, linkDest)) {
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(path, linkDest).absoluteFilePath();
+ }
+
+ int rpcStatus;
+ LOOKUP3res lookupRes;
+ if (lookupHandle(linkPath, rpcStatus, lookupRes)) {
+ GETATTR3res attrAndStat;
+ if (getAttr(linkPath, rpcStatus, attrAndStat)) {
+ badLink = false;
+
+ linkFH = lookupRes.LOOKUP3res_u.resok.object;
+ linkFH.setLinkSource(dirEntry->name_handle.post_op_fh3_u.handle);
+
+ completeUDSEntry(entry, attrAndStat.GETATTR3res_u.resok.obj_attributes);
+ }
+ }
+ }
+
+ if (badLink) {
+ linkFH = dirEntry->name_handle.post_op_fh3_u.handle;
+ linkFH.setBadLink();
+
+ completeBadLinkUDSEntry(entry, dirEntry->name_attributes.post_op_attr_u.attributes);
+ }
+
+ addFileHandle(filePath, linkFH);
+ } else {
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, i18n("Unknown target"));
+ completeBadLinkUDSEntry(entry, dirEntry->name_attributes.post_op_attr_u.attributes);
+ }
+ } else {
+ addFileHandle(filePath, static_cast<NFSFileHandle>(dirEntry->name_handle.post_op_fh3_u.handle));
+
+ completeUDSEntry(entry, dirEntry->name_attributes.post_op_attr_u.attributes);
+ }
+
+ m_slave->listEntry(entry);
+
+ lastEntry = dirEntry;
+ }
+ } while (listres.READDIRPLUS3res_u.resok.reply.entries != NULL && !listres.READDIRPLUS3res_u.resok.reply.eof);
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::listDirCompat(const QUrl& url)
+{
+ // We should always be connected if it reaches this point,
+ // but better safe than sorry!
+ if (!isConnected()) {
+ return;
+ }
+
+ if (url.isEmpty()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, url.path());
+ }
+
+ const QString path(url.path());
+
+ // Is it part of an exported (virtual) dir?
+ if (NFSProtocol::isExportedDir(path)) {
+ QStringList virtualList;
+ for (QStringList::const_iterator it = getExportedDirs().constBegin(); it != getExportedDirs().constEnd(); ++it) {
+ // When an export is multiple levels deep(mnt/nfs for example) we only
+ // want to display one level at a time.
+ QString name = (*it);
+ name = name.remove(0, path.length());
+ if (name.startsWith('/')) {
+ name = name.mid(1);
+ }
+ if (name.indexOf('/') != -1) {
+ name.truncate(name.indexOf('/'));
+ }
+
+ if (!virtualList.contains(name)) {
+ virtualList.append(name);
+ }
+ }
+
+ for (QStringList::const_iterator it = virtualList.constBegin(); it != virtualList.constEnd(); ++it) {
+ qCDebug(LOG_KIO_NFS) << "Found " << (*it) << "in exported dir";
+
+ KIO::UDSEntry entry;
+ entry.insert(KIO::UDSEntry::UDS_NAME, (*it));
+ createVirtualDirEntry(entry);
+ m_slave->listEntry(entry);
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ QStringList filesToList;
+
+ READDIR3args listargs;
+ memset(&listargs, 0, sizeof(listargs));
+ listargs.count = m_readDirSize;
+ fh.toFH(listargs.dir);
+
+ READDIR3res listres;
+ entry3* lastEntry = 0;
+ do {
+ memset(&listres, 0, sizeof(listres));
+
+ // In case that we didn't get all entries we need to set the cookie to the last one we actually received
+ if (lastEntry != 0) {
+ listargs.cookie = lastEntry->cookie;
+ }
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_READDIR,
+ (xdrproc_t) xdr_READDIR3args, reinterpret_cast<caddr_t>(&listargs),
+ (xdrproc_t) xdr_READDIR3res, reinterpret_cast<caddr_t>(&listres),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, listres.status, path)) {
+ return;
+ }
+
+ for (entry3* dirEntry = listres.READDIR3res_u.resok.reply.entries; dirEntry != 0; dirEntry = dirEntry->nextentry) {
+ if (dirEntry->name != QString(".") && dirEntry->name != QString("..")) {
+ filesToList.append(QFile::decodeName(dirEntry->name));
+ }
+
+ lastEntry = dirEntry;
+ }
+ } while (!listres.READDIR3res_u.resok.reply.eof);
+
+ // Loop through all files, getting attributes and link path.
+ KIO::UDSEntry entry;
+ for (QStringList::const_iterator it = filesToList.constBegin(); it != filesToList.constEnd(); ++it) {
+ QString filePath = QFileInfo(QDir(path), (*it)).filePath();
+
+ int rpcStatus;
+ LOOKUP3res dirres;
+ if (!lookupHandle(filePath, rpcStatus, dirres)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to lookup" << filePath << ", rpc:" << rpcStatus << ", nfs:" << dirres.status;
+ // Try the next file instead of aborting
+ continue;
+ }
+
+ entry.clear();
+ entry.insert(KIO::UDSEntry::UDS_NAME, (*it));
+
+ // Is it a symlink?
+ if (dirres.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.type == NF3LNK) {
+ int rpcStatus;
+ READLINK3res readLinkRes;
+ char nameBuf[NFS3_MAXPATHLEN];
+ if (readLink(filePath, rpcStatus, readLinkRes, nameBuf)) {
+ const QString linkDest = QString::fromLocal8Bit(readLinkRes.READLINK3res_u.resok.data);
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, linkDest);
+
+ bool badLink = true;
+ NFSFileHandle linkFH;
+ if (isValidLink(path, linkDest)) {
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(path, linkDest).absoluteFilePath();
+ }
+
+ int rpcStatus;
+ LOOKUP3res lookupRes;
+ if (lookupHandle(linkPath, rpcStatus, lookupRes)) {
+ GETATTR3res attrAndStat;
+ if (getAttr(linkPath, rpcStatus, attrAndStat)) {
+ badLink = false;
+
+ linkFH = lookupRes.LOOKUP3res_u.resok.object;
+ linkFH.setLinkSource(dirres.LOOKUP3res_u.resok.object);
+
+ completeUDSEntry(entry, attrAndStat.GETATTR3res_u.resok.obj_attributes);
+ }
+ }
+ }
+
+ if (badLink) {
+ linkFH = dirres.LOOKUP3res_u.resok.object;
+ linkFH.setBadLink();
+
+ completeBadLinkUDSEntry(entry, dirres.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes);
+ }
+
+ addFileHandle(filePath, linkFH);
+ } else {
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, i18n("Unknown target"));
+ completeBadLinkUDSEntry(entry, dirres.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes);
+ }
+ } else {
+ addFileHandle(filePath, dirres.LOOKUP3res_u.resok.object);
+
+ completeUDSEntry(entry, dirres.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes);
+ }
+
+ m_slave->listEntry(entry);
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::stat(const QUrl& url)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+
+ // We can't stat an exported dir, but we know it's a dir.
+ if (isExportedDir(path)) {
+ KIO::UDSEntry entry;
+
+ entry.insert(KIO::UDSEntry::UDS_NAME, path);
+ createVirtualDirEntry(entry);
+
+ m_slave->statEntry(entry);
+ m_slave->finished();
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid()) {
+ qCDebug(LOG_KIO_NFS) << "File handle is invalid";
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ int rpcStatus;
+ GETATTR3res attrAndStat;
+ if (!getAttr(path, rpcStatus, attrAndStat)) {
+ checkForError(rpcStatus, attrAndStat.status, path);
+ return;
+ }
+
+ const QFileInfo fileInfo(path);
+
+ KIO::UDSEntry entry;
+ entry.insert(KIO::UDSEntry::UDS_NAME, fileInfo.fileName());
+
+ // Is it a symlink?
+ if (attrAndStat.GETATTR3res_u.resok.obj_attributes.type == NF3LNK) {
+ qCDebug(LOG_KIO_NFS) << "It's a symlink";
+
+ //get the link dest
+ QString linkDest;
+
+ int rpcStatus;
+ READLINK3res readLinkRes;
+ char nameBuf[NFS3_MAXPATHLEN];
+ if (readLink(path, rpcStatus, readLinkRes, nameBuf)) {
+ linkDest = QString::fromLocal8Bit(readLinkRes.READLINK3res_u.resok.data);
+ } else {
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, linkDest);
+ completeBadLinkUDSEntry(entry, attrAndStat.GETATTR3res_u.resok.obj_attributes);
+
+ m_slave->statEntry(entry);
+ m_slave->finished();
+ return;
+ }
+
+ qCDebug(LOG_KIO_NFS) << "link dest is" << linkDest;
+
+ entry.insert(KIO::UDSEntry::UDS_LINK_DEST, linkDest);
+
+ if (!isValidLink(fileInfo.path(), linkDest)) {
+ completeBadLinkUDSEntry(entry, attrAndStat.GETATTR3res_u.resok.obj_attributes);
+ } else {
+ QString linkPath;
+ if (QFileInfo(linkDest).isAbsolute()) {
+ linkPath = linkDest;
+ } else {
+ linkPath = QFileInfo(fileInfo.path(), linkDest).absoluteFilePath();
+ }
+
+ int rpcStatus;
+ GETATTR3res attrAndStat;
+ if (!getAttr(linkPath, rpcStatus, attrAndStat)) {
+ checkForError(rpcStatus, attrAndStat.status, linkPath);
+ return;
+ }
+
+ completeUDSEntry(entry, attrAndStat.GETATTR3res_u.resok.obj_attributes);
+ }
+ } else {
+ completeUDSEntry(entry, attrAndStat.GETATTR3res_u.resok.obj_attributes);
+ }
+
+ m_slave->statEntry(entry);
+ m_slave->finished();
+}
+
+void NFSProtocolV3::setHost(const QString& host)
+{
+ qCDebug(LOG_KIO_NFS) << host;
+
+ if (host.isEmpty()) {
+ m_slave->error(KIO::ERR_UNKNOWN_HOST, QString());
+ return;
+ }
+
+ // No need to update if the host hasn't changed
+ if (host == m_currentHost) {
+ return;
+ }
+
+ m_currentHost = host;
+ closeConnection();
+}
+
+void NFSProtocolV3::mkdir(const QUrl& url, int permissions)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+
+ const QFileInfo fileInfo(path);
+ if (isExportedDir(fileInfo.path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, path);
+ return;
+ }
+
+ const NFSFileHandle fh = getFileHandle(fileInfo.path());
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ MKDIR3args createArgs;
+ memset(&createArgs, 0, sizeof(createArgs));
+ fh.toFH(createArgs.where.dir);
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+ createArgs.where.name = tmpName.data();
+
+ createArgs.attributes.mode.set_it = true;
+ if (permissions == -1) {
+ createArgs.attributes.mode.set_mode3_u.mode = 0755;
+ } else {
+ createArgs.attributes.mode.set_mode3_u.mode = permissions;
+ }
+
+ MKDIR3res dirres;
+ memset(&dirres, 0, sizeof(dirres));
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_MKDIR,
+ (xdrproc_t) xdr_MKDIR3args, reinterpret_cast<caddr_t>(&createArgs),
+ (xdrproc_t) xdr_MKDIR3res, reinterpret_cast<caddr_t>(&dirres),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, dirres.status, path)) {
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::del(const QUrl& url, bool/* isfile*/)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+
+ if (isExportedDir(QFileInfo(path).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, path);
+ return;
+ }
+
+ int rpcStatus;
+ REMOVE3res res;
+ if (!remove(path, rpcStatus, res)) {
+ checkForError(rpcStatus, res.status, path);
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::chmod(const QUrl& url, int permissions)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+ if (isExportedDir(path)) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, path);
+ return;
+ }
+
+ sattr3 attributes;
+ memset(&attributes, 0, sizeof(attributes));
+ attributes.mode.set_it = true;
+ attributes.mode.set_mode3_u.mode = permissions;
+
+ int rpcStatus;
+ SETATTR3res setAttrRes;
+ if (!setAttr(path, attributes, rpcStatus, setAttrRes)) {
+ checkForError(rpcStatus, setAttrRes.status, path);
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::get(const QUrl& url)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString path(url.path());
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid() || fh.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, path);
+ return;
+ }
+
+ // Get the optimal read buffer size.
+ if (m_readBufferSize == 0) {
+ initPreferredSizes(fh);
+ }
+
+ READ3args readArgs;
+ memset(&readArgs, 0, sizeof(readArgs));
+ fh.toFH(readArgs.file);
+ readArgs.offset = 0;
+ readArgs.count = m_readBufferSize;
+
+ READ3res readRes;
+ memset(&readRes, 0, sizeof(readRes));
+ readRes.READ3res_u.resok.data.data_len = m_readBufferSize;
+ readRes.READ3res_u.resok.data.data_val = new char[m_readBufferSize];
+
+ // Most likely indicates out of memory
+ if (!readRes.READ3res_u.resok.data.data_val) {
+ m_slave->error(KIO::ERR_OUT_OF_MEMORY, path);
+ return;
+ }
+
+ bool validRead = false;
+ bool hasError = false;
+ int read = 0;
+ QByteArray readBuffer;
+ do {
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_READ,
+ (xdrproc_t) xdr_READ3args, reinterpret_cast<caddr_t>(&readArgs),
+ (xdrproc_t) xdr_READ3res, reinterpret_cast<caddr_t>(&readRes),
+ clnt_timeout);
+
+ // We are trying to read a directory, fail quietly
+ if (readRes.status == NFS3ERR_ISDIR) {
+ break;
+ }
+
+ if (!checkForError(clnt_stat, readRes.status, path)) {
+ hasError = true;
+ break;
+ }
+
+ read = readRes.READ3res_u.resok.count;
+ readBuffer.setRawData(readRes.READ3res_u.resok.data.data_val, read);
+
+ if (readArgs.offset == 0) {
+ const QMimeDatabase db;
+ const QMimeType type = db.mimeTypeForFileNameAndData(url.fileName(), readBuffer);
+ m_slave->mimeType(type.name());
+
+ m_slave->totalSize(readRes.READ3res_u.resok.file_attributes.post_op_attr_u.attributes.size);
+ }
+
+ readArgs.offset += read;
+ if (read > 0) {
+ validRead = true;
+
+ m_slave->data(readBuffer);
+ m_slave->processedSize(readArgs.offset);
+ }
+
+ } while (read > 0);
+
+ if (readRes.READ3res_u.resok.data.data_val != NULL) {
+ delete [] readRes.READ3res_u.resok.data.data_val;
+ }
+
+ // Only send the read data to the slave if we have actually sent some.
+ if (validRead) {
+ m_slave->data(QByteArray());
+ m_slave->processedSize(readArgs.offset);
+ }
+
+ if (!hasError) {
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV3::put(const QUrl& url, int _mode, KIO::JobFlags flags)
+{
+ qCDebug(LOG_KIO_NFS) << url;
+
+ const QString destPath(url.path());
+
+ if (isExportedDir(QFileInfo(destPath).path())) {
+ m_slave->error(KIO::ERR_WRITE_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ NFSFileHandle destFH = getFileHandle(destPath);
+ if (destFH.isBadLink()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, destPath);
+ return;
+ }
+
+ // the file exists and we don't want to overwrite
+ if (!destFH.isInvalid() && ((flags & KIO::Overwrite) == 0)) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Get the optimal write buffer size
+ if (m_writeBufferSize == 0) {
+ initPreferredSizes(destFH);
+ }
+
+ int rpcStatus;
+ CREATE3res createRes;
+ if (!create(destPath, _mode, rpcStatus, createRes)) {
+ checkForError(rpcStatus, createRes.status, destPath);
+ return;
+ }
+
+ // We created the file successfully.
+ destFH = createRes.CREATE3res_u.resok.obj.post_op_fh3_u.handle;
+
+ int result;
+
+ WRITE3args writeArgs;
+ memset(&writeArgs, 0, sizeof(writeArgs));
+
+ destFH.toFH(writeArgs.file);
+ writeArgs.offset = 0;
+ writeArgs.stable = FILE_SYNC;
+
+ WRITE3res writeRes;
+ memset(&writeRes, 0, sizeof(writeRes));
+
+ // Loop until we get 0 (end of data).
+ int bytesWritten = 0;
+ bool error = false;
+ do {
+ QByteArray buffer;
+ m_slave->dataReq();
+ result = m_slave->readData(buffer);
+
+ if (result > 0) {
+ char* data = buffer.data();
+ uint32 bytesToWrite = buffer.size();
+ int writeNow(0);
+
+ do {
+ if (bytesToWrite > m_writeBufferSize) {
+ writeNow = m_writeBufferSize;
+ } else {
+ writeNow = bytesToWrite;
+ }
+
+ writeArgs.data.data_val = data;
+ writeArgs.data.data_len = writeNow;
+ writeArgs.count = writeNow;
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_WRITE,
+ (xdrproc_t) xdr_WRITE3args, reinterpret_cast<caddr_t>(&writeArgs),
+ (xdrproc_t) xdr_WRITE3res, reinterpret_cast<caddr_t>(&writeRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, writeRes.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ writeNow = writeRes.WRITE3res_u.resok.count;
+
+ bytesWritten += writeNow;
+ writeArgs.offset = bytesWritten;
+
+ data = data + writeNow;
+ bytesToWrite -= writeNow;
+ } while (bytesToWrite > 0);
+ }
+
+ if (error) {
+ break;
+ }
+ } while (result > 0);
+
+ if (!error) {
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV3::rename(const QUrl& src, const QUrl& dest, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << dest;
+
+ const QString srcPath(src.path());
+ if (isExportedDir(srcPath)) {
+ m_slave->error(KIO::ERR_CANNOT_RENAME, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+ if (isExportedDir(destPath)) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ if (!getFileHandle(destPath).isInvalid() && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ int rpcStatus;
+ RENAME3res res;
+ if (!rename(srcPath, destPath, rpcStatus, res)) {
+ checkForError(rpcStatus, res.status, destPath);
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::copySame(const QUrl& src, const QUrl& dest, int _mode, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ const QString srcPath(src.path());
+
+ if (isExportedDir(QFileInfo(srcPath).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, srcPath);
+ return;
+ }
+
+ const NFSFileHandle srcFH = getFileHandle(srcPath);
+ if (srcFH.isInvalid()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+
+ if (isExportedDir(QFileInfo(destPath).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ // The file exists and we don't want to overwrite
+ if (!getFileHandle(destPath).isInvalid() && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Is it a link? No need to copy the data then, just copy the link destination.
+ if (srcFH.isLink()) {
+ //get the link dest
+ int rpcStatus;
+ READLINK3res readLinkRes;
+ char nameBuf[NFS3_MAXPATHLEN];
+ if (!readLink(srcPath, rpcStatus, readLinkRes, nameBuf)) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString linkPath = QString::fromLocal8Bit(readLinkRes.READLINK3res_u.resok.data);
+
+ SYMLINK3res linkRes;
+ if (!symLink(linkPath, destPath, rpcStatus, linkRes)) {
+ checkForError(rpcStatus, linkRes.status, linkPath);
+ return;
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ unsigned long resumeOffset = 0;
+ bool bResume = false;
+ const QString partFilePath = destPath + QLatin1String(".part");
+ const NFSFileHandle partFH = getFileHandle(partFilePath);
+ const bool bPartExists = !partFH.isInvalid();
+ const bool bMarkPartial = m_slave->config()->readEntry("MarkPartial", true);
+
+ if (bPartExists) {
+ int rpcStatus;
+ LOOKUP3res partRes;
+ if (lookupHandle(partFilePath, rpcStatus, partRes)) {
+ if (bMarkPartial && partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.size > 0) {
+ if (partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.type == NF3DIR) {
+ m_slave->error(KIO::ERR_IS_DIRECTORY, partFilePath);
+ return;
+ }
+
+ bResume = m_slave->canResume(partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.size);
+ if (bResume) {
+ resumeOffset = partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.size;
+ }
+ }
+ }
+
+ // Remove the part file if we are not resuming
+ if (!bResume) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+
+ // Create the file if we are not resuming a parted transfer,
+ // or if we are not using part files(bResume is false in that case)
+ NFSFileHandle destFH;
+ if (!bResume) {
+ QString createPath;
+ if (bMarkPartial) {
+ createPath = partFilePath;
+ } else {
+ createPath = destPath;
+ }
+
+ int rpcStatus;
+ CREATE3res createRes;
+ if (!create(createPath, _mode, rpcStatus, createRes)) {
+ checkForError(rpcStatus, createRes.status, createPath);
+ return;
+ }
+
+ destFH = createRes.CREATE3res_u.resok.obj.post_op_fh3_u.handle;
+ } else {
+ // Since we are resuming it's implied that we are using a part file,
+ // which should exist at this point.
+ destFH = getFileHandle(partFilePath);
+
+ qCDebug(LOG_KIO_NFS) << "Resuming old transfer";
+ }
+
+ // Check what buffer size we should use, always use the smallest one.
+ const int bufferSize = (m_readBufferSize < m_writeBufferSize) ? m_readBufferSize : m_writeBufferSize;
+
+ WRITE3args writeArgs;
+ memset(&writeArgs, 0, sizeof(writeArgs));
+
+ destFH.toFH(writeArgs.file);
+ writeArgs.offset = 0;
+ writeArgs.data.data_val = new char[bufferSize];
+ writeArgs.stable = FILE_SYNC;
+
+ READ3args readArgs;
+ memset(&readArgs, 0, sizeof(readArgs));
+
+ srcFH.toFH(readArgs.file);
+ readArgs.offset = 0;
+ readArgs.count = bufferSize;
+
+ if (bResume) {
+ writeArgs.offset = resumeOffset;
+ readArgs.offset = resumeOffset;
+ }
+
+ READ3res readRes;
+ readRes.READ3res_u.resok.data.data_val = writeArgs.data.data_val;
+
+ WRITE3res writeRes;
+ memset(&writeRes, 0, sizeof(WRITE3res));
+
+ bool error = false;
+ int bytesRead = 0;
+ do {
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_READ,
+ (xdrproc_t) xdr_READ3args, reinterpret_cast<caddr_t>(&readArgs),
+ (xdrproc_t) xdr_READ3res, reinterpret_cast<caddr_t>(&readRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, readRes.status, srcPath)) {
+ error = true;
+ break;
+ }
+
+ bytesRead = readRes.READ3res_u.resok.data.data_len;
+
+ // We should only send out the total size and mimetype at the start of the transfer
+ if (readArgs.offset == 0 || (bResume && writeArgs.offset == resumeOffset)) {
+ QMimeDatabase db;
+ QMimeType type = db.mimeTypeForFileNameAndData(src.fileName(), QByteArray::fromRawData(writeArgs.data.data_val, bytesRead));
+ m_slave->mimeType(type.name());
+
+ m_slave->totalSize(readRes.READ3res_u.resok.file_attributes.post_op_attr_u.attributes.size);
+ }
+
+ if (bytesRead > 0) {
+ readArgs.offset += bytesRead;
+
+ writeArgs.count = bytesRead;
+ writeArgs.data.data_len = bytesRead;
+
+ clnt_stat = clnt_call(m_nfsClient, NFSPROC3_WRITE,
+ (xdrproc_t) xdr_WRITE3args, reinterpret_cast<caddr_t>(&writeArgs),
+ (xdrproc_t) xdr_WRITE3res, reinterpret_cast<caddr_t>(&writeRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, writeRes.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ writeArgs.offset += bytesRead;
+
+ m_slave->processedSize(readArgs.offset);
+ }
+ } while (bytesRead > 0);
+
+ delete [] writeArgs.data.data_val;
+
+ if (error) {
+ if (bMarkPartial) {
+ // Remove the part file if it's smaller than the minimum keep size.
+ const unsigned int size = m_slave->config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
+ if (writeArgs.offset < size) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+ } else {
+ // Rename partial file to its original name.
+ if (bMarkPartial) {
+ // Remove the destination file(if it exists)
+ if (!getFileHandle(destPath).isInvalid() && !remove(destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove destination file" << destPath << ", ignoring...";
+ }
+
+ if (!rename(partFilePath, destPath)) {
+ qCDebug(LOG_KIO_NFS) << "failed to rename" << partFilePath << "to" << destPath;
+ m_slave->error(KIO::ERR_CANNOT_RENAME_PARTIAL, partFilePath);
+ return;
+ }
+ }
+
+ // Restore modification time
+ int rpcStatus;
+ GETATTR3res attrRes;
+ if (getAttr(srcPath, rpcStatus, attrRes)) {
+ sattr3 attributes;
+ memset(&attributes, 0, sizeof(attributes));
+ attributes.mtime.set_it = SET_TO_CLIENT_TIME;
+ attributes.mtime.set_mtime_u.mtime.seconds = attrRes.GETATTR3res_u.resok.obj_attributes.mtime.seconds;
+ attributes.mtime.set_mtime_u.mtime.nseconds = attrRes.GETATTR3res_u.resok.obj_attributes.mtime.nseconds;
+
+ SETATTR3res attrSetRes;
+ if (!setAttr(destPath, attributes, rpcStatus, attrSetRes)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to restore mtime, ignoring..." << rpcStatus << attrSetRes.status;
+ }
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Copied" << writeArgs.offset << "bytes of data";
+
+ m_slave->processedSize(readArgs.offset);
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV3::copyFrom(const QUrl& src, const QUrl& dest, int _mode, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ const QString srcPath(src.path());
+
+ const NFSFileHandle srcFH = getFileHandle(srcPath);
+ if (srcFH.isInvalid()) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+
+ // The file exists and we don't want to overwrite.
+ if (QFile::exists(destPath) && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Is it a link? No need to copy the data then, just copy the link destination.
+ if (srcFH.isLink()) {
+ qCDebug(LOG_KIO_NFS) << "Is a link";
+
+ //get the link dest
+ int rpcStatus;
+ READLINK3res readLinkRes;
+ char nameBuf[NFS3_MAXPATHLEN];
+ if (!readLink(srcPath, rpcStatus, readLinkRes, nameBuf)) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ QFile::link(QString::fromLocal8Bit(readLinkRes.READLINK3res_u.resok.data), destPath);
+
+ m_slave->finished();
+ return;
+ }
+
+ if (m_readBufferSize == 0) {
+ initPreferredSizes(srcFH);
+ }
+
+ unsigned int resumeOffset = 0;
+ bool bResume = false;
+ const QFileInfo partInfo(destPath + QLatin1String(".part"));
+ const bool bPartExists = partInfo.exists();
+ const bool bMarkPartial = m_slave->config()->readEntry("MarkPartial", true);
+
+ if (bMarkPartial && bPartExists && partInfo.size() > 0) {
+ if (partInfo.isDir()) {
+ m_slave->error(KIO::ERR_IS_DIRECTORY, partInfo.absoluteFilePath());
+ return;
+ }
+
+ bResume = m_slave->canResume(partInfo.size());
+ resumeOffset = partInfo.size();
+ }
+
+ if (bPartExists && !bResume) {
+ QFile::remove(partInfo.absoluteFilePath());
+ }
+
+ QFile::OpenMode openMode;
+ QString outFileName;
+ if (bResume) {
+ outFileName = partInfo.absoluteFilePath();
+ openMode = QFile::WriteOnly | QFile::Append;
+ } else {
+ outFileName = (bMarkPartial ? partInfo.absoluteFilePath() : destPath);
+ openMode = QFile::WriteOnly | QFile::Truncate;
+ }
+
+ QFile destFile(outFileName);
+ if (!bResume) {
+ QFile::Permissions perms;
+ if (_mode == -1) {
+ perms = QFile::ReadOwner | QFile::WriteOwner;
+ } else {
+ perms = KIO::convertPermissions(_mode | QFile::WriteOwner);
+ }
+
+ destFile.setPermissions(perms);
+ }
+
+ if (!destFile.open(openMode)) {
+ switch (destFile.error()) {
+ case QFile::OpenError:
+ if (bResume) {
+ m_slave->error(KIO::ERR_CANNOT_RESUME, destPath);
+ } else {
+ m_slave->error(KIO::ERR_CANNOT_OPEN_FOR_WRITING, destPath);
+ }
+ break;
+ case QFile::PermissionsError:
+ m_slave->error(KIO::ERR_WRITE_ACCESS_DENIED, destPath);
+ break;
+ default:
+ m_slave->error(KIO::ERR_CANNOT_OPEN_FOR_WRITING, destPath);
+ break;
+ }
+ return;
+ }
+
+ READ3args readArgs;
+ srcFH.toFH(readArgs.file);
+ if (bResume) {
+ readArgs.offset = resumeOffset;
+ } else {
+ readArgs.offset = 0;
+ }
+ readArgs.count = m_readBufferSize;
+
+ READ3res readRes;
+ memset(&readRes, 0, sizeof(readres));
+ readRes.READ3res_u.resok.data.data_val = new char[m_readBufferSize];
+ readRes.READ3res_u.resok.data.data_len = m_readBufferSize;
+
+ bool error = false;
+ unsigned long bytesToRead = 0, bytesRead = 0;
+ do {
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_READ,
+ (xdrproc_t) xdr_READ3args, reinterpret_cast<caddr_t>(&readArgs),
+ (xdrproc_t) xdr_READ3res, reinterpret_cast<caddr_t>(&readRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, readRes.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ bytesRead = readRes.READ3res_u.resok.count;
+
+ if (readArgs.offset == 0 || (bResume && readArgs.offset == resumeOffset)) {
+ bytesToRead = readRes.READ3res_u.resok.file_attributes.post_op_attr_u.attributes.size;
+
+ m_slave->totalSize(bytesToRead);
+
+ QMimeDatabase db;
+ QMimeType type = db.mimeTypeForFileNameAndData(src.fileName(), QByteArray::fromRawData(readRes.READ3res_u.resok.data.data_val, bytesRead));
+ m_slave->mimeType(type.name());
+ }
+
+ if (bytesRead > 0) {
+ readArgs.offset += bytesRead;
+
+ if (destFile.write(readRes.READ3res_u.resok.data.data_val, bytesRead) < 0) {
+ m_slave->error(KIO::ERR_COULD_NOT_WRITE, destPath);
+
+ error = true;
+ break;
+ }
+
+ m_slave->processedSize(readArgs.offset);
+ }
+ } while (readArgs.offset < bytesToRead);
+
+ delete [] readRes.READ3res_u.resok.data.data_val;
+
+ // Close the file so we can modify the modification time later.
+ destFile.close();
+
+ if (error) {
+ if (bMarkPartial) {
+ // Remove the part file if it's smaller than the minimum keep
+ const int size = m_slave->config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
+ if (partInfo.size() < size) {
+ QFile::remove(partInfo.absoluteFilePath());
+ }
+ }
+ } else {
+ // Rename partial file to its original name.
+ if (bMarkPartial) {
+ const QString sPart = partInfo.absoluteFilePath();
+ if (QFile::exists(destPath)) {
+ QFile::remove(destPath);
+ }
+ if (!QFile::rename(sPart, destPath)) {
+ qCDebug(LOG_KIO_NFS) << "failed to rename" << sPart << "to" << destPath;
+ m_slave->error(KIO::ERR_CANNOT_RENAME_PARTIAL, sPart);
+ return;
+ }
+ }
+
+ // Restore the mtime on the file.
+ const QString mtimeStr = m_slave->metaData("modified");
+ if (!mtimeStr.isEmpty()) {
+ QDateTime dt = QDateTime::fromString(mtimeStr, Qt::ISODate);
+ if (dt.isValid()) {
+ struct utimbuf utbuf;
+ utbuf.actime = QFileInfo(destPath).lastRead().toTime_t(); // access time, unchanged
+ utbuf.modtime = dt.toTime_t(); // modification time
+ utime(QFile::encodeName(destPath).constData(), &utbuf);
+ }
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Copied" << readArgs.offset << "bytes of data";
+
+ m_slave->processedSize(readArgs.offset);
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV3::copyTo(const QUrl& src, const QUrl& dest, int _mode, KIO::JobFlags _flags)
+{
+ qCDebug(LOG_KIO_NFS) << src << "to" << dest;
+
+ // The source does not exist, how strange
+ const QString srcPath(src.path());
+ if (!QFile::exists(srcPath)) {
+ m_slave->error(KIO::ERR_DOES_NOT_EXIST, srcPath);
+ return;
+ }
+
+ const QString destPath(dest.path());
+ if (isExportedDir(QFileInfo(destPath).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ // The file exists and we don't want to overwrite.
+ if (!getFileHandle(destPath).isInvalid() && (_flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+ // Is it a link? No need to copy the data then, just copy the link destination.
+ const QString symlinkTarget = QFile::symLinkTarget(srcPath);
+ if (!symlinkTarget.isEmpty()) {
+ int rpcStatus;
+ SYMLINK3res linkRes;
+ if (!symLink(symlinkTarget, destPath, rpcStatus, linkRes)) {
+ checkForError(rpcStatus, linkRes.status, symlinkTarget);
+ return;
+ }
+
+ m_slave->finished();
+ return;
+ }
+
+ unsigned long resumeOffset = 0;
+ bool bResume = false;
+ const QString partFilePath = destPath + QLatin1String(".part");
+ const NFSFileHandle partFH = getFileHandle(partFilePath);
+ const bool bPartExists = !partFH.isInvalid();
+ const bool bMarkPartial = m_slave->config()->readEntry("MarkPartial", true);
+
+ if (bPartExists) {
+ int rpcStatus;
+ LOOKUP3res partRes;
+ if (lookupHandle(partFilePath, rpcStatus, partRes)) {
+ if (bMarkPartial && partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.size > 0) {
+ if (partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.type == NF3DIR) {
+ m_slave->error(KIO::ERR_IS_DIRECTORY, partFilePath);
+ return;
+ }
+
+ bResume = m_slave->canResume(partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.size);
+ if (bResume) {
+ resumeOffset = partRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.size;
+ }
+ }
+ }
+
+ // Remove the part file if we are not resuming
+ if (!bResume) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+
+ // Open the source file
+ QFile srcFile(srcPath);
+ if (!srcFile.open(QIODevice::ReadOnly)) {
+ m_slave->error(KIO::ERR_CANNOT_OPEN_FOR_READING, srcPath);
+ return;
+ }
+
+ // Create the file if we are not resuming a parted transfer,
+ // or if we are not using part files (bResume is false in that case)
+ NFSFileHandle destFH;
+ if (!bResume) {
+ QString createPath;
+ if (bMarkPartial) {
+ createPath = partFilePath;
+ } else {
+ createPath = destPath;
+ }
+
+ int rpcStatus;
+ CREATE3res createRes;
+ if (!create(createPath, _mode, rpcStatus, createRes)) {
+ checkForError(rpcStatus, createRes.status, createPath);
+ return;
+ }
+
+ destFH = createRes.CREATE3res_u.resok.obj.post_op_fh3_u.handle;
+ } else {
+ // Since we are resuming it's implied that we are using a part file,
+ // which should exist at this point.
+ destFH = getFileHandle(partFilePath);
+
+ qCDebug(LOG_KIO_NFS) << "Resuming old transfer";
+ }
+
+ // Send the total size to the slave.
+ m_slave->totalSize(srcFile.size());
+
+ // Get the optimal write buffer size
+ if (m_writeBufferSize == 0) {
+ initPreferredSizes(destFH);
+ }
+
+ // Set up write arguments.
+ WRITE3args writeArgs;
+ memset(&writeArgs, 0, sizeof(writeArgs));
+ destFH.toFH(writeArgs.file);
+ writeArgs.data.data_val = new char[m_writeBufferSize];
+ writeArgs.stable = FILE_SYNC;
+ if (bResume) {
+ writeArgs.offset = resumeOffset;
+ } else {
+ writeArgs.offset = 0;
+ }
+
+ WRITE3res writeRes;
+ memset(&writeRes, 0 , sizeof(writeRes));
+
+ bool error = false;
+ int bytesRead = 0;
+ do {
+ memset(writeArgs.data.data_val, 0, m_writeBufferSize);
+
+ bytesRead = srcFile.read(writeArgs.data.data_val, m_writeBufferSize);
+ if (bytesRead < 0) {
+ m_slave->error(KIO::ERR_COULD_NOT_READ, srcPath);
+
+ error = true;
+ break;
+ }
+
+ if (bytesRead > 0) {
+ writeArgs.count = bytesRead;
+ writeArgs.data.data_len = bytesRead;
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_WRITE,
+ (xdrproc_t) xdr_WRITE3args, reinterpret_cast<caddr_t>(&writeArgs),
+ (xdrproc_t) xdr_WRITE3res, reinterpret_cast<caddr_t>(&writeRes),
+ clnt_timeout);
+
+ if (!checkForError(clnt_stat, writeRes.status, destPath)) {
+ error = true;
+ break;
+ }
+
+ writeArgs.offset += bytesRead;
+
+ m_slave->processedSize(writeArgs.offset);
+ }
+ } while (bytesRead > 0);
+
+ delete [] writeArgs.data.data_val;
+
+ if (error) {
+ if (bMarkPartial) {
+ // Remove the part file if it's smaller than the minimum keep size.
+ const unsigned int size = m_slave->config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE);
+ if (writeArgs.offset < size) {
+ if (!remove(partFilePath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove part file, ignoring...";
+ }
+ }
+ }
+ } else {
+ // Rename partial file to its original name.
+ if (bMarkPartial) {
+ // Remove the destination file(if it exists)
+ if (!getFileHandle(destPath).isInvalid() && !remove(destPath)) {
+ qCDebug(LOG_KIO_NFS) << "Could not remove destination file" << destPath << ", ignoring...";
+ }
+
+ if (!rename(partFilePath, destPath)) {
+ qCDebug(LOG_KIO_NFS) << "failed to rename" << partFilePath << "to" << destPath;
+ m_slave->error(KIO::ERR_CANNOT_RENAME_PARTIAL, partFilePath);
+ return;
+ }
+ }
+
+ // Restore the mtime on the file.
+ const QString mtimeStr = m_slave->metaData("modified");
+ if (!mtimeStr.isEmpty()) {
+ QDateTime dt = QDateTime::fromString(mtimeStr, Qt::ISODate);
+ if (dt.isValid()) {
+ sattr3 attributes;
+ memset(&attributes, 0, sizeof(attributes));
+ attributes.mtime.set_it = SET_TO_CLIENT_TIME;
+ attributes.mtime.set_mtime_u.mtime.seconds = dt.toTime_t();
+ attributes.mtime.set_mtime_u.mtime.nseconds = attributes.mtime.set_mtime_u.mtime.seconds * 1000000000ULL;
+
+ int rpcStatus;
+ SETATTR3res attrSetRes;
+ if (!setAttr(destPath, attributes, rpcStatus, attrSetRes)) {
+ qCDebug(LOG_KIO_NFS) << "Failed to restore mtime, ignoring..." << rpcStatus << attrSetRes.status;
+ }
+ }
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Copied" << writeArgs.offset << "bytes of data";
+
+ m_slave->processedSize(writeArgs.offset);
+ m_slave->finished();
+ }
+}
+
+void NFSProtocolV3::symlink(const QString& target, const QUrl& dest, KIO::JobFlags flags)
+{
+ const QString destPath(dest.path());
+
+ if (isExportedDir(QFileInfo(destPath).path())) {
+ m_slave->error(KIO::ERR_ACCESS_DENIED, destPath);
+ return;
+ }
+
+ if (!getFileHandle(destPath).isInvalid() && (flags & KIO::Overwrite) == 0) {
+ m_slave->error(KIO::ERR_FILE_ALREADY_EXIST, destPath);
+ return;
+ }
+
+
+ int rpcStatus;
+ SYMLINK3res res;
+ if (!symLink(target, destPath, rpcStatus, res)) {
+ checkForError(rpcStatus, res.status, destPath);
+ return;
+ }
+
+ m_slave->finished();
+}
+
+void NFSProtocolV3::initPreferredSizes(const NFSFileHandle& fh)
+{
+ FSINFO3args fsArgs;
+ memset(&fsArgs, 0, sizeof(fsArgs));
+ fh.toFH(fsArgs.fsroot);
+
+ FSINFO3res fsRes;
+ memset(&fsRes, 0, sizeof(fsRes));
+
+ int clnt_stat = clnt_call(m_nfsClient, NFSPROC3_FSINFO,
+ (xdrproc_t) xdr_FSINFO3args, reinterpret_cast<caddr_t>(&fsArgs),
+ (xdrproc_t) xdr_FSINFO3res, reinterpret_cast<caddr_t>(&fsRes),
+ clnt_timeout);
+
+ if (clnt_stat == RPC_SUCCESS && fsRes.status == NFS3_OK) {
+ m_writeBufferSize = fsRes.FSINFO3res_u.resok.wtpref;
+ m_readBufferSize = fsRes.FSINFO3res_u.resok.rtpref;
+ m_readDirSize = fsRes.FSINFO3res_u.resok.dtpref;
+ } else {
+ m_writeBufferSize = NFS3_MAXDATA;
+ m_readBufferSize = NFS3_MAXDATA;
+ m_readDirSize = NFS3_MAXDATA;
+ }
+
+ qCDebug(LOG_KIO_NFS) << "Preferred sizes - write" << m_writeBufferSize << ", read" << m_readBufferSize << ", read dir" << m_readDirSize;
+}
+
+
+bool NFSProtocolV3::create(const QString& path, int mode, int& rpcStatus, CREATE3res& result)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFS3ERR_ACCES;
+ return false;
+ }
+
+ const QFileInfo fileInfo(path);
+
+ const NFSFileHandle directoryFH = getFileHandle(fileInfo.path());
+ if (directoryFH.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+
+ CREATE3args args;
+ memset(&args, 0, sizeof(args));
+
+ directoryFH.toFH(args.where.dir);
+ args.where.name = tmpName.data();
+
+ args.how.createhow3_u.obj_attributes.mode.set_it = true;
+ args.how.createhow3_u.obj_attributes.uid.set_it = true;
+ args.how.createhow3_u.obj_attributes.gid.set_it = true;
+ args.how.createhow3_u.obj_attributes.size.set_it = true;
+
+ if (mode == -1) {
+ args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = 0644;
+ } else {
+ args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = mode;
+ }
+ args.how.createhow3_u.obj_attributes.uid.set_uid3_u.uid = geteuid();
+ args.how.createhow3_u.obj_attributes.gid.set_gid3_u.gid = getegid();
+ args.how.createhow3_u.obj_attributes.size.set_size3_u.size = 0;
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_CREATE,
+ (xdrproc_t) xdr_CREATE3args, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_CREATE3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+}
+
+bool NFSProtocolV3::getAttr(const QString& path, int& rpcStatus, GETATTR3res& result)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFS3ERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle fileFH = getFileHandle(path);
+ if (fileFH.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ GETATTR3args args;
+ memset(&args, 0, sizeof(GETATTR3args));
+ fileFH.toFH(args.object);
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_GETATTR,
+ (xdrproc_t) xdr_GETATTR3args, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_GETATTR3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+}
+
+bool NFSProtocolV3::lookupHandle(const QString& path, int& rpcStatus, LOOKUP3res& result)
+{
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFS3ERR_ACCES;
+ return false;
+ }
+
+ const QFileInfo fileInfo(path);
+
+ const NFSFileHandle parentFH = getFileHandle(fileInfo.path());
+ if (parentFH.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+
+ // do the rpc call
+ LOOKUP3args args;
+ memset(&args, 0, sizeof(args));
+ parentFH.toFH(args.what.dir);
+ args.what.name = tmpName.data();
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_LOOKUP,
+ (xdrproc_t) xdr_LOOKUP3args, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_LOOKUP3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+}
+
+bool NFSProtocolV3::readLink(const QString& path, int& rpcStatus, READLINK3res& result, char* dataBuffer)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ READLINK3args readLinkArgs;
+ memset(&readLinkArgs, 0, sizeof(readLinkArgs));
+ if (fh.isLink() && !fh.isBadLink()) {
+ fh.toFHLink(readLinkArgs.symlink);
+ } else {
+ fh.toFH(readLinkArgs.symlink);
+ }
+
+ result.READLINK3res_u.resok.data = dataBuffer;
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_READLINK,
+ (xdrproc_t) xdr_READLINK3args, reinterpret_cast<caddr_t>(&readLinkArgs),
+ (xdrproc_t) xdr_READLINK3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+}
+
+bool NFSProtocolV3::remove(const QString& path)
+{
+ int rpcStatus;
+ REMOVE3res result;
+
+ return remove(path, rpcStatus, result);
+}
+
+bool NFSProtocolV3::remove(const QString& path, int& rpcStatus, REMOVE3res& result)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ if (!isConnected()) {
+ result.status = NFS3ERR_PERM;
+ return false;
+ }
+
+ const QFileInfo fileInfo(path);
+ if (isExportedDir(fileInfo.path())) {
+ result.status = NFS3ERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle directoryFH = getFileHandle(fileInfo.path());
+ if (directoryFH.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ int rpcLookupStatus;
+ LOOKUP3res lookupRes;
+ if (!lookupHandle(path, rpcLookupStatus, lookupRes)) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpName = QFile::encodeName(fileInfo.fileName());
+
+ REMOVE3args args;
+ memset(&args, 0, sizeof(args));
+ directoryFH.toFH(args.object.dir);
+ args.object.name = tmpName.data();
+
+ if (lookupRes.LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes.type != NF3DIR) {
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_REMOVE,
+ (xdrproc_t) xdr_REMOVE3args, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_REMOVE3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+ } else {
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_RMDIR,
+ (xdrproc_t) xdr_RMDIR3args, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_RMDIR3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+ }
+
+ bool ret = (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+ if (ret) {
+ // Remove it from the cache as well
+ removeFileHandle(path);
+ }
+
+ return ret;
+}
+
+bool NFSProtocolV3::rename(const QString& src, const QString& dest)
+{
+ int rpcStatus;
+ RENAME3res result;
+
+ return rename(src, dest, rpcStatus, result);
+}
+
+bool NFSProtocolV3::rename(const QString& src, const QString& dest, int& rpcStatus, RENAME3res& result)
+{
+ qCDebug(LOG_KIO_NFS) << src << dest;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ const QFileInfo srcFileInfo(src);
+ if (isExportedDir(srcFileInfo.path())) {
+ result.status = NFS3ERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle srcDirectoryFH = getFileHandle(srcFileInfo.path());
+ if (srcDirectoryFH.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ const QFileInfo destFileInfo(dest);
+ if (isExportedDir(destFileInfo.path())) {
+ result.status = NFS3ERR_ACCES;
+ return false;
+ }
+
+ const NFSFileHandle destDirectoryFH = getFileHandle(destFileInfo.path());
+ if (destDirectoryFH.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ RENAME3args args;
+ memset(&args, 0, sizeof(args));
+
+ QByteArray srcByteName = QFile::encodeName(srcFileInfo.fileName());
+ srcDirectoryFH.toFH(args.fromfile.dir);
+ args.fromfile.name = srcByteName.data();
+
+ QByteArray destByteName = QFile::encodeName(destFileInfo.fileName());
+ destDirectoryFH.toFH(args.tofile.dir);
+ args.tofile.name = destByteName.data();
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_RENAME,
+ (xdrproc_t) xdr_RENAME3args, reinterpret_cast<caddr_t>(&args),
+ (xdrproc_t) xdr_RENAME3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ bool ret = (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+ if (ret) {
+ // Can we actually find the new handle?
+ int lookupStatus;
+ LOOKUP3res lookupRes;
+ if (lookupHandle(dest, lookupStatus, lookupRes)) {
+ // Remove the old file, and add the new one
+ removeFileHandle(src);
+ addFileHandle(dest, lookupRes.LOOKUP3res_u.resok.object);
+ }
+ }
+
+ return ret;
+}
+
+bool NFSProtocolV3::setAttr(const QString& path, const sattr3& attributes, int& rpcStatus, SETATTR3res& result)
+{
+ qCDebug(LOG_KIO_NFS) << path;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ const NFSFileHandle fh = getFileHandle(path);
+ if (fh.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ SETATTR3args setAttrArgs;
+ memset(&setAttrArgs, 0, sizeof(setAttrArgs));
+ fh.toFH(setAttrArgs.object);
+ memcpy(&setAttrArgs.new_attributes, &attributes, sizeof(attributes));
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_SETATTR,
+ (xdrproc_t) xdr_SETATTR3args, reinterpret_cast<caddr_t>(&setAttrArgs),
+ (xdrproc_t) xdr_SETATTR3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+}
+
+bool NFSProtocolV3::symLink(const QString& target, const QString& dest, int& rpcStatus, SYMLINK3res& result)
+{
+ qCDebug(LOG_KIO_NFS) << target << dest;
+
+ memset(&rpcStatus, 0, sizeof(int));
+ memset(&result, 0, sizeof(result));
+
+ // Remove dest first, we don't really care about the return value at this point,
+ // the symlink call will fail if dest was not removed correctly.
+ remove(dest);
+
+ const QFileInfo fileInfo(dest);
+
+ const NFSFileHandle fh = getFileHandle(fileInfo.path());
+ if (fh.isInvalid()) {
+ result.status = NFS3ERR_NOENT;
+ return false;
+ }
+
+ QByteArray tmpStr = QFile::encodeName(fileInfo.fileName());
+ QByteArray tmpStr2 = QFile::encodeName(target);
+
+ SYMLINK3args symLinkArgs;
+ memset(&symLinkArgs, 0, sizeof(symLinkArgs));
+
+ fh.toFH(symLinkArgs.where.dir);
+ symLinkArgs.where.name = tmpStr.data();
+ symLinkArgs.symlink.symlink_data = tmpStr2.data();
+
+ rpcStatus = clnt_call(m_nfsClient, NFSPROC3_SYMLINK,
+ (xdrproc_t) xdr_SYMLINK3args, reinterpret_cast<caddr_t>(&symLinkArgs),
+ (xdrproc_t) xdr_SYMLINK3res, reinterpret_cast<caddr_t>(&result),
+ clnt_timeout);
+
+ // Add the new handle to the cache
+ NFSFileHandle destFH = getFileHandle(dest);
+ if (!destFH.isInvalid()) {
+ addFileHandle(dest, destFH);
+ }
+
+ return (rpcStatus == RPC_SUCCESS && result.status == NFS3_OK);
+}
+
+
+void NFSProtocolV3::completeUDSEntry(KIO::UDSEntry& entry, const fattr3& attributes)
+{
+ entry.insert(KIO::UDSEntry::UDS_SIZE, attributes.size);
+ entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, attributes.mtime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS_TIME, attributes.atime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, attributes.ctime.seconds);
+
+ // Some servers still send the file type information in the mode, even though
+ // the reference specifies NFSv3 shouldn't, so we need to work around that here.
+ // Not sure this is the best way to do it, but it works.
+ if (attributes.mode > 0777) {
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, (attributes.mode & 07777));
+ } else {
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, attributes.mode);
+ }
+
+ unsigned int type;
+ switch (attributes.type) {
+ case NF3DIR:
+ type = S_IFDIR;
+ break;
+ case NF3BLK:
+ type = S_IFBLK;
+ break;
+ case NF3CHR:
+ type = S_IFCHR;
+ break;
+ case NF3LNK:
+ type = S_IFLNK;
+ break;
+ case NF3SOCK:
+ type = S_IFSOCK;
+ break;
+ case NF3FIFO:
+ type = S_IFIFO;
+ break;
+ default:
+ type = S_IFREG;
+ break;
+ }
+
+ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, type);
+
+ QString str;
+
+ const uid_t uid = attributes.uid;
+ if (!m_usercache.contains(uid)) {
+ struct passwd* user = getpwuid(uid);
+ if (user) {
+ m_usercache.insert(uid, QString::fromLatin1(user->pw_name));
+ str = user->pw_name;
+ } else {
+ str = QString::number(uid);
+ }
+ } else {
+ str = m_usercache.value(uid);
+ }
+
+ entry.insert(KIO::UDSEntry::UDS_USER, str);
+
+ const gid_t gid = attributes.gid;
+ if (!m_groupcache.contains(gid)) {
+ struct group* grp = getgrgid(gid);
+ if (grp) {
+ m_groupcache.insert(gid, QString::fromLatin1(grp->gr_name));
+ str = grp->gr_name;
+ } else {
+ str = QString::number(gid);
+ }
+ } else {
+ str = m_groupcache.value(gid);
+ }
+
+ entry.insert(KIO::UDSEntry::UDS_GROUP, str);
+}
+
+void NFSProtocolV3::completeBadLinkUDSEntry(KIO::UDSEntry& entry, const fattr3& attributes)
+{
+ entry.insert(KIO::UDSEntry::UDS_SIZE, 0LL);
+ entry.insert(KIO::UDSEntry::UDS_MODIFICATION_TIME, attributes.mtime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS_TIME, attributes.atime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_CREATION_TIME, attributes.ctime.seconds);
+ entry.insert(KIO::UDSEntry::UDS_FILE_TYPE, S_IFMT - 1);
+ entry.insert(KIO::UDSEntry::UDS_ACCESS, S_IRWXU | S_IRWXG | S_IRWXO);
+ entry.insert(KIO::UDSEntry::UDS_USER, attributes.uid);
+ entry.insert(KIO::UDSEntry::UDS_GROUP, attributes.gid);
+}
diff --git a/nfs/nfsv3.h b/nfs/nfsv3.h
new file mode 100644
index 0000000000000000000000000000000000000000..341dbd40b19ca2c6add67e4ff764e8f9a7e27c94
--- /dev/null
+++ b/nfs/nfsv3.h
@@ -0,0 +1,114 @@
+/* This file is part of the KDE project
+ Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org>,
+ 2014 Mathias Tillman <master.homer@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KIO_NFSV3_H
+#define KIO_NFSV3_H
+
+#include "kio_nfs.h"
+
+#define PORTMAP //this seems to be required to compile on Solaris
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+
+class NFSProtocolV3 : public NFSProtocol
+{
+public:
+ NFSProtocolV3(NFSSlave* slave);
+ ~NFSProtocolV3();
+
+ bool isCompatible(bool& connectionError) Q_DECL_OVERRIDE;
+ bool isConnected() const Q_DECL_OVERRIDE;
+
+ void openConnection() Q_DECL_OVERRIDE;
+ void closeConnection() Q_DECL_OVERRIDE;
+
+ void setHost(const QString& host) Q_DECL_OVERRIDE;
+
+ void put(const QUrl& url, int _mode, KIO::JobFlags _flags) Q_DECL_OVERRIDE;
+ void get(const QUrl& url) Q_DECL_OVERRIDE;
+ void listDir(const QUrl& url) Q_DECL_OVERRIDE;
+ void symlink(const QString& target, const QUrl& dest, KIO::JobFlags) Q_DECL_OVERRIDE;
+ void stat(const QUrl& url) Q_DECL_OVERRIDE;
+ void mkdir(const QUrl& url, int permissions) Q_DECL_OVERRIDE;
+ void del(const QUrl& url, bool isfile) Q_DECL_OVERRIDE;
+ void chmod(const QUrl& url, int permissions) Q_DECL_OVERRIDE;
+ void rename(const QUrl& src, const QUrl& dest, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+
+protected:
+ void copySame(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+ void copyFrom(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+ void copyTo(const QUrl& src, const QUrl& dest, int mode, KIO::JobFlags flags) Q_DECL_OVERRIDE;
+
+ // For servers that don't support the READDIRPLUS command.
+ void listDirCompat(const QUrl& url);
+
+ // Look up a file handle.
+ NFSFileHandle lookupFileHandle(const QString& path) Q_DECL_OVERRIDE;
+
+private:
+ bool create(const QString& path, int mode, int& rpcStatus, CREATE3res& result);
+
+ bool getAttr(const QString& path, int& rpcStatus, GETATTR3res& result);
+
+ bool lookupHandle(const QString& path, int& rpcStatus, LOOKUP3res& result);
+
+ bool readLink(const QString& path, int& rpcStatus, READLINK3res& result, char* dataBuffer);
+
+ // Calls @remove, but with dummy rpcStatus and result arguments
+ bool remove(const QString& path);
+ bool remove(const QString& path, int& rpcStatus, REMOVE3res& result);
+
+ // Calls @rename, but with dummy rpcStatus and result arguments
+ bool rename(const QString& src, const QString& dest);
+ bool rename(const QString& src, const QString& dest, int& rpcStatus, RENAME3res& result);
+
+ bool setAttr(const QString& path, const sattr3& attributes, int& rpcStatus, SETATTR3res& result);
+
+ bool symLink(const QString& target, const QString& dest, int& rpcStatus, SYMLINK3res& result);
+
+ // Initialises the optimal read, write and read dir buffer sizes
+ void initPreferredSizes(const NFSFileHandle& fh);
+
+ // UDS helper functions
+ void completeUDSEntry(KIO::UDSEntry& entry, const fattr3& attributes);
+ void completeBadLinkUDSEntry(KIO::UDSEntry& entry, const fattr3& attributes);
+
+ NFSSlave* m_slave;
+
+ QString m_currentHost;
+ CLIENT* m_mountClient;
+ int m_mountSock;
+ CLIENT* m_nfsClient;
+ int m_nfsSock;
+
+ timeval clnt_timeout;
+
+ QHash<long, QString> m_usercache;
+ QHash<long, QString> m_groupcache;
+
+ // The optimal read and write buffer sizes and read dir size, cached values
+ uint32 m_readBufferSize;
+ uint32 m_writeBufferSize;
+ uint32 m_readDirSize;
+};
+
+#endif
diff --git a/nfs/rpc_mnt2.h b/nfs/rpc_mnt2.h
new file mode 100644
index 0000000000000000000000000000000000000000..ed21256c4754ce861ff1f5ea5ddc4ca224a7da7e
--- /dev/null
+++ b/nfs/rpc_mnt2.h
@@ -0,0 +1,238 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _MNT2_H_RPCGEN
+#define _MNT2_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
+ */
+
+/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
+#ifndef _rpcsvc_mount_h
+#define _rpcsvc_mount_h
+#define MNTPATHLEN 1024
+#define MNTNAMLEN 255
+#define FHSIZE 32
+
+typedef char fhandle[FHSIZE];
+
+struct fhstatus {
+ u_int fhs_status;
+ union {
+ fhandle fhs_fhandle;
+ } fhstatus_u;
+};
+typedef struct fhstatus fhstatus;
+
+typedef char *dirpath;
+
+typedef char *name;
+
+typedef struct mountbody *mountlist;
+
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+typedef struct mountbody mountbody;
+
+typedef struct groupnode *groups;
+
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+typedef struct groupnode groupnode;
+
+typedef struct exportnode *exports;
+
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+typedef struct exportnode exportnode;
+
+struct ppathcnf {
+ int pc_link_max;
+ short pc_max_canon;
+ short pc_max_input;
+ short pc_name_max;
+ short pc_path_max;
+ short pc_pipe_buf;
+ u_char pc_vdisable;
+ char pc_xxx;
+ short pc_mask[2];
+};
+typedef struct ppathcnf ppathcnf;
+#endif /*!_rpcsvc_mount_h*/
+
+#define MOUNTPROG 100005
+#define MOUNTVERS 1
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC_NULL 0
+extern void * mountproc_null_1(void *, CLIENT *);
+extern void * mountproc_null_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_MNT 1
+extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *);
+extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_DUMP 2
+extern mountlist * mountproc_dump_1(void *, CLIENT *);
+extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_UMNT 3
+extern void * mountproc_umnt_1(dirpath *, CLIENT *);
+extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *);
+#define MOUNTPROC_UMNTALL 4
+extern void * mountproc_umntall_1(void *, CLIENT *);
+extern void * mountproc_umntall_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORT 5
+extern exports * mountproc_export_1(void *, CLIENT *);
+extern exports * mountproc_export_1_svc(void *, struct svc_req *);
+#define MOUNTPROC_EXPORTALL 6
+extern exports * mountproc_exportall_1(void *, CLIENT *);
+extern exports * mountproc_exportall_1_svc(void *, struct svc_req *);
+extern int mountprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define MOUNTPROC_NULL 0
+extern void * mountproc_null_1();
+extern void * mountproc_null_1_svc();
+#define MOUNTPROC_MNT 1
+extern fhstatus * mountproc_mnt_1();
+extern fhstatus * mountproc_mnt_1_svc();
+#define MOUNTPROC_DUMP 2
+extern mountlist * mountproc_dump_1();
+extern mountlist * mountproc_dump_1_svc();
+#define MOUNTPROC_UMNT 3
+extern void * mountproc_umnt_1();
+extern void * mountproc_umnt_1_svc();
+#define MOUNTPROC_UMNTALL 4
+extern void * mountproc_umntall_1();
+extern void * mountproc_umntall_1_svc();
+#define MOUNTPROC_EXPORT 5
+extern exports * mountproc_export_1();
+extern exports * mountproc_export_1_svc();
+#define MOUNTPROC_EXPORTALL 6
+extern exports * mountproc_exportall_1();
+extern exports * mountproc_exportall_1_svc();
+extern int mountprog_1_freeresult ();
+#endif /* K&R C */
+#define MOUNTVERS_POSIX 2
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern void * mountproc_null_2(void *, CLIENT *);
+extern void * mountproc_null_2_svc(void *, struct svc_req *);
+extern fhstatus * mountproc_mnt_2(dirpath *, CLIENT *);
+extern fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *);
+extern mountlist * mountproc_dump_2(void *, CLIENT *);
+extern mountlist * mountproc_dump_2_svc(void *, struct svc_req *);
+extern void * mountproc_umnt_2(dirpath *, CLIENT *);
+extern void * mountproc_umnt_2_svc(dirpath *, struct svc_req *);
+extern void * mountproc_umntall_2(void *, CLIENT *);
+extern void * mountproc_umntall_2_svc(void *, struct svc_req *);
+extern exports * mountproc_export_2(void *, CLIENT *);
+extern exports * mountproc_export_2_svc(void *, struct svc_req *);
+extern exports * mountproc_exportall_2(void *, CLIENT *);
+extern exports * mountproc_exportall_2_svc(void *, struct svc_req *);
+#define MOUNTPROC_PATHCONF 7
+extern ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *);
+extern ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *);
+extern int mountprog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+extern void * mountproc_null_2();
+extern void * mountproc_null_2_svc();
+extern fhstatus * mountproc_mnt_2();
+extern fhstatus * mountproc_mnt_2_svc();
+extern mountlist * mountproc_dump_2();
+extern mountlist * mountproc_dump_2_svc();
+extern void * mountproc_umnt_2();
+extern void * mountproc_umnt_2_svc();
+extern void * mountproc_umntall_2();
+extern void * mountproc_umntall_2_svc();
+extern exports * mountproc_export_2();
+extern exports * mountproc_export_2_svc();
+extern exports * mountproc_exportall_2();
+extern exports * mountproc_exportall_2_svc();
+#define MOUNTPROC_PATHCONF 7
+extern ppathcnf * mountproc_pathconf_2();
+extern ppathcnf * mountproc_pathconf_2_svc();
+extern int mountprog_2_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_fhandle (XDR *, fhandle);
+extern bool_t xdr_fhstatus (XDR *, fhstatus*);
+extern bool_t xdr_dirpath (XDR *, dirpath*);
+extern bool_t xdr_name (XDR *, name*);
+extern bool_t xdr_mountlist (XDR *, mountlist*);
+extern bool_t xdr_mountbody (XDR *, mountbody*);
+extern bool_t xdr_groups (XDR *, groups*);
+extern bool_t xdr_groupnode (XDR *, groupnode*);
+extern bool_t xdr_exports (XDR *, exports*);
+extern bool_t xdr_exportnode (XDR *, exportnode*);
+extern bool_t xdr_ppathcnf (XDR *, ppathcnf*);
+
+#else /* K&R C */
+extern bool_t xdr_fhandle ();
+extern bool_t xdr_fhstatus ();
+extern bool_t xdr_dirpath ();
+extern bool_t xdr_name ();
+extern bool_t xdr_mountlist ();
+extern bool_t xdr_mountbody ();
+extern bool_t xdr_groups ();
+extern bool_t xdr_groupnode ();
+extern bool_t xdr_exports ();
+extern bool_t xdr_exportnode ();
+extern bool_t xdr_ppathcnf ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_MNT2_H_RPCGEN */
diff --git a/nfs/rpc_mnt2.x b/nfs/rpc_mnt2.x
new file mode 100644
index 0000000000000000000000000000000000000000..4aaf97de9ade2655cd48ae460ba24ee322b57183
--- /dev/null
+++ b/nfs/rpc_mnt2.x
@@ -0,0 +1,255 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+%/*
+% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
+% */
+%
+%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
+
+/*
+ * Protocol description for the mount program
+ */
+
+#ifdef RPC_HDR
+%#ifndef _rpcsvc_mount_h
+%#define _rpcsvc_mount_h
+#endif
+
+const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */
+const MNTNAMLEN = 255; /* maximum bytes in a name argument */
+const FHSIZE = 32; /* size in bytes of a file handle */
+
+/*
+ * The fhandle is the file handle that the server passes to the client.
+ * All file operations are done using the file handles to refer to a file
+ * or a directory. The file handle can contain whatever information the
+ * server needs to distinguish an individual file.
+ */
+typedef opaque fhandle[FHSIZE];
+
+/*
+ * If a status of zero is returned, the call completed successfully, and
+ * a file handle for the directory follows. A non-zero status indicates
+ * some sort of error. The status corresponds with UNIX error numbers.
+ */
+union fhstatus switch (unsigned fhs_status) {
+case 0:
+ fhandle fhs_fhandle;
+default:
+ void;
+};
+
+/*
+ * The type dirpath is the pathname of a directory
+ */
+typedef string dirpath<MNTPATHLEN>;
+
+/*
+ * The type name is used for arbitrary names (hostnames, groupnames)
+ */
+typedef string name<MNTNAMLEN>;
+
+/*
+ * A list of who has what mounted
+ */
+typedef struct mountbody *mountlist;
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+
+/*
+ * A list of netgroups
+ */
+typedef struct groupnode *groups;
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+
+/*
+ * A list of what is exported and to whom
+ */
+typedef struct exportnode *exports;
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
+
+/*
+ * POSIX pathconf information
+ */
+struct ppathcnf {
+ int pc_link_max; /* max links allowed */
+ short pc_max_canon; /* max line len for a tty */
+ short pc_max_input; /* input a tty can eat all at once */
+ short pc_name_max; /* max file name length (dir entry) */
+ short pc_path_max; /* max path name length (/x/y/x/.. ) */
+ short pc_pipe_buf; /* size of a pipe (bytes) */
+ u_char pc_vdisable; /* safe char to turn off c_cc[i] */
+ char pc_xxx; /* alignment padding; cc_t == char */
+ short pc_mask[2]; /* validity and boolean bits */
+};
+
+program MOUNTPROG {
+ /*
+ * Version one of the mount protocol communicates with version two
+ * of the NFS protocol. The only connecting point is the fhandle
+ * structure, which is the same for both protocols.
+ */
+ version MOUNTVERS {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ /*
+ * If fhs_status is 0, then fhs_fhandle contains the
+ * file handle for the directory. This file handle may
+ * be used in the NFS protocol. This procedure also adds
+ * a new entry to the mount list for this client mounting
+ * the directory.
+ * Unix authentication required.
+ */
+ fhstatus
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC_EXPORT(void) = 5;
+
+ /*
+ * Identical to MOUNTPROC_EXPORT above
+ */
+ exports
+ MOUNTPROC_EXPORTALL(void) = 6;
+ } = 1;
+
+ /*
+ * Version two of the mount protocol communicates with version two
+ * of the NFS protocol.
+ * The only difference from version one is the addition of a POSIX
+ * pathconf call.
+ */
+ version MOUNTVERS_POSIX {
+ /*
+ * Does no work. It is made available in all RPC services
+ * to allow server reponse testing and timing
+ */
+ void
+ MOUNTPROC_NULL(void) = 0;
+
+ /*
+ * If fhs_status is 0, then fhs_fhandle contains the
+ * file handle for the directory. This file handle may
+ * be used in the NFS protocol. This procedure also adds
+ * a new entry to the mount list for this client mounting
+ * the directory.
+ * Unix authentication required.
+ */
+ fhstatus
+ MOUNTPROC_MNT(dirpath) = 1;
+
+ /*
+ * Returns the list of remotely mounted filesystems. The
+ * mountlist contains one entry for each hostname and
+ * directory pair.
+ */
+ mountlist
+ MOUNTPROC_DUMP(void) = 2;
+
+ /*
+ * Removes the mount list entry for the directory
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNT(dirpath) = 3;
+
+ /*
+ * Removes all of the mount list entries for this client
+ * Unix authentication required.
+ */
+ void
+ MOUNTPROC_UMNTALL(void) = 4;
+
+ /*
+ * Returns a list of all the exported filesystems, and which
+ * machines are allowed to import it.
+ */
+ exports
+ MOUNTPROC_EXPORT(void) = 5;
+
+ /*
+ * Identical to MOUNTPROC_EXPORT above
+ */
+ exports
+ MOUNTPROC_EXPORTALL(void) = 6;
+
+ /*
+ * POSIX pathconf info (Sun hack)
+ */
+ ppathcnf
+ MOUNTPROC_PATHCONF(dirpath) = 7;
+ } = 2;
+} = 100005;
+
+#ifdef RPC_HDR
+%#endif /*!_rpcsvc_mount_h*/
+#endif
diff --git a/nfs/rpc_mnt2_xdr.c b/nfs/rpc_mnt2_xdr.c
new file mode 100644
index 0000000000000000000000000000000000000000..b380f4f93853ba54112a68ddf851f8f04b251312
--- /dev/null
+++ b/nfs/rpc_mnt2_xdr.c
@@ -0,0 +1,277 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "rpc_mnt2.h"
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1985, 1990 by Sun Microsystems, Inc.
+ */
+
+/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */
+
+bool_t
+xdr_fhandle (XDR *xdrs, fhandle objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_opaque (xdrs, objp, FHSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fhstatus (XDR *xdrs, fhstatus *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_u_int (xdrs, &objp->fhs_status))
+ return FALSE;
+ switch (objp->fhs_status) {
+ case 0:
+ if (!xdr_fhandle (xdrs, objp->fhstatus_u.fhs_fhandle))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_dirpath (XDR *xdrs, dirpath *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, MNTPATHLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_name (XDR *xdrs, name *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, MNTNAMLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountlist (XDR *xdrs, mountlist *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody), (xdrproc_t) xdr_mountbody))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountbody (XDR *xdrs, mountbody *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_name (xdrs, &objp->ml_hostname))
+ return FALSE;
+ if (!xdr_dirpath (xdrs, &objp->ml_directory))
+ return FALSE;
+ if (!xdr_mountlist (xdrs, &objp->ml_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_groups (XDR *xdrs, groups *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode), (xdrproc_t) xdr_groupnode))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_groupnode (XDR *xdrs, groupnode *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_name (xdrs, &objp->gr_name))
+ return FALSE;
+ if (!xdr_groups (xdrs, &objp->gr_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_exports (XDR *xdrs, exports *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode), (xdrproc_t) xdr_exportnode))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_exportnode (XDR *xdrs, exportnode *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_dirpath (xdrs, &objp->ex_dir))
+ return FALSE;
+ if (!xdr_groups (xdrs, &objp->ex_groups))
+ return FALSE;
+ if (!xdr_exports (xdrs, &objp->ex_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ppathcnf (XDR *xdrs, ppathcnf *objp)
+{
+ register int32_t *buf;
+
+ int i;
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->pc_link_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_canon))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_input))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_name_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_path_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_pipe_buf))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_LONG(buf, objp->pc_link_max);
+ IXDR_PUT_SHORT(buf, objp->pc_max_canon);
+ IXDR_PUT_SHORT(buf, objp->pc_max_input);
+ IXDR_PUT_SHORT(buf, objp->pc_name_max);
+ IXDR_PUT_SHORT(buf, objp->pc_path_max);
+ IXDR_PUT_SHORT(buf, objp->pc_pipe_buf);
+ }
+ if (!xdr_u_char (xdrs, &objp->pc_vdisable))
+ return FALSE;
+ if (!xdr_char (xdrs, &objp->pc_xxx))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, ( 2 ) * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_vector (xdrs, (char *)objp->pc_mask, 2,
+ sizeof (short), (xdrproc_t) xdr_short))
+ return FALSE;
+ } else {
+ {
+ register short *genp;
+
+ for (i = 0, genp = objp->pc_mask;
+ i < 2; ++i) {
+ IXDR_PUT_SHORT(buf, *genp++);
+ }
+ }
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_int (xdrs, &objp->pc_link_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_canon))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_input))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_name_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_path_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_pipe_buf))
+ return FALSE;
+
+ } else {
+ objp->pc_link_max = IXDR_GET_LONG(buf);
+ objp->pc_max_canon = IXDR_GET_SHORT(buf);
+ objp->pc_max_input = IXDR_GET_SHORT(buf);
+ objp->pc_name_max = IXDR_GET_SHORT(buf);
+ objp->pc_path_max = IXDR_GET_SHORT(buf);
+ objp->pc_pipe_buf = IXDR_GET_SHORT(buf);
+ }
+ if (!xdr_u_char (xdrs, &objp->pc_vdisable))
+ return FALSE;
+ if (!xdr_char (xdrs, &objp->pc_xxx))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, ( 2 ) * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_vector (xdrs, (char *)objp->pc_mask, 2,
+ sizeof (short), (xdrproc_t) xdr_short))
+ return FALSE;
+ } else {
+ {
+ register short *genp;
+
+ for (i = 0, genp = objp->pc_mask;
+ i < 2; ++i) {
+ *genp++ = IXDR_GET_SHORT(buf);
+ }
+ }
+ }
+ return TRUE;
+ }
+
+ if (!xdr_int (xdrs, &objp->pc_link_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_canon))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_max_input))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_name_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_path_max))
+ return FALSE;
+ if (!xdr_short (xdrs, &objp->pc_pipe_buf))
+ return FALSE;
+ if (!xdr_u_char (xdrs, &objp->pc_vdisable))
+ return FALSE;
+ if (!xdr_char (xdrs, &objp->pc_xxx))
+ return FALSE;
+ if (!xdr_vector (xdrs, (char *)objp->pc_mask, 2,
+ sizeof (short), (xdrproc_t) xdr_short))
+ return FALSE;
+ return TRUE;
+}
diff --git a/nfs/rpc_mnt3.h b/nfs/rpc_mnt3.h
new file mode 100644
index 0000000000000000000000000000000000000000..cba4ff656a3d524f39cb7f607b8b4b331b41a0c5
--- /dev/null
+++ b/nfs/rpc_mnt3.h
@@ -0,0 +1,168 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _MNT3_H_RPCGEN
+#define _MNT3_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MNTPATHLEN 1024
+#define MNTNAMLEN 255
+#define FHSIZE3 64
+
+typedef struct {
+ u_int fhandle3_len;
+ char *fhandle3_val;
+} fhandle3;
+
+typedef char *dirpath3;
+
+typedef char *name3;
+
+enum mountstat3 {
+ MNT3_OK = 0,
+ MNT3ERR_PERM = 1,
+ MNT3ERR_NOENT = 2,
+ MNT3ERR_IO = 5,
+ MNT3ERR_ACCES = 13,
+ MNT3ERR_NOTDIR = 20,
+ MNT3ERR_INVAL = 22,
+ MNT3ERR_NAMETOOLONG = 63,
+ MNT3ERR_NOTSUPP = 10004,
+ MNT3ERR_SERVERFAULT = 10006,
+};
+typedef enum mountstat3 mountstat3;
+
+struct mountres3_ok {
+ fhandle3 fhandle;
+ struct {
+ u_int auth_flavors_len;
+ int *auth_flavors_val;
+ } auth_flavors;
+};
+typedef struct mountres3_ok mountres3_ok;
+
+struct mountres3 {
+ mountstat3 fhs_status;
+ union {
+ mountres3_ok mountinfo;
+ } mountres3_u;
+};
+typedef struct mountres3 mountres3;
+
+typedef struct mountbody3 *mountlist3;
+
+struct mountbody3 {
+ name3 ml_hostname;
+ dirpath3 ml_directory;
+ mountlist3 ml_next;
+};
+typedef struct mountbody3 mountbody3;
+
+typedef struct groupnode3 *groups3;
+
+struct groupnode3 {
+ name3 gr_name;
+ groups3 gr_next;
+};
+typedef struct groupnode3 groupnode3;
+
+typedef struct exportnode3 *exports3;
+
+struct exportnode3 {
+ dirpath3 ex_dir;
+ groups3 ex_groups;
+ exports3 ex_next;
+};
+typedef struct exportnode3 exportnode3;
+
+#define MOUNT_PROGRAM 100005
+#define MOUNT_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define MOUNTPROC3_NULL 0
+extern void * mountproc3_null_3(void *, CLIENT *);
+extern void * mountproc3_null_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_MNT 1
+extern mountres3 * mountproc3_mnt_3(dirpath3 *, CLIENT *);
+extern mountres3 * mountproc3_mnt_3_svc(dirpath3 *, struct svc_req *);
+#define MOUNTPROC3_DUMP 2
+extern mountlist3 * mountproc3_dump_3(void *, CLIENT *);
+extern mountlist3 * mountproc3_dump_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_UMNT 3
+extern void * mountproc3_umnt_3(dirpath3 *, CLIENT *);
+extern void * mountproc3_umnt_3_svc(dirpath3 *, struct svc_req *);
+#define MOUNTPROC3_UMNTALL 4
+extern void * mountproc3_umntall_3(void *, CLIENT *);
+extern void * mountproc3_umntall_3_svc(void *, struct svc_req *);
+#define MOUNTPROC3_EXPORT 5
+extern exports3 * mountproc3_export_3(void *, CLIENT *);
+extern exports3 * mountproc3_export_3_svc(void *, struct svc_req *);
+extern int mount_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define MOUNTPROC3_NULL 0
+extern void * mountproc3_null_3();
+extern void * mountproc3_null_3_svc();
+#define MOUNTPROC3_MNT 1
+extern mountres3 * mountproc3_mnt_3();
+extern mountres3 * mountproc3_mnt_3_svc();
+#define MOUNTPROC3_DUMP 2
+extern mountlist3 * mountproc3_dump_3();
+extern mountlist3 * mountproc3_dump_3_svc();
+#define MOUNTPROC3_UMNT 3
+extern void * mountproc3_umnt_3();
+extern void * mountproc3_umnt_3_svc();
+#define MOUNTPROC3_UMNTALL 4
+extern void * mountproc3_umntall_3();
+extern void * mountproc3_umntall_3_svc();
+#define MOUNTPROC3_EXPORT 5
+extern exports3 * mountproc3_export_3();
+extern exports3 * mountproc3_export_3_svc();
+extern int mount_program_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_fhandle3 (XDR *, fhandle3*);
+extern bool_t xdr_dirpath3 (XDR *, dirpath3*);
+extern bool_t xdr_name3 (XDR *, name3*);
+extern bool_t xdr_mountstat3 (XDR *, mountstat3*);
+extern bool_t xdr_mountres3_ok (XDR *, mountres3_ok*);
+extern bool_t xdr_mountres3 (XDR *, mountres3*);
+extern bool_t xdr_mountlist3 (XDR *, mountlist3*);
+extern bool_t xdr_mountbody3 (XDR *, mountbody3*);
+extern bool_t xdr_groups3 (XDR *, groups3*);
+extern bool_t xdr_groupnode3 (XDR *, groupnode3*);
+extern bool_t xdr_exports3 (XDR *, exports3*);
+extern bool_t xdr_exportnode3 (XDR *, exportnode3*);
+
+#else /* K&R C */
+extern bool_t xdr_fhandle3 ();
+extern bool_t xdr_dirpath3 ();
+extern bool_t xdr_name3 ();
+extern bool_t xdr_mountstat3 ();
+extern bool_t xdr_mountres3_ok ();
+extern bool_t xdr_mountres3 ();
+extern bool_t xdr_mountlist3 ();
+extern bool_t xdr_mountbody3 ();
+extern bool_t xdr_groups3 ();
+extern bool_t xdr_groupnode3 ();
+extern bool_t xdr_exports3 ();
+extern bool_t xdr_exportnode3 ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_MNT3_H_RPCGEN */
diff --git a/nfs/rpc_mnt3_xdr.c b/nfs/rpc_mnt3_xdr.c
new file mode 100644
index 0000000000000000000000000000000000000000..2016e688770e3753affe20923a8515f2427c5447
--- /dev/null
+++ b/nfs/rpc_mnt3_xdr.c
@@ -0,0 +1,147 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "rpc_mnt3.h"
+
+bool_t
+xdr_fhandle3 (XDR *xdrs, fhandle3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bytes (xdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirpath3 (XDR *xdrs, dirpath3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, MNTPATHLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_name3 (XDR *xdrs, name3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, MNTNAMLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountstat3 (XDR *xdrs, mountstat3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountres3_ok (XDR *xdrs, mountres3_ok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_fhandle3 (xdrs, &objp->fhandle))
+ return FALSE;
+ if (!xdr_array (xdrs, (char **)&objp->auth_flavors.auth_flavors_val, (u_int *) &objp->auth_flavors.auth_flavors_len, ~0,
+ sizeof (int), (xdrproc_t) xdr_int))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountres3 (XDR *xdrs, mountres3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_mountstat3 (xdrs, &objp->fhs_status))
+ return FALSE;
+ switch (objp->fhs_status) {
+ case MNT3_OK:
+ if (!xdr_mountres3_ok (xdrs, &objp->mountres3_u.mountinfo))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_mountlist3 (XDR *xdrs, mountlist3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct mountbody3), (xdrproc_t) xdr_mountbody3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mountbody3 (XDR *xdrs, mountbody3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_name3 (xdrs, &objp->ml_hostname))
+ return FALSE;
+ if (!xdr_dirpath3 (xdrs, &objp->ml_directory))
+ return FALSE;
+ if (!xdr_mountlist3 (xdrs, &objp->ml_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_groups3 (XDR *xdrs, groups3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct groupnode3), (xdrproc_t) xdr_groupnode3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_groupnode3 (XDR *xdrs, groupnode3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_name3 (xdrs, &objp->gr_name))
+ return FALSE;
+ if (!xdr_groups3 (xdrs, &objp->gr_next))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_exports3 (XDR *xdrs, exports3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)objp, sizeof (struct exportnode3), (xdrproc_t) xdr_exportnode3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_exportnode3 (XDR *xdrs, exportnode3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_dirpath3 (xdrs, &objp->ex_dir))
+ return FALSE;
+ if (!xdr_groups3 (xdrs, &objp->ex_groups))
+ return FALSE;
+ if (!xdr_exports3 (xdrs, &objp->ex_next))
+ return FALSE;
+ return TRUE;
+}
diff --git a/nfs/rpc_nfs2_prot.h b/nfs/rpc_nfs2_prot.h
new file mode 100644
index 0000000000000000000000000000000000000000..62ab3056a51cc0e89536081c9d5741ff136dc804
--- /dev/null
+++ b/nfs/rpc_nfs2_prot.h
@@ -0,0 +1,488 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NFS2_PROT_H_RPCGEN
+#define _NFS2_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1987, 1990 by Sun Microsystems, Inc.
+ */
+
+/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */
+#ifndef _rpcsvc_nfs_prot_h
+#define _rpcsvc_nfs_prot_h
+#define NFS_PORT 2049
+#define NFS_MAXDATA 8192
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_FHSIZE 32
+#define NFS_COOKIESIZE 4
+#define NFS_FIFO_DEV -1
+#define NFSMODE_FMT 0170000
+#define NFSMODE_DIR 0040000
+#define NFSMODE_CHR 0020000
+#define NFSMODE_BLK 0060000
+#define NFSMODE_REG 0100000
+#define NFSMODE_LNK 0120000
+#define NFSMODE_SOCK 0140000
+#define NFSMODE_FIFO 0010000
+
+enum nfsstat {
+ NFS_OK = 0,
+ NFSERR_PERM = 1,
+ NFSERR_NOENT = 2,
+ NFSERR_IO = 5,
+ NFSERR_NXIO = 6,
+ NFSERR_ACCES = 13,
+ NFSERR_EXIST = 17,
+ NFSERR_NODEV = 19,
+ NFSERR_NOTDIR = 20,
+ NFSERR_ISDIR = 21,
+ NFSERR_INVAL = 22,
+ NFSERR_FBIG = 27,
+ NFSERR_NOSPC = 28,
+ NFSERR_ROFS = 30,
+ NFSERR_NAMETOOLONG = 63,
+ NFSERR_NOTEMPTY = 66,
+ NFSERR_DQUOT = 69,
+ NFSERR_STALE = 70,
+ NFSERR_WFLUSH = 99,
+};
+typedef enum nfsstat nfsstat;
+
+enum ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5,
+ NFSOCK = 6,
+ NFBAD = 7,
+ NFFIFO = 8,
+};
+typedef enum ftype ftype;
+
+struct nfs_fh {
+ char data[NFS_FHSIZE];
+};
+typedef struct nfs_fh nfs_fh;
+
+struct nfstime {
+ u_int seconds;
+ u_int useconds;
+};
+typedef struct nfstime nfstime;
+
+struct fattr {
+ ftype type;
+ u_int mode;
+ u_int nlink;
+ u_int uid;
+ u_int gid;
+ u_int size;
+ u_int blocksize;
+ u_int rdev;
+ u_int blocks;
+ u_int fsid;
+ u_int fileid;
+ nfstime atime;
+ nfstime mtime;
+ nfstime ctime;
+};
+typedef struct fattr fattr;
+
+struct sattr {
+ u_int mode;
+ u_int uid;
+ u_int gid;
+ u_int size;
+ nfstime atime;
+ nfstime mtime;
+};
+typedef struct sattr sattr;
+
+typedef char *filename;
+
+typedef char *nfspath;
+
+struct attrstat {
+ nfsstat status;
+ union {
+ fattr attributes;
+ } attrstat_u;
+};
+typedef struct attrstat attrstat;
+
+struct sattrargs {
+ nfs_fh file;
+ sattr attributes;
+};
+typedef struct sattrargs sattrargs;
+
+struct diropargs {
+ nfs_fh dir;
+ filename name;
+};
+typedef struct diropargs diropargs;
+
+struct diropokres {
+ nfs_fh file;
+ fattr attributes;
+};
+typedef struct diropokres diropokres;
+
+struct diropres {
+ nfsstat status;
+ union {
+ diropokres diropres;
+ } diropres_u;
+};
+typedef struct diropres diropres;
+
+struct readlinkres {
+ nfsstat status;
+ union {
+ nfspath data;
+ } readlinkres_u;
+};
+typedef struct readlinkres readlinkres;
+
+struct readargs {
+ nfs_fh file;
+ u_int offset;
+ u_int count;
+ u_int totalcount;
+};
+typedef struct readargs readargs;
+
+struct readokres {
+ fattr attributes;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct readokres readokres;
+
+struct readres {
+ nfsstat status;
+ union {
+ readokres reply;
+ } readres_u;
+};
+typedef struct readres readres;
+
+struct writeargs {
+ nfs_fh file;
+ u_int beginoffset;
+ u_int offset;
+ u_int totalcount;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct writeargs writeargs;
+
+struct createargs {
+ diropargs where;
+ sattr attributes;
+};
+typedef struct createargs createargs;
+
+struct renameargs {
+ diropargs from;
+ diropargs to;
+};
+typedef struct renameargs renameargs;
+
+struct linkargs {
+ nfs_fh from;
+ diropargs to;
+};
+typedef struct linkargs linkargs;
+
+struct symlinkargs {
+ diropargs from;
+ nfspath to;
+ sattr attributes;
+};
+typedef struct symlinkargs symlinkargs;
+
+typedef char nfscookie[NFS_COOKIESIZE];
+
+struct readdirargs {
+ nfs_fh dir;
+ nfscookie cookie;
+ u_int count;
+};
+typedef struct readdirargs readdirargs;
+
+struct entry {
+ u_int fileid;
+ filename name;
+ nfscookie cookie;
+ struct entry *nextentry;
+};
+typedef struct entry entry;
+
+struct dirlist {
+ entry *entries;
+ bool_t eof;
+};
+typedef struct dirlist dirlist;
+
+struct readdirres {
+ nfsstat status;
+ union {
+ dirlist reply;
+ } readdirres_u;
+};
+typedef struct readdirres readdirres;
+
+struct statfsokres {
+ u_int tsize;
+ u_int bsize;
+ u_int blocks;
+ u_int bfree;
+ u_int bavail;
+};
+typedef struct statfsokres statfsokres;
+
+struct statfsres {
+ nfsstat status;
+ union {
+ statfsokres reply;
+ } statfsres_u;
+};
+typedef struct statfsres statfsres;
+#endif /*!_rpcsvc_nfs_prot_h*/
+
+#define NFS_PROGRAM 100003
+#define NFS_VERSION 2
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define NFSPROC_NULL 0
+extern void * nfsproc_null_2(void *, CLIENT *);
+extern void * nfsproc_null_2_svc(void *, struct svc_req *);
+#define NFSPROC_GETATTR 1
+extern attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *);
+extern attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *);
+#define NFSPROC_SETATTR 2
+extern attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *);
+extern attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *);
+#define NFSPROC_ROOT 3
+extern void * nfsproc_root_2(void *, CLIENT *);
+extern void * nfsproc_root_2_svc(void *, struct svc_req *);
+#define NFSPROC_LOOKUP 4
+extern diropres * nfsproc_lookup_2(diropargs *, CLIENT *);
+extern diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *);
+#define NFSPROC_READLINK 5
+extern readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *);
+extern readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *);
+#define NFSPROC_READ 6
+extern readres * nfsproc_read_2(readargs *, CLIENT *);
+extern readres * nfsproc_read_2_svc(readargs *, struct svc_req *);
+#define NFSPROC_WRITECACHE 7
+extern void * nfsproc_writecache_2(void *, CLIENT *);
+extern void * nfsproc_writecache_2_svc(void *, struct svc_req *);
+#define NFSPROC_WRITE 8
+extern attrstat * nfsproc_write_2(writeargs *, CLIENT *);
+extern attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *);
+#define NFSPROC_CREATE 9
+extern diropres * nfsproc_create_2(createargs *, CLIENT *);
+extern diropres * nfsproc_create_2_svc(createargs *, struct svc_req *);
+#define NFSPROC_REMOVE 10
+extern nfsstat * nfsproc_remove_2(diropargs *, CLIENT *);
+extern nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *);
+#define NFSPROC_RENAME 11
+extern nfsstat * nfsproc_rename_2(renameargs *, CLIENT *);
+extern nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *);
+#define NFSPROC_LINK 12
+extern nfsstat * nfsproc_link_2(linkargs *, CLIENT *);
+extern nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *);
+#define NFSPROC_SYMLINK 13
+extern nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *);
+extern nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *);
+#define NFSPROC_MKDIR 14
+extern diropres * nfsproc_mkdir_2(createargs *, CLIENT *);
+extern diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *);
+#define NFSPROC_RMDIR 15
+extern nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *);
+extern nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *);
+#define NFSPROC_READDIR 16
+extern readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *);
+extern readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *);
+#define NFSPROC_STATFS 17
+extern statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *);
+extern statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *);
+extern int nfs_program_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define NFSPROC_NULL 0
+extern void * nfsproc_null_2();
+extern void * nfsproc_null_2_svc();
+#define NFSPROC_GETATTR 1
+extern attrstat * nfsproc_getattr_2();
+extern attrstat * nfsproc_getattr_2_svc();
+#define NFSPROC_SETATTR 2
+extern attrstat * nfsproc_setattr_2();
+extern attrstat * nfsproc_setattr_2_svc();
+#define NFSPROC_ROOT 3
+extern void * nfsproc_root_2();
+extern void * nfsproc_root_2_svc();
+#define NFSPROC_LOOKUP 4
+extern diropres * nfsproc_lookup_2();
+extern diropres * nfsproc_lookup_2_svc();
+#define NFSPROC_READLINK 5
+extern readlinkres * nfsproc_readlink_2();
+extern readlinkres * nfsproc_readlink_2_svc();
+#define NFSPROC_READ 6
+extern readres * nfsproc_read_2();
+extern readres * nfsproc_read_2_svc();
+#define NFSPROC_WRITECACHE 7
+extern void * nfsproc_writecache_2();
+extern void * nfsproc_writecache_2_svc();
+#define NFSPROC_WRITE 8
+extern attrstat * nfsproc_write_2();
+extern attrstat * nfsproc_write_2_svc();
+#define NFSPROC_CREATE 9
+extern diropres * nfsproc_create_2();
+extern diropres * nfsproc_create_2_svc();
+#define NFSPROC_REMOVE 10
+extern nfsstat * nfsproc_remove_2();
+extern nfsstat * nfsproc_remove_2_svc();
+#define NFSPROC_RENAME 11
+extern nfsstat * nfsproc_rename_2();
+extern nfsstat * nfsproc_rename_2_svc();
+#define NFSPROC_LINK 12
+extern nfsstat * nfsproc_link_2();
+extern nfsstat * nfsproc_link_2_svc();
+#define NFSPROC_SYMLINK 13
+extern nfsstat * nfsproc_symlink_2();
+extern nfsstat * nfsproc_symlink_2_svc();
+#define NFSPROC_MKDIR 14
+extern diropres * nfsproc_mkdir_2();
+extern diropres * nfsproc_mkdir_2_svc();
+#define NFSPROC_RMDIR 15
+extern nfsstat * nfsproc_rmdir_2();
+extern nfsstat * nfsproc_rmdir_2_svc();
+#define NFSPROC_READDIR 16
+extern readdirres * nfsproc_readdir_2();
+extern readdirres * nfsproc_readdir_2_svc();
+#define NFSPROC_STATFS 17
+extern statfsres * nfsproc_statfs_2();
+extern statfsres * nfsproc_statfs_2_svc();
+extern int nfs_program_2_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_nfsstat (XDR *, nfsstat*);
+extern bool_t xdr_ftype (XDR *, ftype*);
+extern bool_t xdr_nfs_fh (XDR *, nfs_fh*);
+extern bool_t xdr_nfstime (XDR *, nfstime*);
+extern bool_t xdr_fattr (XDR *, fattr*);
+extern bool_t xdr_sattr (XDR *, sattr*);
+extern bool_t xdr_filename (XDR *, filename*);
+extern bool_t xdr_nfspath (XDR *, nfspath*);
+extern bool_t xdr_attrstat (XDR *, attrstat*);
+extern bool_t xdr_sattrargs (XDR *, sattrargs*);
+extern bool_t xdr_diropargs (XDR *, diropargs*);
+extern bool_t xdr_diropokres (XDR *, diropokres*);
+extern bool_t xdr_diropres (XDR *, diropres*);
+extern bool_t xdr_readlinkres (XDR *, readlinkres*);
+extern bool_t xdr_readargs (XDR *, readargs*);
+extern bool_t xdr_readokres (XDR *, readokres*);
+extern bool_t xdr_readres (XDR *, readres*);
+extern bool_t xdr_writeargs (XDR *, writeargs*);
+extern bool_t xdr_createargs (XDR *, createargs*);
+extern bool_t xdr_renameargs (XDR *, renameargs*);
+extern bool_t xdr_linkargs (XDR *, linkargs*);
+extern bool_t xdr_symlinkargs (XDR *, symlinkargs*);
+extern bool_t xdr_nfscookie (XDR *, nfscookie);
+extern bool_t xdr_readdirargs (XDR *, readdirargs*);
+extern bool_t xdr_entry (XDR *, entry*);
+extern bool_t xdr_dirlist (XDR *, dirlist*);
+extern bool_t xdr_readdirres (XDR *, readdirres*);
+extern bool_t xdr_statfsokres (XDR *, statfsokres*);
+extern bool_t xdr_statfsres (XDR *, statfsres*);
+
+#else /* K&R C */
+extern bool_t xdr_nfsstat ();
+extern bool_t xdr_ftype ();
+extern bool_t xdr_nfs_fh ();
+extern bool_t xdr_nfstime ();
+extern bool_t xdr_fattr ();
+extern bool_t xdr_sattr ();
+extern bool_t xdr_filename ();
+extern bool_t xdr_nfspath ();
+extern bool_t xdr_attrstat ();
+extern bool_t xdr_sattrargs ();
+extern bool_t xdr_diropargs ();
+extern bool_t xdr_diropokres ();
+extern bool_t xdr_diropres ();
+extern bool_t xdr_readlinkres ();
+extern bool_t xdr_readargs ();
+extern bool_t xdr_readokres ();
+extern bool_t xdr_readres ();
+extern bool_t xdr_writeargs ();
+extern bool_t xdr_createargs ();
+extern bool_t xdr_renameargs ();
+extern bool_t xdr_linkargs ();
+extern bool_t xdr_symlinkargs ();
+extern bool_t xdr_nfscookie ();
+extern bool_t xdr_readdirargs ();
+extern bool_t xdr_entry ();
+extern bool_t xdr_dirlist ();
+extern bool_t xdr_readdirres ();
+extern bool_t xdr_statfsokres ();
+extern bool_t xdr_statfsres ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NFS2_PROT_H_RPCGEN */
diff --git a/nfs/rpc_nfs2_prot.x b/nfs/rpc_nfs2_prot.x
new file mode 100644
index 0000000000000000000000000000000000000000..cd21123c7b57040d97245f22038153945abe88ee
--- /dev/null
+++ b/nfs/rpc_nfs2_prot.x
@@ -0,0 +1,365 @@
+%/*
+% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+% * unrestricted use provided that this legend is included on all tape
+% * media and as a part of the software program in whole or part. Users
+% * may copy or modify Sun RPC without charge, but are not authorized
+% * to license or distribute it to anyone else except as part of a product or
+% * program developed by the user or with the express written consent of
+% * Sun Microsystems, Inc.
+% *
+% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+% *
+% * Sun RPC is provided with no support and without any obligation on the
+% * part of Sun Microsystems, Inc. to assist in its use, correction,
+% * modification or enhancement.
+% *
+% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+% * OR ANY PART THEREOF.
+% *
+% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+% * or profits or other special, indirect and consequential damages, even if
+% * Sun has been advised of the possibility of such damages.
+% *
+% * Sun Microsystems, Inc.
+% * 2550 Garcia Avenue
+% * Mountain View, California 94043
+% */
+
+%/*
+% * Copyright (c) 1987, 1990 by Sun Microsystems, Inc.
+% */
+%
+%/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */
+
+#ifdef RPC_HDR
+%#ifndef _rpcsvc_nfs_prot_h
+%#define _rpcsvc_nfs_prot_h
+#endif
+
+const NFS_PORT = 2049;
+const NFS_MAXDATA = 8192;
+const NFS_MAXPATHLEN = 1024;
+const NFS_MAXNAMLEN = 255;
+const NFS_FHSIZE = 32;
+const NFS_COOKIESIZE = 4;
+const NFS_FIFO_DEV = -1; /* size kludge for named pipes */
+
+/*
+ * File types
+ */
+const NFSMODE_FMT = 0170000; /* type of file */
+const NFSMODE_DIR = 0040000; /* directory */
+const NFSMODE_CHR = 0020000; /* character special */
+const NFSMODE_BLK = 0060000; /* block special */
+const NFSMODE_REG = 0100000; /* regular */
+const NFSMODE_LNK = 0120000; /* symbolic link */
+const NFSMODE_SOCK = 0140000; /* socket */
+const NFSMODE_FIFO = 0010000; /* fifo */
+
+/*
+ * Error status
+ */
+enum nfsstat {
+ NFS_OK= 0, /* no error */
+ NFSERR_PERM=1, /* Not owner */
+ NFSERR_NOENT=2, /* No such file or directory */
+ NFSERR_IO=5, /* I/O error */
+ NFSERR_NXIO=6, /* No such device or address */
+ NFSERR_ACCES=13, /* Permission denied */
+ NFSERR_EXIST=17, /* File exists */
+ NFSERR_NODEV=19, /* No such device */
+ NFSERR_NOTDIR=20, /* Not a directory*/
+ NFSERR_ISDIR=21, /* Is a directory */
+ NFSERR_INVAL=22, /* invalid argument */
+ NFSERR_FBIG=27, /* File too large */
+ NFSERR_NOSPC=28, /* No space left on device */
+ NFSERR_ROFS=30, /* Read-only file system */
+ NFSERR_NAMETOOLONG=63, /* File name too long */
+ NFSERR_NOTEMPTY=66, /* Directory not empty */
+ NFSERR_DQUOT=69, /* Disc quota exceeded */
+ NFSERR_STALE=70, /* Stale NFS file handle */
+ NFSERR_WFLUSH=99 /* write cache flushed */
+};
+
+/*
+ * File types
+ */
+enum ftype {
+ NFNON = 0, /* non-file */
+ NFREG = 1, /* regular file */
+ NFDIR = 2, /* directory */
+ NFBLK = 3, /* block special */
+ NFCHR = 4, /* character special */
+ NFLNK = 5, /* symbolic link */
+ NFSOCK = 6, /* unix domain sockets */
+ NFBAD = 7, /* unused */
+ NFFIFO = 8 /* named pipe */
+};
+
+/*
+ * File access handle
+ */
+struct nfs_fh {
+ opaque data[NFS_FHSIZE];
+};
+
+/*
+ * Timeval
+ */
+struct nfstime {
+ unsigned seconds;
+ unsigned useconds;
+};
+
+
+/*
+ * File attributes
+ */
+struct fattr {
+ ftype type; /* file type */
+ unsigned mode; /* protection mode bits */
+ unsigned nlink; /* # hard links */
+ unsigned uid; /* owner user id */
+ unsigned gid; /* owner group id */
+ unsigned size; /* file size in bytes */
+ unsigned blocksize; /* prefered block size */
+ unsigned rdev; /* special device # */
+ unsigned blocks; /* Kb of disk used by file */
+ unsigned fsid; /* device # */
+ unsigned fileid; /* inode # */
+ nfstime atime; /* time of last access */
+ nfstime mtime; /* time of last modification */
+ nfstime ctime; /* time of last change */
+};
+
+/*
+ * File attributes which can be set
+ */
+struct sattr {
+ unsigned mode; /* protection mode bits */
+ unsigned uid; /* owner user id */
+ unsigned gid; /* owner group id */
+ unsigned size; /* file size in bytes */
+ nfstime atime; /* time of last access */
+ nfstime mtime; /* time of last modification */
+};
+
+
+typedef string filename<NFS_MAXNAMLEN>;
+typedef string nfspath<NFS_MAXPATHLEN>;
+
+/*
+ * Reply status with file attributes
+ */
+union attrstat switch (nfsstat status) {
+case NFS_OK:
+ fattr attributes;
+default:
+ void;
+};
+
+struct sattrargs {
+ nfs_fh file;
+ sattr attributes;
+};
+
+/*
+ * Arguments for directory operations
+ */
+struct diropargs {
+ nfs_fh dir; /* directory file handle */
+ filename name; /* name (up to NFS_MAXNAMLEN bytes) */
+};
+
+struct diropokres {
+ nfs_fh file;
+ fattr attributes;
+};
+
+/*
+ * Results from directory operation
+ */
+union diropres switch (nfsstat status) {
+case NFS_OK:
+ diropokres diropres;
+default:
+ void;
+};
+
+union readlinkres switch (nfsstat status) {
+case NFS_OK:
+ nfspath data;
+default:
+ void;
+};
+
+/*
+ * Arguments to remote read
+ */
+struct readargs {
+ nfs_fh file; /* handle for file */
+ unsigned offset; /* byte offset in file */
+ unsigned count; /* immediate read count */
+ unsigned totalcount; /* total read count (from this offset)*/
+};
+
+/*
+ * Status OK portion of remote read reply
+ */
+struct readokres {
+ fattr attributes; /* attributes, need for pagin*/
+ opaque data<NFS_MAXDATA>;
+};
+
+union readres switch (nfsstat status) {
+case NFS_OK:
+ readokres reply;
+default:
+ void;
+};
+
+/*
+ * Arguments to remote write
+ */
+struct writeargs {
+ nfs_fh file; /* handle for file */
+ unsigned beginoffset; /* beginning byte offset in file */
+ unsigned offset; /* current byte offset in file */
+ unsigned totalcount; /* total write count (to this offset)*/
+ opaque data<NFS_MAXDATA>;
+};
+
+struct createargs {
+ diropargs where;
+ sattr attributes;
+};
+
+struct renameargs {
+ diropargs from;
+ diropargs to;
+};
+
+struct linkargs {
+ nfs_fh from;
+ diropargs to;
+};
+
+struct symlinkargs {
+ diropargs from;
+ nfspath to;
+ sattr attributes;
+};
+
+
+typedef opaque nfscookie[NFS_COOKIESIZE];
+
+/*
+ * Arguments to readdir
+ */
+struct readdirargs {
+ nfs_fh dir; /* directory handle */
+ nfscookie cookie;
+ unsigned count; /* number of directory bytes to read */
+};
+
+struct entry {
+ unsigned fileid;
+ filename name;
+ nfscookie cookie;
+ entry *nextentry;
+};
+
+struct dirlist {
+ entry *entries;
+ bool eof;
+};
+
+union readdirres switch (nfsstat status) {
+case NFS_OK:
+ dirlist reply;
+default:
+ void;
+};
+
+struct statfsokres {
+ unsigned tsize; /* preferred transfer size in bytes */
+ unsigned bsize; /* fundamental file system block size */
+ unsigned blocks; /* total blocks in file system */
+ unsigned bfree; /* free blocks in fs */
+ unsigned bavail; /* free blocks avail to non-superuser */
+};
+
+union statfsres switch (nfsstat status) {
+case NFS_OK:
+ statfsokres reply;
+default:
+ void;
+};
+
+/*
+ * Remote file service routines
+ */
+program NFS_PROGRAM {
+ version NFS_VERSION {
+ void
+ NFSPROC_NULL(void) = 0;
+
+ attrstat
+ NFSPROC_GETATTR(nfs_fh) = 1;
+
+ attrstat
+ NFSPROC_SETATTR(sattrargs) = 2;
+
+ void
+ NFSPROC_ROOT(void) = 3;
+
+ diropres
+ NFSPROC_LOOKUP(diropargs) = 4;
+
+ readlinkres
+ NFSPROC_READLINK(nfs_fh) = 5;
+
+ readres
+ NFSPROC_READ(readargs) = 6;
+
+ void
+ NFSPROC_WRITECACHE(void) = 7;
+
+ attrstat
+ NFSPROC_WRITE(writeargs) = 8;
+
+ diropres
+ NFSPROC_CREATE(createargs) = 9;
+
+ nfsstat
+ NFSPROC_REMOVE(diropargs) = 10;
+
+ nfsstat
+ NFSPROC_RENAME(renameargs) = 11;
+
+ nfsstat
+ NFSPROC_LINK(linkargs) = 12;
+
+ nfsstat
+ NFSPROC_SYMLINK(symlinkargs) = 13;
+
+ diropres
+ NFSPROC_MKDIR(createargs) = 14;
+
+ nfsstat
+ NFSPROC_RMDIR(diropargs) = 15;
+
+ readdirres
+ NFSPROC_READDIR(readdirargs) = 16;
+
+ statfsres
+ NFSPROC_STATFS(nfs_fh) = 17;
+ } = 2;
+} = 100003;
+
+#ifdef RPC_HDR
+%#endif /*!_rpcsvc_nfs_prot_h*/
+#endif
diff --git a/nfs/rpc_nfs2_prot_xdr.c b/nfs/rpc_nfs2_prot_xdr.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb63b8ec2329730ef55c8f068e8abf47e865173b
--- /dev/null
+++ b/nfs/rpc_nfs2_prot_xdr.c
@@ -0,0 +1,699 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "rpc_nfs2_prot.h"
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ */
+/*
+ * Copyright (c) 1987, 1990 by Sun Microsystems, Inc.
+ */
+
+/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */
+
+bool_t
+xdr_nfsstat (XDR *xdrs, nfsstat *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ftype (XDR *xdrs, ftype *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfs_fh (XDR *xdrs, nfs_fh *objp)
+{
+ register int32_t *buf;
+
+ int i;
+ if (!xdr_opaque (xdrs, objp->data, NFS_FHSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfstime (XDR *xdrs, nfstime *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_u_int (xdrs, &objp->seconds))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->useconds))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fattr (XDR *xdrs, fattr *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_ftype (xdrs, &objp->type))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 10 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocksize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->fileid))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->mode);
+ IXDR_PUT_U_LONG(buf, objp->nlink);
+ IXDR_PUT_U_LONG(buf, objp->uid);
+ IXDR_PUT_U_LONG(buf, objp->gid);
+ IXDR_PUT_U_LONG(buf, objp->size);
+ IXDR_PUT_U_LONG(buf, objp->blocksize);
+ IXDR_PUT_U_LONG(buf, objp->rdev);
+ IXDR_PUT_U_LONG(buf, objp->blocks);
+ IXDR_PUT_U_LONG(buf, objp->fsid);
+ IXDR_PUT_U_LONG(buf, objp->fileid);
+ }
+ if (!xdr_nfstime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_ftype (xdrs, &objp->type))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 10 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocksize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->fileid))
+ return FALSE;
+
+ } else {
+ objp->mode = IXDR_GET_U_LONG(buf);
+ objp->nlink = IXDR_GET_U_LONG(buf);
+ objp->uid = IXDR_GET_U_LONG(buf);
+ objp->gid = IXDR_GET_U_LONG(buf);
+ objp->size = IXDR_GET_U_LONG(buf);
+ objp->blocksize = IXDR_GET_U_LONG(buf);
+ objp->rdev = IXDR_GET_U_LONG(buf);
+ objp->blocks = IXDR_GET_U_LONG(buf);
+ objp->fsid = IXDR_GET_U_LONG(buf);
+ objp->fileid = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_nfstime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_ftype (xdrs, &objp->type))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocksize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_sattr (XDR *xdrs, sattr *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->size))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->mode);
+ IXDR_PUT_U_LONG(buf, objp->uid);
+ IXDR_PUT_U_LONG(buf, objp->gid);
+ IXDR_PUT_U_LONG(buf, objp->size);
+ }
+ if (!xdr_nfstime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->size))
+ return FALSE;
+
+ } else {
+ objp->mode = IXDR_GET_U_LONG(buf);
+ objp->uid = IXDR_GET_U_LONG(buf);
+ objp->gid = IXDR_GET_U_LONG(buf);
+ objp->size = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_nfstime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_u_int (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime (xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_filename (XDR *xdrs, filename *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, NFS_MAXNAMLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfspath (XDR *xdrs, nfspath *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, NFS_MAXPATHLEN))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_attrstat (XDR *xdrs, attrstat *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS_OK:
+ if (!xdr_fattr (xdrs, &objp->attrstat_u.attributes))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_sattrargs (XDR *xdrs, sattrargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_sattr (xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_diropargs (XDR *xdrs, diropargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_filename (xdrs, &objp->name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_diropokres (XDR *xdrs, diropokres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_fattr (xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_diropres (XDR *xdrs, diropres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS_OK:
+ if (!xdr_diropokres (xdrs, &objp->diropres_u.diropres))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_readlinkres (XDR *xdrs, readlinkres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS_OK:
+ if (!xdr_nfspath (xdrs, &objp->readlinkres_u.data))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_readargs (XDR *xdrs, readargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->totalcount))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readokres (XDR *xdrs, readokres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_fattr (xdrs, &objp->attributes))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readres (XDR *xdrs, readres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS_OK:
+ if (!xdr_readokres (xdrs, &objp->readres_u.reply))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_writeargs (XDR *xdrs, writeargs *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_nfs_fh (xdrs, &objp->file))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->beginoffset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->totalcount))
+ return FALSE;
+
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->beginoffset);
+ IXDR_PUT_U_LONG(buf, objp->offset);
+ IXDR_PUT_U_LONG(buf, objp->totalcount);
+ }
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
+ return FALSE;
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_nfs_fh (xdrs, &objp->file))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 3 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->beginoffset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->totalcount))
+ return FALSE;
+
+ } else {
+ objp->beginoffset = IXDR_GET_U_LONG(buf);
+ objp->offset = IXDR_GET_U_LONG(buf);
+ objp->totalcount = IXDR_GET_U_LONG(buf);
+ }
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
+ return FALSE;
+ return TRUE;
+ }
+
+ if (!xdr_nfs_fh (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->beginoffset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->totalcount))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS_MAXDATA))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_createargs (XDR *xdrs, createargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_sattr (xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_renameargs (XDR *xdrs, renameargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs (xdrs, &objp->from))
+ return FALSE;
+ if (!xdr_diropargs (xdrs, &objp->to))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_linkargs (XDR *xdrs, linkargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh (xdrs, &objp->from))
+ return FALSE;
+ if (!xdr_diropargs (xdrs, &objp->to))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_symlinkargs (XDR *xdrs, symlinkargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs (xdrs, &objp->from))
+ return FALSE;
+ if (!xdr_nfspath (xdrs, &objp->to))
+ return FALSE;
+ if (!xdr_sattr (xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfscookie (XDR *xdrs, nfscookie objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_opaque (xdrs, objp, NFS_COOKIESIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdirargs (XDR *xdrs, readdirargs *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_nfscookie (xdrs, objp->cookie))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entry (XDR *xdrs, entry *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_u_int (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_filename (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_nfscookie (xdrs, objp->cookie))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entry), (xdrproc_t) xdr_entry))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirlist (XDR *xdrs, dirlist *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entry), (xdrproc_t) xdr_entry))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_readdirres (XDR *xdrs, readdirres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS_OK:
+ if (!xdr_dirlist (xdrs, &objp->readdirres_u.reply))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_statfsokres (XDR *xdrs, statfsokres *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->tsize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bsize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bfree))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bavail))
+ return FALSE;
+ } else {
+ IXDR_PUT_U_LONG(buf, objp->tsize);
+ IXDR_PUT_U_LONG(buf, objp->bsize);
+ IXDR_PUT_U_LONG(buf, objp->blocks);
+ IXDR_PUT_U_LONG(buf, objp->bfree);
+ IXDR_PUT_U_LONG(buf, objp->bavail);
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ buf = XDR_INLINE (xdrs, 5 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_u_int (xdrs, &objp->tsize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bsize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bfree))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bavail))
+ return FALSE;
+ } else {
+ objp->tsize = IXDR_GET_U_LONG(buf);
+ objp->bsize = IXDR_GET_U_LONG(buf);
+ objp->blocks = IXDR_GET_U_LONG(buf);
+ objp->bfree = IXDR_GET_U_LONG(buf);
+ objp->bavail = IXDR_GET_U_LONG(buf);
+ }
+ return TRUE;
+ }
+
+ if (!xdr_u_int (xdrs, &objp->tsize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bsize))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->blocks))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bfree))
+ return FALSE;
+ if (!xdr_u_int (xdrs, &objp->bavail))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_statfsres (XDR *xdrs, statfsres *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS_OK:
+ if (!xdr_statfsokres (xdrs, &objp->statfsres_u.reply))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
diff --git a/nfs/rpc_nfs3_prot.h b/nfs/rpc_nfs3_prot.h
new file mode 100644
index 0000000000000000000000000000000000000000..76b2f5becef9cbdc9fd3db08c540c065a43a89a6
--- /dev/null
+++ b/nfs/rpc_nfs3_prot.h
@@ -0,0 +1,1330 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#ifndef _NFS3_PROT_H_RPCGEN
+#define _NFS3_PROT_H_RPCGEN
+
+#include <rpc/rpc.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NFS3_FHSIZE 64
+#define NFS3_COOKIEVERFSIZE 8
+#define NFS3_CREATEVERFSIZE 8
+#define NFS3_WRITEVERFSIZE 8
+
+typedef u_quad_t uint64;
+
+typedef quad_t int64;
+
+typedef u_int uint32;
+
+typedef int int32;
+
+typedef char *filename3;
+
+typedef char *nfspath3;
+
+typedef uint64 fileid3;
+
+typedef uint64 cookie3;
+
+typedef char cookieverf3[NFS3_COOKIEVERFSIZE];
+
+typedef char createverf3[NFS3_CREATEVERFSIZE];
+
+typedef char writeverf3[NFS3_WRITEVERFSIZE];
+
+typedef uint32 uid3;
+
+typedef uint32 gid3;
+
+typedef uint64 size3;
+
+typedef uint64 offset3;
+
+typedef uint32 mode3;
+
+typedef uint32 count3;
+
+enum nfsstat3 {
+ NFS3_OK = 0,
+ NFS3ERR_PERM = 1,
+ NFS3ERR_NOENT = 2,
+ NFS3ERR_IO = 5,
+ NFS3ERR_NXIO = 6,
+ NFS3ERR_ACCES = 13,
+ NFS3ERR_EXIST = 17,
+ NFS3ERR_XDEV = 18,
+ NFS3ERR_NODEV = 19,
+ NFS3ERR_NOTDIR = 20,
+ NFS3ERR_ISDIR = 21,
+ NFS3ERR_INVAL = 22,
+ NFS3ERR_FBIG = 27,
+ NFS3ERR_NOSPC = 28,
+ NFS3ERR_ROFS = 30,
+ NFS3ERR_MLINK = 31,
+ NFS3ERR_NAMETOOLONG = 63,
+ NFS3ERR_NOTEMPTY = 66,
+ NFS3ERR_DQUOT = 69,
+ NFS3ERR_STALE = 70,
+ NFS3ERR_REMOTE = 71,
+ NFS3ERR_BADHANDLE = 10001,
+ NFS3ERR_NOT_SYNC = 10002,
+ NFS3ERR_BAD_COOKIE = 10003,
+ NFS3ERR_NOTSUPP = 10004,
+ NFS3ERR_TOOSMALL = 10005,
+ NFS3ERR_SERVERFAULT = 10006,
+ NFS3ERR_BADTYPE = 10007,
+ NFS3ERR_JUKEBOX = 10008,
+};
+typedef enum nfsstat3 nfsstat3;
+
+enum ftype3 {
+ NF3REG = 1,
+ NF3DIR = 2,
+ NF3BLK = 3,
+ NF3CHR = 4,
+ NF3LNK = 5,
+ NF3SOCK = 6,
+ NF3FIFO = 7,
+};
+typedef enum ftype3 ftype3;
+
+struct specdata3 {
+ uint32 specdata1;
+ uint32 specdata2;
+};
+typedef struct specdata3 specdata3;
+
+struct nfs_fh3 {
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct nfs_fh3 nfs_fh3;
+
+struct nfstime3 {
+ uint32 seconds;
+ uint32 nseconds;
+};
+typedef struct nfstime3 nfstime3;
+
+struct fattr3 {
+ ftype3 type;
+ mode3 mode;
+ uint32 nlink;
+ uid3 uid;
+ gid3 gid;
+ size3 size;
+ size3 used;
+ specdata3 rdev;
+ uint64 fsid;
+ fileid3 fileid;
+ nfstime3 atime;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+typedef struct fattr3 fattr3;
+
+struct post_op_attr {
+ bool_t attributes_follow;
+ union {
+ fattr3 attributes;
+ } post_op_attr_u;
+};
+typedef struct post_op_attr post_op_attr;
+
+struct wcc_attr {
+ size3 size;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+typedef struct wcc_attr wcc_attr;
+
+struct pre_op_attr {
+ bool_t attributes_follow;
+ union {
+ wcc_attr attributes;
+ } pre_op_attr_u;
+};
+typedef struct pre_op_attr pre_op_attr;
+
+struct wcc_data {
+ pre_op_attr before;
+ post_op_attr after;
+};
+typedef struct wcc_data wcc_data;
+
+struct post_op_fh3 {
+ bool_t handle_follows;
+ union {
+ nfs_fh3 handle;
+ } post_op_fh3_u;
+};
+typedef struct post_op_fh3 post_op_fh3;
+
+enum time_how {
+ DONT_CHANGE = 0,
+ SET_TO_SERVER_TIME = 1,
+ SET_TO_CLIENT_TIME = 2,
+};
+typedef enum time_how time_how;
+
+struct set_mode3 {
+ bool_t set_it;
+ union {
+ mode3 mode;
+ } set_mode3_u;
+};
+typedef struct set_mode3 set_mode3;
+
+struct set_uid3 {
+ bool_t set_it;
+ union {
+ uid3 uid;
+ } set_uid3_u;
+};
+typedef struct set_uid3 set_uid3;
+
+struct set_gid3 {
+ bool_t set_it;
+ union {
+ gid3 gid;
+ } set_gid3_u;
+};
+typedef struct set_gid3 set_gid3;
+
+struct set_size3 {
+ bool_t set_it;
+ union {
+ size3 size;
+ } set_size3_u;
+};
+typedef struct set_size3 set_size3;
+
+struct set_atime {
+ time_how set_it;
+ union {
+ nfstime3 atime;
+ } set_atime_u;
+};
+typedef struct set_atime set_atime;
+
+struct set_mtime {
+ time_how set_it;
+ union {
+ nfstime3 mtime;
+ } set_mtime_u;
+};
+typedef struct set_mtime set_mtime;
+
+struct sattr3 {
+ set_mode3 mode;
+ set_uid3 uid;
+ set_gid3 gid;
+ set_size3 size;
+ set_atime atime;
+ set_mtime mtime;
+};
+typedef struct sattr3 sattr3;
+
+struct diropargs3 {
+ nfs_fh3 dir;
+ filename3 name;
+};
+typedef struct diropargs3 diropargs3;
+
+struct GETATTR3args {
+ nfs_fh3 object;
+};
+typedef struct GETATTR3args GETATTR3args;
+
+struct GETATTR3resok {
+ fattr3 obj_attributes;
+};
+typedef struct GETATTR3resok GETATTR3resok;
+
+struct GETATTR3res {
+ nfsstat3 status;
+ union {
+ GETATTR3resok resok;
+ } GETATTR3res_u;
+};
+typedef struct GETATTR3res GETATTR3res;
+
+struct sattrguard3 {
+ bool_t check;
+ union {
+ nfstime3 obj_ctime;
+ } sattrguard3_u;
+};
+typedef struct sattrguard3 sattrguard3;
+
+struct SETATTR3args {
+ nfs_fh3 object;
+ sattr3 new_attributes;
+ sattrguard3 guard;
+};
+typedef struct SETATTR3args SETATTR3args;
+
+struct SETATTR3resok {
+ wcc_data obj_wcc;
+};
+typedef struct SETATTR3resok SETATTR3resok;
+
+struct SETATTR3resfail {
+ wcc_data obj_wcc;
+};
+typedef struct SETATTR3resfail SETATTR3resfail;
+
+struct SETATTR3res {
+ nfsstat3 status;
+ union {
+ SETATTR3resok resok;
+ SETATTR3resfail resfail;
+ } SETATTR3res_u;
+};
+typedef struct SETATTR3res SETATTR3res;
+
+struct LOOKUP3args {
+ diropargs3 what;
+};
+typedef struct LOOKUP3args LOOKUP3args;
+
+struct LOOKUP3resok {
+ nfs_fh3 object;
+ post_op_attr obj_attributes;
+ post_op_attr dir_attributes;
+};
+typedef struct LOOKUP3resok LOOKUP3resok;
+
+struct LOOKUP3resfail {
+ post_op_attr dir_attributes;
+};
+typedef struct LOOKUP3resfail LOOKUP3resfail;
+
+struct LOOKUP3res {
+ nfsstat3 status;
+ union {
+ LOOKUP3resok resok;
+ LOOKUP3resfail resfail;
+ } LOOKUP3res_u;
+};
+typedef struct LOOKUP3res LOOKUP3res;
+#define ACCESS3_READ 0x0001
+#define ACCESS3_LOOKUP 0x0002
+#define ACCESS3_MODIFY 0x0004
+#define ACCESS3_EXTEND 0x0008
+#define ACCESS3_DELETE 0x0010
+#define ACCESS3_EXECUTE 0x0020
+
+struct ACCESS3args {
+ nfs_fh3 object;
+ uint32 access;
+};
+typedef struct ACCESS3args ACCESS3args;
+
+struct ACCESS3resok {
+ post_op_attr obj_attributes;
+ uint32 access;
+};
+typedef struct ACCESS3resok ACCESS3resok;
+
+struct ACCESS3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct ACCESS3resfail ACCESS3resfail;
+
+struct ACCESS3res {
+ nfsstat3 status;
+ union {
+ ACCESS3resok resok;
+ ACCESS3resfail resfail;
+ } ACCESS3res_u;
+};
+typedef struct ACCESS3res ACCESS3res;
+
+struct READLINK3args {
+ nfs_fh3 symlink;
+};
+typedef struct READLINK3args READLINK3args;
+
+struct READLINK3resok {
+ post_op_attr symlink_attributes;
+ nfspath3 data;
+};
+typedef struct READLINK3resok READLINK3resok;
+
+struct READLINK3resfail {
+ post_op_attr symlink_attributes;
+};
+typedef struct READLINK3resfail READLINK3resfail;
+
+struct READLINK3res {
+ nfsstat3 status;
+ union {
+ READLINK3resok resok;
+ READLINK3resfail resfail;
+ } READLINK3res_u;
+};
+typedef struct READLINK3res READLINK3res;
+
+struct READ3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+typedef struct READ3args READ3args;
+
+struct READ3resok {
+ post_op_attr file_attributes;
+ count3 count;
+ bool_t eof;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct READ3resok READ3resok;
+
+struct READ3resfail {
+ post_op_attr file_attributes;
+};
+typedef struct READ3resfail READ3resfail;
+
+struct READ3res {
+ nfsstat3 status;
+ union {
+ READ3resok resok;
+ READ3resfail resfail;
+ } READ3res_u;
+};
+typedef struct READ3res READ3res;
+
+enum stable_how {
+ UNSTABLE = 0,
+ DATA_SYNC = 1,
+ FILE_SYNC = 2,
+};
+typedef enum stable_how stable_how;
+
+struct WRITE3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+ stable_how stable;
+ struct {
+ u_int data_len;
+ char *data_val;
+ } data;
+};
+typedef struct WRITE3args WRITE3args;
+
+struct WRITE3resok {
+ wcc_data file_wcc;
+ count3 count;
+ stable_how committed;
+ writeverf3 verf;
+};
+typedef struct WRITE3resok WRITE3resok;
+
+struct WRITE3resfail {
+ wcc_data file_wcc;
+};
+typedef struct WRITE3resfail WRITE3resfail;
+
+struct WRITE3res {
+ nfsstat3 status;
+ union {
+ WRITE3resok resok;
+ WRITE3resfail resfail;
+ } WRITE3res_u;
+};
+typedef struct WRITE3res WRITE3res;
+
+enum createmode3 {
+ UNCHECKED = 0,
+ GUARDED = 1,
+ EXCLUSIVE = 2,
+};
+typedef enum createmode3 createmode3;
+
+struct createhow3 {
+ createmode3 mode;
+ union {
+ sattr3 obj_attributes;
+ createverf3 verf;
+ } createhow3_u;
+};
+typedef struct createhow3 createhow3;
+
+struct CREATE3args {
+ diropargs3 where;
+ createhow3 how;
+};
+typedef struct CREATE3args CREATE3args;
+
+struct CREATE3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct CREATE3resok CREATE3resok;
+
+struct CREATE3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct CREATE3resfail CREATE3resfail;
+
+struct CREATE3res {
+ nfsstat3 status;
+ union {
+ CREATE3resok resok;
+ CREATE3resfail resfail;
+ } CREATE3res_u;
+};
+typedef struct CREATE3res CREATE3res;
+
+struct MKDIR3args {
+ diropargs3 where;
+ sattr3 attributes;
+};
+typedef struct MKDIR3args MKDIR3args;
+
+struct MKDIR3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct MKDIR3resok MKDIR3resok;
+
+struct MKDIR3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct MKDIR3resfail MKDIR3resfail;
+
+struct MKDIR3res {
+ nfsstat3 status;
+ union {
+ MKDIR3resok resok;
+ MKDIR3resfail resfail;
+ } MKDIR3res_u;
+};
+typedef struct MKDIR3res MKDIR3res;
+
+struct symlinkdata3 {
+ sattr3 symlink_attributes;
+ nfspath3 symlink_data;
+};
+typedef struct symlinkdata3 symlinkdata3;
+
+struct SYMLINK3args {
+ diropargs3 where;
+ symlinkdata3 symlink;
+};
+typedef struct SYMLINK3args SYMLINK3args;
+
+struct SYMLINK3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct SYMLINK3resok SYMLINK3resok;
+
+struct SYMLINK3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct SYMLINK3resfail SYMLINK3resfail;
+
+struct SYMLINK3res {
+ nfsstat3 status;
+ union {
+ SYMLINK3resok resok;
+ SYMLINK3resfail resfail;
+ } SYMLINK3res_u;
+};
+typedef struct SYMLINK3res SYMLINK3res;
+
+struct devicedata3 {
+ sattr3 dev_attributes;
+ specdata3 spec;
+};
+typedef struct devicedata3 devicedata3;
+
+struct mknoddata3 {
+ ftype3 type;
+ union {
+ devicedata3 device;
+ sattr3 pipe_attributes;
+ } mknoddata3_u;
+};
+typedef struct mknoddata3 mknoddata3;
+
+struct MKNOD3args {
+ diropargs3 where;
+ mknoddata3 what;
+};
+typedef struct MKNOD3args MKNOD3args;
+
+struct MKNOD3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+typedef struct MKNOD3resok MKNOD3resok;
+
+struct MKNOD3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct MKNOD3resfail MKNOD3resfail;
+
+struct MKNOD3res {
+ nfsstat3 status;
+ union {
+ MKNOD3resok resok;
+ MKNOD3resfail resfail;
+ } MKNOD3res_u;
+};
+typedef struct MKNOD3res MKNOD3res;
+
+struct REMOVE3args {
+ diropargs3 object;
+};
+typedef struct REMOVE3args REMOVE3args;
+
+struct REMOVE3resok {
+ wcc_data dir_wcc;
+};
+typedef struct REMOVE3resok REMOVE3resok;
+
+struct REMOVE3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct REMOVE3resfail REMOVE3resfail;
+
+struct REMOVE3res {
+ nfsstat3 status;
+ union {
+ REMOVE3resok resok;
+ REMOVE3resfail resfail;
+ } REMOVE3res_u;
+};
+typedef struct REMOVE3res REMOVE3res;
+
+struct RMDIR3args {
+ diropargs3 object;
+};
+typedef struct RMDIR3args RMDIR3args;
+
+struct RMDIR3resok {
+ wcc_data dir_wcc;
+};
+typedef struct RMDIR3resok RMDIR3resok;
+
+struct RMDIR3resfail {
+ wcc_data dir_wcc;
+};
+typedef struct RMDIR3resfail RMDIR3resfail;
+
+struct RMDIR3res {
+ nfsstat3 status;
+ union {
+ RMDIR3resok resok;
+ RMDIR3resfail resfail;
+ } RMDIR3res_u;
+};
+typedef struct RMDIR3res RMDIR3res;
+
+struct RENAME3args {
+ diropargs3 fromfile;
+ diropargs3 tofile;
+};
+typedef struct RENAME3args RENAME3args;
+
+struct RENAME3resok {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+typedef struct RENAME3resok RENAME3resok;
+
+struct RENAME3resfail {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+typedef struct RENAME3resfail RENAME3resfail;
+
+struct RENAME3res {
+ nfsstat3 status;
+ union {
+ RENAME3resok resok;
+ RENAME3resfail resfail;
+ } RENAME3res_u;
+};
+typedef struct RENAME3res RENAME3res;
+
+struct LINK3args {
+ nfs_fh3 file;
+ diropargs3 link;
+};
+typedef struct LINK3args LINK3args;
+
+struct LINK3resok {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+typedef struct LINK3resok LINK3resok;
+
+struct LINK3resfail {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+typedef struct LINK3resfail LINK3resfail;
+
+struct LINK3res {
+ nfsstat3 status;
+ union {
+ LINK3resok resok;
+ LINK3resfail resfail;
+ } LINK3res_u;
+};
+typedef struct LINK3res LINK3res;
+
+struct READDIR3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 count;
+};
+typedef struct READDIR3args READDIR3args;
+
+struct entry3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ struct entry3 *nextentry;
+};
+typedef struct entry3 entry3;
+
+struct dirlist3 {
+ entry3 *entries;
+ bool_t eof;
+};
+typedef struct dirlist3 dirlist3;
+
+struct READDIR3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlist3 reply;
+};
+typedef struct READDIR3resok READDIR3resok;
+
+struct READDIR3resfail {
+ post_op_attr dir_attributes;
+};
+typedef struct READDIR3resfail READDIR3resfail;
+
+struct READDIR3res {
+ nfsstat3 status;
+ union {
+ READDIR3resok resok;
+ READDIR3resfail resfail;
+ } READDIR3res_u;
+};
+typedef struct READDIR3res READDIR3res;
+
+struct READDIRPLUS3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 dircount;
+ count3 maxcount;
+};
+typedef struct READDIRPLUS3args READDIRPLUS3args;
+
+struct entryplus3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ post_op_attr name_attributes;
+ post_op_fh3 name_handle;
+ struct entryplus3 *nextentry;
+};
+typedef struct entryplus3 entryplus3;
+
+struct dirlistplus3 {
+ entryplus3 *entries;
+ bool_t eof;
+};
+typedef struct dirlistplus3 dirlistplus3;
+
+struct READDIRPLUS3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlistplus3 reply;
+};
+typedef struct READDIRPLUS3resok READDIRPLUS3resok;
+
+struct READDIRPLUS3resfail {
+ post_op_attr dir_attributes;
+};
+typedef struct READDIRPLUS3resfail READDIRPLUS3resfail;
+
+struct READDIRPLUS3res {
+ nfsstat3 status;
+ union {
+ READDIRPLUS3resok resok;
+ READDIRPLUS3resfail resfail;
+ } READDIRPLUS3res_u;
+};
+typedef struct READDIRPLUS3res READDIRPLUS3res;
+
+struct FSSTAT3args {
+ nfs_fh3 fsroot;
+};
+typedef struct FSSTAT3args FSSTAT3args;
+
+struct FSSTAT3resok {
+ post_op_attr obj_attributes;
+ size3 tbytes;
+ size3 fbytes;
+ size3 abytes;
+ size3 tfiles;
+ size3 ffiles;
+ size3 afiles;
+ uint32 invarsec;
+};
+typedef struct FSSTAT3resok FSSTAT3resok;
+
+struct FSSTAT3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct FSSTAT3resfail FSSTAT3resfail;
+
+struct FSSTAT3res {
+ nfsstat3 status;
+ union {
+ FSSTAT3resok resok;
+ FSSTAT3resfail resfail;
+ } FSSTAT3res_u;
+};
+typedef struct FSSTAT3res FSSTAT3res;
+#define FSF3_LINK 0x0001
+#define FSF3_SYMLINK 0x0002
+#define FSF3_HOMOGENEOUS 0x0008
+#define FSF3_CANSETTIME 0x0010
+
+struct FSINFO3args {
+ nfs_fh3 fsroot;
+};
+typedef struct FSINFO3args FSINFO3args;
+
+struct FSINFO3resok {
+ post_op_attr obj_attributes;
+ uint32 rtmax;
+ uint32 rtpref;
+ uint32 rtmult;
+ uint32 wtmax;
+ uint32 wtpref;
+ uint32 wtmult;
+ uint32 dtpref;
+ size3 maxfilesize;
+ nfstime3 time_delta;
+ uint32 properties;
+};
+typedef struct FSINFO3resok FSINFO3resok;
+
+struct FSINFO3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct FSINFO3resfail FSINFO3resfail;
+
+struct FSINFO3res {
+ nfsstat3 status;
+ union {
+ FSINFO3resok resok;
+ FSINFO3resfail resfail;
+ } FSINFO3res_u;
+};
+typedef struct FSINFO3res FSINFO3res;
+
+struct PATHCONF3args {
+ nfs_fh3 object;
+};
+typedef struct PATHCONF3args PATHCONF3args;
+
+struct PATHCONF3resok {
+ post_op_attr obj_attributes;
+ uint32 linkmax;
+ uint32 name_max;
+ bool_t no_trunc;
+ bool_t chown_restricted;
+ bool_t case_insensitive;
+ bool_t case_preserving;
+};
+typedef struct PATHCONF3resok PATHCONF3resok;
+
+struct PATHCONF3resfail {
+ post_op_attr obj_attributes;
+};
+typedef struct PATHCONF3resfail PATHCONF3resfail;
+
+struct PATHCONF3res {
+ nfsstat3 status;
+ union {
+ PATHCONF3resok resok;
+ PATHCONF3resfail resfail;
+ } PATHCONF3res_u;
+};
+typedef struct PATHCONF3res PATHCONF3res;
+
+struct COMMIT3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+typedef struct COMMIT3args COMMIT3args;
+
+struct COMMIT3resok {
+ wcc_data file_wcc;
+ writeverf3 verf;
+};
+typedef struct COMMIT3resok COMMIT3resok;
+
+struct COMMIT3resfail {
+ wcc_data file_wcc;
+};
+typedef struct COMMIT3resfail COMMIT3resfail;
+
+struct COMMIT3res {
+ nfsstat3 status;
+ union {
+ COMMIT3resok resok;
+ COMMIT3resfail resfail;
+ } COMMIT3res_u;
+};
+typedef struct COMMIT3res COMMIT3res;
+
+#define NFS_PROGRAM 100003
+#define NFS_V3 3
+
+#if defined(__STDC__) || defined(__cplusplus)
+#define NFSPROC3_NULL 0
+extern void * nfsproc3_null_3(void *, CLIENT *);
+extern void * nfsproc3_null_3_svc(void *, struct svc_req *);
+#define NFSPROC3_GETATTR 1
+extern GETATTR3res * nfsproc3_getattr_3(GETATTR3args *, CLIENT *);
+extern GETATTR3res * nfsproc3_getattr_3_svc(GETATTR3args *, struct svc_req *);
+#define NFSPROC3_SETATTR 2
+extern SETATTR3res * nfsproc3_setattr_3(SETATTR3args *, CLIENT *);
+extern SETATTR3res * nfsproc3_setattr_3_svc(SETATTR3args *, struct svc_req *);
+#define NFSPROC3_LOOKUP 3
+extern LOOKUP3res * nfsproc3_lookup_3(LOOKUP3args *, CLIENT *);
+extern LOOKUP3res * nfsproc3_lookup_3_svc(LOOKUP3args *, struct svc_req *);
+#define NFSPROC3_ACCESS 4
+extern ACCESS3res * nfsproc3_access_3(ACCESS3args *, CLIENT *);
+extern ACCESS3res * nfsproc3_access_3_svc(ACCESS3args *, struct svc_req *);
+#define NFSPROC3_READLINK 5
+extern READLINK3res * nfsproc3_readlink_3(READLINK3args *, CLIENT *);
+extern READLINK3res * nfsproc3_readlink_3_svc(READLINK3args *, struct svc_req *);
+#define NFSPROC3_READ 6
+extern READ3res * nfsproc3_read_3(READ3args *, CLIENT *);
+extern READ3res * nfsproc3_read_3_svc(READ3args *, struct svc_req *);
+#define NFSPROC3_WRITE 7
+extern WRITE3res * nfsproc3_write_3(WRITE3args *, CLIENT *);
+extern WRITE3res * nfsproc3_write_3_svc(WRITE3args *, struct svc_req *);
+#define NFSPROC3_CREATE 8
+extern CREATE3res * nfsproc3_create_3(CREATE3args *, CLIENT *);
+extern CREATE3res * nfsproc3_create_3_svc(CREATE3args *, struct svc_req *);
+#define NFSPROC3_MKDIR 9
+extern MKDIR3res * nfsproc3_mkdir_3(MKDIR3args *, CLIENT *);
+extern MKDIR3res * nfsproc3_mkdir_3_svc(MKDIR3args *, struct svc_req *);
+#define NFSPROC3_SYMLINK 10
+extern SYMLINK3res * nfsproc3_symlink_3(SYMLINK3args *, CLIENT *);
+extern SYMLINK3res * nfsproc3_symlink_3_svc(SYMLINK3args *, struct svc_req *);
+#define NFSPROC3_MKNOD 11
+extern MKNOD3res * nfsproc3_mknod_3(MKNOD3args *, CLIENT *);
+extern MKNOD3res * nfsproc3_mknod_3_svc(MKNOD3args *, struct svc_req *);
+#define NFSPROC3_REMOVE 12
+extern REMOVE3res * nfsproc3_remove_3(REMOVE3args *, CLIENT *);
+extern REMOVE3res * nfsproc3_remove_3_svc(REMOVE3args *, struct svc_req *);
+#define NFSPROC3_RMDIR 13
+extern RMDIR3res * nfsproc3_rmdir_3(RMDIR3args *, CLIENT *);
+extern RMDIR3res * nfsproc3_rmdir_3_svc(RMDIR3args *, struct svc_req *);
+#define NFSPROC3_RENAME 14
+extern RENAME3res * nfsproc3_rename_3(RENAME3args *, CLIENT *);
+extern RENAME3res * nfsproc3_rename_3_svc(RENAME3args *, struct svc_req *);
+#define NFSPROC3_LINK 15
+extern LINK3res * nfsproc3_link_3(LINK3args *, CLIENT *);
+extern LINK3res * nfsproc3_link_3_svc(LINK3args *, struct svc_req *);
+#define NFSPROC3_READDIR 16
+extern READDIR3res * nfsproc3_readdir_3(READDIR3args *, CLIENT *);
+extern READDIR3res * nfsproc3_readdir_3_svc(READDIR3args *, struct svc_req *);
+#define NFSPROC3_READDIRPLUS 17
+extern READDIRPLUS3res * nfsproc3_readdirplus_3(READDIRPLUS3args *, CLIENT *);
+extern READDIRPLUS3res * nfsproc3_readdirplus_3_svc(READDIRPLUS3args *, struct svc_req *);
+#define NFSPROC3_FSSTAT 18
+extern FSSTAT3res * nfsproc3_fsstat_3(FSSTAT3args *, CLIENT *);
+extern FSSTAT3res * nfsproc3_fsstat_3_svc(FSSTAT3args *, struct svc_req *);
+#define NFSPROC3_FSINFO 19
+extern FSINFO3res * nfsproc3_fsinfo_3(FSINFO3args *, CLIENT *);
+extern FSINFO3res * nfsproc3_fsinfo_3_svc(FSINFO3args *, struct svc_req *);
+#define NFSPROC3_PATHCONF 20
+extern PATHCONF3res * nfsproc3_pathconf_3(PATHCONF3args *, CLIENT *);
+extern PATHCONF3res * nfsproc3_pathconf_3_svc(PATHCONF3args *, struct svc_req *);
+#define NFSPROC3_COMMIT 21
+extern COMMIT3res * nfsproc3_commit_3(COMMIT3args *, CLIENT *);
+extern COMMIT3res * nfsproc3_commit_3_svc(COMMIT3args *, struct svc_req *);
+extern int nfs_program_3_freeresult (SVCXPRT *, xdrproc_t, caddr_t);
+
+#else /* K&R C */
+#define NFSPROC3_NULL 0
+extern void * nfsproc3_null_3();
+extern void * nfsproc3_null_3_svc();
+#define NFSPROC3_GETATTR 1
+extern GETATTR3res * nfsproc3_getattr_3();
+extern GETATTR3res * nfsproc3_getattr_3_svc();
+#define NFSPROC3_SETATTR 2
+extern SETATTR3res * nfsproc3_setattr_3();
+extern SETATTR3res * nfsproc3_setattr_3_svc();
+#define NFSPROC3_LOOKUP 3
+extern LOOKUP3res * nfsproc3_lookup_3();
+extern LOOKUP3res * nfsproc3_lookup_3_svc();
+#define NFSPROC3_ACCESS 4
+extern ACCESS3res * nfsproc3_access_3();
+extern ACCESS3res * nfsproc3_access_3_svc();
+#define NFSPROC3_READLINK 5
+extern READLINK3res * nfsproc3_readlink_3();
+extern READLINK3res * nfsproc3_readlink_3_svc();
+#define NFSPROC3_READ 6
+extern READ3res * nfsproc3_read_3();
+extern READ3res * nfsproc3_read_3_svc();
+#define NFSPROC3_WRITE 7
+extern WRITE3res * nfsproc3_write_3();
+extern WRITE3res * nfsproc3_write_3_svc();
+#define NFSPROC3_CREATE 8
+extern CREATE3res * nfsproc3_create_3();
+extern CREATE3res * nfsproc3_create_3_svc();
+#define NFSPROC3_MKDIR 9
+extern MKDIR3res * nfsproc3_mkdir_3();
+extern MKDIR3res * nfsproc3_mkdir_3_svc();
+#define NFSPROC3_SYMLINK 10
+extern SYMLINK3res * nfsproc3_symlink_3();
+extern SYMLINK3res * nfsproc3_symlink_3_svc();
+#define NFSPROC3_MKNOD 11
+extern MKNOD3res * nfsproc3_mknod_3();
+extern MKNOD3res * nfsproc3_mknod_3_svc();
+#define NFSPROC3_REMOVE 12
+extern REMOVE3res * nfsproc3_remove_3();
+extern REMOVE3res * nfsproc3_remove_3_svc();
+#define NFSPROC3_RMDIR 13
+extern RMDIR3res * nfsproc3_rmdir_3();
+extern RMDIR3res * nfsproc3_rmdir_3_svc();
+#define NFSPROC3_RENAME 14
+extern RENAME3res * nfsproc3_rename_3();
+extern RENAME3res * nfsproc3_rename_3_svc();
+#define NFSPROC3_LINK 15
+extern LINK3res * nfsproc3_link_3();
+extern LINK3res * nfsproc3_link_3_svc();
+#define NFSPROC3_READDIR 16
+extern READDIR3res * nfsproc3_readdir_3();
+extern READDIR3res * nfsproc3_readdir_3_svc();
+#define NFSPROC3_READDIRPLUS 17
+extern READDIRPLUS3res * nfsproc3_readdirplus_3();
+extern READDIRPLUS3res * nfsproc3_readdirplus_3_svc();
+#define NFSPROC3_FSSTAT 18
+extern FSSTAT3res * nfsproc3_fsstat_3();
+extern FSSTAT3res * nfsproc3_fsstat_3_svc();
+#define NFSPROC3_FSINFO 19
+extern FSINFO3res * nfsproc3_fsinfo_3();
+extern FSINFO3res * nfsproc3_fsinfo_3_svc();
+#define NFSPROC3_PATHCONF 20
+extern PATHCONF3res * nfsproc3_pathconf_3();
+extern PATHCONF3res * nfsproc3_pathconf_3_svc();
+#define NFSPROC3_COMMIT 21
+extern COMMIT3res * nfsproc3_commit_3();
+extern COMMIT3res * nfsproc3_commit_3_svc();
+extern int nfs_program_3_freeresult ();
+#endif /* K&R C */
+
+/* the xdr functions */
+
+#if defined(__STDC__) || defined(__cplusplus)
+extern bool_t xdr_uint64 (XDR *, uint64*);
+extern bool_t xdr_int64 (XDR *, int64*);
+extern bool_t xdr_uint32 (XDR *, uint32*);
+extern bool_t xdr_int32 (XDR *, int32*);
+extern bool_t xdr_filename3 (XDR *, filename3*);
+extern bool_t xdr_nfspath3 (XDR *, nfspath3*);
+extern bool_t xdr_fileid3 (XDR *, fileid3*);
+extern bool_t xdr_cookie3 (XDR *, cookie3*);
+extern bool_t xdr_cookieverf3 (XDR *, cookieverf3);
+extern bool_t xdr_createverf3 (XDR *, createverf3);
+extern bool_t xdr_writeverf3 (XDR *, writeverf3);
+extern bool_t xdr_uid3 (XDR *, uid3*);
+extern bool_t xdr_gid3 (XDR *, gid3*);
+extern bool_t xdr_size3 (XDR *, size3*);
+extern bool_t xdr_offset3 (XDR *, offset3*);
+extern bool_t xdr_mode3 (XDR *, mode3*);
+extern bool_t xdr_count3 (XDR *, count3*);
+extern bool_t xdr_nfsstat3 (XDR *, nfsstat3*);
+extern bool_t xdr_ftype3 (XDR *, ftype3*);
+extern bool_t xdr_specdata3 (XDR *, specdata3*);
+extern bool_t xdr_nfs_fh3 (XDR *, nfs_fh3*);
+extern bool_t xdr_nfstime3 (XDR *, nfstime3*);
+extern bool_t xdr_fattr3 (XDR *, fattr3*);
+extern bool_t xdr_post_op_attr (XDR *, post_op_attr*);
+extern bool_t xdr_wcc_attr (XDR *, wcc_attr*);
+extern bool_t xdr_pre_op_attr (XDR *, pre_op_attr*);
+extern bool_t xdr_wcc_data (XDR *, wcc_data*);
+extern bool_t xdr_post_op_fh3 (XDR *, post_op_fh3*);
+extern bool_t xdr_time_how (XDR *, time_how*);
+extern bool_t xdr_set_mode3 (XDR *, set_mode3*);
+extern bool_t xdr_set_uid3 (XDR *, set_uid3*);
+extern bool_t xdr_set_gid3 (XDR *, set_gid3*);
+extern bool_t xdr_set_size3 (XDR *, set_size3*);
+extern bool_t xdr_set_atime (XDR *, set_atime*);
+extern bool_t xdr_set_mtime (XDR *, set_mtime*);
+extern bool_t xdr_sattr3 (XDR *, sattr3*);
+extern bool_t xdr_diropargs3 (XDR *, diropargs3*);
+extern bool_t xdr_GETATTR3args (XDR *, GETATTR3args*);
+extern bool_t xdr_GETATTR3resok (XDR *, GETATTR3resok*);
+extern bool_t xdr_GETATTR3res (XDR *, GETATTR3res*);
+extern bool_t xdr_sattrguard3 (XDR *, sattrguard3*);
+extern bool_t xdr_SETATTR3args (XDR *, SETATTR3args*);
+extern bool_t xdr_SETATTR3resok (XDR *, SETATTR3resok*);
+extern bool_t xdr_SETATTR3resfail (XDR *, SETATTR3resfail*);
+extern bool_t xdr_SETATTR3res (XDR *, SETATTR3res*);
+extern bool_t xdr_LOOKUP3args (XDR *, LOOKUP3args*);
+extern bool_t xdr_LOOKUP3resok (XDR *, LOOKUP3resok*);
+extern bool_t xdr_LOOKUP3resfail (XDR *, LOOKUP3resfail*);
+extern bool_t xdr_LOOKUP3res (XDR *, LOOKUP3res*);
+extern bool_t xdr_ACCESS3args (XDR *, ACCESS3args*);
+extern bool_t xdr_ACCESS3resok (XDR *, ACCESS3resok*);
+extern bool_t xdr_ACCESS3resfail (XDR *, ACCESS3resfail*);
+extern bool_t xdr_ACCESS3res (XDR *, ACCESS3res*);
+extern bool_t xdr_READLINK3args (XDR *, READLINK3args*);
+extern bool_t xdr_READLINK3resok (XDR *, READLINK3resok*);
+extern bool_t xdr_READLINK3resfail (XDR *, READLINK3resfail*);
+extern bool_t xdr_READLINK3res (XDR *, READLINK3res*);
+extern bool_t xdr_READ3args (XDR *, READ3args*);
+extern bool_t xdr_READ3resok (XDR *, READ3resok*);
+extern bool_t xdr_READ3resfail (XDR *, READ3resfail*);
+extern bool_t xdr_READ3res (XDR *, READ3res*);
+extern bool_t xdr_stable_how (XDR *, stable_how*);
+extern bool_t xdr_WRITE3args (XDR *, WRITE3args*);
+extern bool_t xdr_WRITE3resok (XDR *, WRITE3resok*);
+extern bool_t xdr_WRITE3resfail (XDR *, WRITE3resfail*);
+extern bool_t xdr_WRITE3res (XDR *, WRITE3res*);
+extern bool_t xdr_createmode3 (XDR *, createmode3*);
+extern bool_t xdr_createhow3 (XDR *, createhow3*);
+extern bool_t xdr_CREATE3args (XDR *, CREATE3args*);
+extern bool_t xdr_CREATE3resok (XDR *, CREATE3resok*);
+extern bool_t xdr_CREATE3resfail (XDR *, CREATE3resfail*);
+extern bool_t xdr_CREATE3res (XDR *, CREATE3res*);
+extern bool_t xdr_MKDIR3args (XDR *, MKDIR3args*);
+extern bool_t xdr_MKDIR3resok (XDR *, MKDIR3resok*);
+extern bool_t xdr_MKDIR3resfail (XDR *, MKDIR3resfail*);
+extern bool_t xdr_MKDIR3res (XDR *, MKDIR3res*);
+extern bool_t xdr_symlinkdata3 (XDR *, symlinkdata3*);
+extern bool_t xdr_SYMLINK3args (XDR *, SYMLINK3args*);
+extern bool_t xdr_SYMLINK3resok (XDR *, SYMLINK3resok*);
+extern bool_t xdr_SYMLINK3resfail (XDR *, SYMLINK3resfail*);
+extern bool_t xdr_SYMLINK3res (XDR *, SYMLINK3res*);
+extern bool_t xdr_devicedata3 (XDR *, devicedata3*);
+extern bool_t xdr_mknoddata3 (XDR *, mknoddata3*);
+extern bool_t xdr_MKNOD3args (XDR *, MKNOD3args*);
+extern bool_t xdr_MKNOD3resok (XDR *, MKNOD3resok*);
+extern bool_t xdr_MKNOD3resfail (XDR *, MKNOD3resfail*);
+extern bool_t xdr_MKNOD3res (XDR *, MKNOD3res*);
+extern bool_t xdr_REMOVE3args (XDR *, REMOVE3args*);
+extern bool_t xdr_REMOVE3resok (XDR *, REMOVE3resok*);
+extern bool_t xdr_REMOVE3resfail (XDR *, REMOVE3resfail*);
+extern bool_t xdr_REMOVE3res (XDR *, REMOVE3res*);
+extern bool_t xdr_RMDIR3args (XDR *, RMDIR3args*);
+extern bool_t xdr_RMDIR3resok (XDR *, RMDIR3resok*);
+extern bool_t xdr_RMDIR3resfail (XDR *, RMDIR3resfail*);
+extern bool_t xdr_RMDIR3res (XDR *, RMDIR3res*);
+extern bool_t xdr_RENAME3args (XDR *, RENAME3args*);
+extern bool_t xdr_RENAME3resok (XDR *, RENAME3resok*);
+extern bool_t xdr_RENAME3resfail (XDR *, RENAME3resfail*);
+extern bool_t xdr_RENAME3res (XDR *, RENAME3res*);
+extern bool_t xdr_LINK3args (XDR *, LINK3args*);
+extern bool_t xdr_LINK3resok (XDR *, LINK3resok*);
+extern bool_t xdr_LINK3resfail (XDR *, LINK3resfail*);
+extern bool_t xdr_LINK3res (XDR *, LINK3res*);
+extern bool_t xdr_READDIR3args (XDR *, READDIR3args*);
+extern bool_t xdr_entry3 (XDR *, entry3*);
+extern bool_t xdr_dirlist3 (XDR *, dirlist3*);
+extern bool_t xdr_READDIR3resok (XDR *, READDIR3resok*);
+extern bool_t xdr_READDIR3resfail (XDR *, READDIR3resfail*);
+extern bool_t xdr_READDIR3res (XDR *, READDIR3res*);
+extern bool_t xdr_READDIRPLUS3args (XDR *, READDIRPLUS3args*);
+extern bool_t xdr_entryplus3 (XDR *, entryplus3*);
+extern bool_t xdr_dirlistplus3 (XDR *, dirlistplus3*);
+extern bool_t xdr_READDIRPLUS3resok (XDR *, READDIRPLUS3resok*);
+extern bool_t xdr_READDIRPLUS3resfail (XDR *, READDIRPLUS3resfail*);
+extern bool_t xdr_READDIRPLUS3res (XDR *, READDIRPLUS3res*);
+extern bool_t xdr_FSSTAT3args (XDR *, FSSTAT3args*);
+extern bool_t xdr_FSSTAT3resok (XDR *, FSSTAT3resok*);
+extern bool_t xdr_FSSTAT3resfail (XDR *, FSSTAT3resfail*);
+extern bool_t xdr_FSSTAT3res (XDR *, FSSTAT3res*);
+extern bool_t xdr_FSINFO3args (XDR *, FSINFO3args*);
+extern bool_t xdr_FSINFO3resok (XDR *, FSINFO3resok*);
+extern bool_t xdr_FSINFO3resfail (XDR *, FSINFO3resfail*);
+extern bool_t xdr_FSINFO3res (XDR *, FSINFO3res*);
+extern bool_t xdr_PATHCONF3args (XDR *, PATHCONF3args*);
+extern bool_t xdr_PATHCONF3resok (XDR *, PATHCONF3resok*);
+extern bool_t xdr_PATHCONF3resfail (XDR *, PATHCONF3resfail*);
+extern bool_t xdr_PATHCONF3res (XDR *, PATHCONF3res*);
+extern bool_t xdr_COMMIT3args (XDR *, COMMIT3args*);
+extern bool_t xdr_COMMIT3resok (XDR *, COMMIT3resok*);
+extern bool_t xdr_COMMIT3resfail (XDR *, COMMIT3resfail*);
+extern bool_t xdr_COMMIT3res (XDR *, COMMIT3res*);
+
+#else /* K&R C */
+extern bool_t xdr_uint64 ();
+extern bool_t xdr_int64 ();
+extern bool_t xdr_uint32 ();
+extern bool_t xdr_int32 ();
+extern bool_t xdr_filename3 ();
+extern bool_t xdr_nfspath3 ();
+extern bool_t xdr_fileid3 ();
+extern bool_t xdr_cookie3 ();
+extern bool_t xdr_cookieverf3 ();
+extern bool_t xdr_createverf3 ();
+extern bool_t xdr_writeverf3 ();
+extern bool_t xdr_uid3 ();
+extern bool_t xdr_gid3 ();
+extern bool_t xdr_size3 ();
+extern bool_t xdr_offset3 ();
+extern bool_t xdr_mode3 ();
+extern bool_t xdr_count3 ();
+extern bool_t xdr_nfsstat3 ();
+extern bool_t xdr_ftype3 ();
+extern bool_t xdr_specdata3 ();
+extern bool_t xdr_nfs_fh3 ();
+extern bool_t xdr_nfstime3 ();
+extern bool_t xdr_fattr3 ();
+extern bool_t xdr_post_op_attr ();
+extern bool_t xdr_wcc_attr ();
+extern bool_t xdr_pre_op_attr ();
+extern bool_t xdr_wcc_data ();
+extern bool_t xdr_post_op_fh3 ();
+extern bool_t xdr_time_how ();
+extern bool_t xdr_set_mode3 ();
+extern bool_t xdr_set_uid3 ();
+extern bool_t xdr_set_gid3 ();
+extern bool_t xdr_set_size3 ();
+extern bool_t xdr_set_atime ();
+extern bool_t xdr_set_mtime ();
+extern bool_t xdr_sattr3 ();
+extern bool_t xdr_diropargs3 ();
+extern bool_t xdr_GETATTR3args ();
+extern bool_t xdr_GETATTR3resok ();
+extern bool_t xdr_GETATTR3res ();
+extern bool_t xdr_sattrguard3 ();
+extern bool_t xdr_SETATTR3args ();
+extern bool_t xdr_SETATTR3resok ();
+extern bool_t xdr_SETATTR3resfail ();
+extern bool_t xdr_SETATTR3res ();
+extern bool_t xdr_LOOKUP3args ();
+extern bool_t xdr_LOOKUP3resok ();
+extern bool_t xdr_LOOKUP3resfail ();
+extern bool_t xdr_LOOKUP3res ();
+extern bool_t xdr_ACCESS3args ();
+extern bool_t xdr_ACCESS3resok ();
+extern bool_t xdr_ACCESS3resfail ();
+extern bool_t xdr_ACCESS3res ();
+extern bool_t xdr_READLINK3args ();
+extern bool_t xdr_READLINK3resok ();
+extern bool_t xdr_READLINK3resfail ();
+extern bool_t xdr_READLINK3res ();
+extern bool_t xdr_READ3args ();
+extern bool_t xdr_READ3resok ();
+extern bool_t xdr_READ3resfail ();
+extern bool_t xdr_READ3res ();
+extern bool_t xdr_stable_how ();
+extern bool_t xdr_WRITE3args ();
+extern bool_t xdr_WRITE3resok ();
+extern bool_t xdr_WRITE3resfail ();
+extern bool_t xdr_WRITE3res ();
+extern bool_t xdr_createmode3 ();
+extern bool_t xdr_createhow3 ();
+extern bool_t xdr_CREATE3args ();
+extern bool_t xdr_CREATE3resok ();
+extern bool_t xdr_CREATE3resfail ();
+extern bool_t xdr_CREATE3res ();
+extern bool_t xdr_MKDIR3args ();
+extern bool_t xdr_MKDIR3resok ();
+extern bool_t xdr_MKDIR3resfail ();
+extern bool_t xdr_MKDIR3res ();
+extern bool_t xdr_symlinkdata3 ();
+extern bool_t xdr_SYMLINK3args ();
+extern bool_t xdr_SYMLINK3resok ();
+extern bool_t xdr_SYMLINK3resfail ();
+extern bool_t xdr_SYMLINK3res ();
+extern bool_t xdr_devicedata3 ();
+extern bool_t xdr_mknoddata3 ();
+extern bool_t xdr_MKNOD3args ();
+extern bool_t xdr_MKNOD3resok ();
+extern bool_t xdr_MKNOD3resfail ();
+extern bool_t xdr_MKNOD3res ();
+extern bool_t xdr_REMOVE3args ();
+extern bool_t xdr_REMOVE3resok ();
+extern bool_t xdr_REMOVE3resfail ();
+extern bool_t xdr_REMOVE3res ();
+extern bool_t xdr_RMDIR3args ();
+extern bool_t xdr_RMDIR3resok ();
+extern bool_t xdr_RMDIR3resfail ();
+extern bool_t xdr_RMDIR3res ();
+extern bool_t xdr_RENAME3args ();
+extern bool_t xdr_RENAME3resok ();
+extern bool_t xdr_RENAME3resfail ();
+extern bool_t xdr_RENAME3res ();
+extern bool_t xdr_LINK3args ();
+extern bool_t xdr_LINK3resok ();
+extern bool_t xdr_LINK3resfail ();
+extern bool_t xdr_LINK3res ();
+extern bool_t xdr_READDIR3args ();
+extern bool_t xdr_entry3 ();
+extern bool_t xdr_dirlist3 ();
+extern bool_t xdr_READDIR3resok ();
+extern bool_t xdr_READDIR3resfail ();
+extern bool_t xdr_READDIR3res ();
+extern bool_t xdr_READDIRPLUS3args ();
+extern bool_t xdr_entryplus3 ();
+extern bool_t xdr_dirlistplus3 ();
+extern bool_t xdr_READDIRPLUS3resok ();
+extern bool_t xdr_READDIRPLUS3resfail ();
+extern bool_t xdr_READDIRPLUS3res ();
+extern bool_t xdr_FSSTAT3args ();
+extern bool_t xdr_FSSTAT3resok ();
+extern bool_t xdr_FSSTAT3resfail ();
+extern bool_t xdr_FSSTAT3res ();
+extern bool_t xdr_FSINFO3args ();
+extern bool_t xdr_FSINFO3resok ();
+extern bool_t xdr_FSINFO3resfail ();
+extern bool_t xdr_FSINFO3res ();
+extern bool_t xdr_PATHCONF3args ();
+extern bool_t xdr_PATHCONF3resok ();
+extern bool_t xdr_PATHCONF3resfail ();
+extern bool_t xdr_PATHCONF3res ();
+extern bool_t xdr_COMMIT3args ();
+extern bool_t xdr_COMMIT3resok ();
+extern bool_t xdr_COMMIT3resfail ();
+extern bool_t xdr_COMMIT3res ();
+
+#endif /* K&R C */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_NFS3_PROT_H_RPCGEN */
diff --git a/nfs/rpc_nfs3_prot.x b/nfs/rpc_nfs3_prot.x
new file mode 100644
index 0000000000000000000000000000000000000000..fba417c8cd6edb955e018a89dd38942f1e788c69
--- /dev/null
+++ b/nfs/rpc_nfs3_prot.x
@@ -0,0 +1,908 @@
+/*
+ * To compile this file into the proper files:
+ * rpcgen -C -N nfs.x
+ * rpcgen -C -N -m nfs.x > programs.c
+ * rpcgen -C -N -s tcp nfs.x > run_example.c
+ * rpcgen -C -N -Ss nfs.x > server_template.c
+ * rm nfs_clnt.c nfs_svc.c
+ * mv nfs_xdr.c xdr.c
+ */
+
+const PROGRAM = 100003;
+const VERSION = 3;
+const NFS3_FHSIZE = 64;
+const NFS3_COOKIEVERFSIZE = 8;
+const NFS3_CREATEVERFSIZE = 8;
+const NFS3_WRITEVERFSIZE = 8;
+
+typedef u_int64_t uint64;
+typedef int64_t int64;
+typedef u_int32_t uint32;
+typedef int32_t int32;
+typedef string filename3<>;
+typedef string nfspath3<>;
+typedef uint64 fileid3;
+typedef uint64 cookie3;
+typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef opaque createverf3[NFS3_CREATEVERFSIZE];
+typedef opaque writeverf3[NFS3_WRITEVERFSIZE];
+typedef uint32 uid3;
+typedef uint32 gid3;
+typedef uint64 size3;
+typedef uint64 offset3;
+typedef uint32 mode3;
+typedef uint32 count3;
+
+enum nfsstat3 {
+ NFS3_OK = 0,
+ NFS3ERR_PERM = 1,
+ NFS3ERR_NOENT = 2,
+ NFS3ERR_IO = 5,
+ NFS3ERR_NXIO = 6,
+ NFS3ERR_ACCES = 13,
+ NFS3ERR_EXIST = 17,
+ NFS3ERR_XDEV = 18,
+ NFS3ERR_NODEV = 19,
+ NFS3ERR_NOTDIR = 20,
+ NFS3ERR_ISDIR = 21,
+ NFS3ERR_INVAL = 22,
+ NFS3ERR_FBIG = 27,
+ NFS3ERR_NOSPC = 28,
+ NFS3ERR_ROFS = 30,
+ NFS3ERR_MLINK = 31,
+ NFS3ERR_NAMETOOLONG = 63,
+ NFS3ERR_NOTEMPTY = 66,
+ NFS3ERR_DQUOT = 69,
+ NFS3ERR_STALE = 70,
+ NFS3ERR_REMOTE = 71,
+ NFS3ERR_BADHANDLE = 10001,
+
+ NFS3ERR_NOT_SYNC = 10002,
+ NFS3ERR_BAD_COOKIE = 10003,
+ NFS3ERR_NOTSUPP = 10004,
+ NFS3ERR_TOOSMALL = 10005,
+ NFS3ERR_SERVERFAULT = 10006,
+ NFS3ERR_BADTYPE = 10007,
+ NFS3ERR_JUKEBOX = 10008
+};
+
+enum ftype3 {
+ NF3REG = 1,
+ NF3DIR = 2,
+ NF3BLK = 3,
+ NF3CHR = 4,
+ NF3LNK = 5,
+ NF3SOCK = 6,
+ NF3FIFO = 7
+};
+
+struct specdata3 {
+ uint32 specdata1;
+ uint32 specdata2;
+};
+
+struct nfs_fh3 {
+ opaque data<NFS3_FHSIZE>;
+};
+
+struct nfstime3 {
+ uint32 seconds;
+ uint32 nseconds;
+};
+
+struct fattr3 {
+ ftype3 type;
+ mode3 mode;
+ uint32 nlink;
+ uid3 uid;
+ gid3 gid;
+ size3 size;
+ size3 used;
+ specdata3 rdev;
+ uint64 fsid;
+ fileid3 fileid;
+ nfstime3 atime;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+
+union post_op_attr switch (bool attributes_follow) {
+case TRUE:
+ fattr3 attributes;
+case FALSE:
+ void;
+};
+
+struct wcc_attr {
+ size3 size;
+ nfstime3 mtime;
+ nfstime3 ctime;
+};
+
+union pre_op_attr switch (bool attributes_follow) {
+case TRUE:
+ wcc_attr attributes;
+case FALSE:
+ void;
+};
+
+struct wcc_data {
+ pre_op_attr before;
+ post_op_attr after;
+};
+
+union post_op_fh3 switch (bool handle_follows) {
+case TRUE:
+ nfs_fh3 handle;
+case FALSE:
+ void;
+};
+
+enum time_how {
+ DONT_CHANGE = 0,
+ SET_TO_SERVER_TIME = 1,
+ SET_TO_CLIENT_TIME = 2
+};
+
+union set_mode3 switch (bool set_it) {
+case TRUE:
+ mode3 mode;
+default:
+ void;
+};
+
+union set_uid3 switch (bool set_it) {
+case TRUE:
+ uid3 uid;
+default:
+ void;
+};
+
+union set_gid3 switch (bool set_it) {
+case TRUE:
+ gid3 gid;
+default:
+ void;
+};
+
+union set_size3 switch (bool set_it) {
+case TRUE:
+ size3 size;
+default:
+ void;
+};
+
+union set_atime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+ nfstime3 atime;
+default:
+ void;
+};
+
+union set_mtime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+ nfstime3 mtime;
+default:
+ void;
+};
+
+struct sattr3 {
+ set_mode3 mode;
+ set_uid3 uid;
+ set_gid3 gid;
+ set_size3 size;
+ set_atime atime;
+ set_mtime mtime;
+
+};
+
+struct diropargs3 {
+ nfs_fh3 dir;
+ filename3 name;
+};
+
+
+program NFS_PROGRAM {
+ version NFS_V3 {
+
+ void
+ NFSPROC3_NULL(void) = 0;
+
+ GETATTR3res
+ NFSPROC3_GETATTR(GETATTR3args) = 1;
+
+ SETATTR3res
+ NFSPROC3_SETATTR(SETATTR3args) = 2;
+
+ LOOKUP3res
+ NFSPROC3_LOOKUP(LOOKUP3args) = 3;
+
+ ACCESS3res
+ NFSPROC3_ACCESS(ACCESS3args) = 4;
+
+ READLINK3res
+ NFSPROC3_READLINK(READLINK3args) = 5;
+
+ READ3res
+ NFSPROC3_READ(READ3args) = 6;
+
+ WRITE3res
+ NFSPROC3_WRITE(WRITE3args) = 7;
+
+ CREATE3res
+ NFSPROC3_CREATE(CREATE3args) = 8;
+
+ MKDIR3res
+ NFSPROC3_MKDIR(MKDIR3args) = 9;
+
+ SYMLINK3res
+ NFSPROC3_SYMLINK(SYMLINK3args) = 10;
+
+ MKNOD3res
+ NFSPROC3_MKNOD(MKNOD3args) = 11;
+
+ REMOVE3res
+ NFSPROC3_REMOVE(REMOVE3args) = 12;
+
+ RMDIR3res
+ NFSPROC3_RMDIR(RMDIR3args) = 13;
+
+ RENAME3res
+ NFSPROC3_RENAME(RENAME3args) = 14;
+
+ LINK3res
+ NFSPROC3_LINK(LINK3args) = 15;
+
+ READDIR3res
+ NFSPROC3_READDIR(READDIR3args) = 16;
+
+ READDIRPLUS3res
+ NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
+
+ FSSTAT3res
+ NFSPROC3_FSSTAT(FSSTAT3args) = 18;
+
+ FSINFO3res
+ NFSPROC3_FSINFO(FSINFO3args) = 19;
+
+ PATHCONF3res
+ NFSPROC3_PATHCONF(PATHCONF3args) = 20;
+
+ COMMIT3res
+ NFSPROC3_COMMIT(COMMIT3args) = 21;
+
+} = 3;
+} = 100003;
+
+struct GETATTR3args {
+ nfs_fh3 object;
+};
+
+struct GETATTR3resok {
+ fattr3 obj_attributes;
+};
+
+union GETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ GETATTR3resok resok;
+default:
+ void;
+};
+
+union sattrguard3 switch (bool check) {
+case TRUE:
+ nfstime3 obj_ctime;
+case FALSE:
+ void;
+};
+
+struct SETATTR3args {
+ nfs_fh3 object;
+ sattr3 new_attributes;
+ sattrguard3 guard;
+};
+
+struct SETATTR3resok {
+ wcc_data obj_wcc;
+};
+
+struct SETATTR3resfail {
+ wcc_data obj_wcc;
+};
+
+union SETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ SETATTR3resok resok;
+default:
+ SETATTR3resfail resfail;
+};
+
+struct LOOKUP3args {
+ diropargs3 what;
+};
+
+struct LOOKUP3resok {
+ nfs_fh3 object;
+ post_op_attr obj_attributes;
+ post_op_attr dir_attributes;
+};
+
+struct LOOKUP3resfail {
+ post_op_attr dir_attributes;
+};
+
+union LOOKUP3res switch (nfsstat3 status) {
+case NFS3_OK:
+ LOOKUP3resok resok;
+default:
+ LOOKUP3resfail resfail;
+};
+
+
+const ACCESS3_READ = 0x0001;
+const ACCESS3_LOOKUP = 0x0002;
+const ACCESS3_MODIFY = 0x0004;
+const ACCESS3_EXTEND = 0x0008;
+const ACCESS3_DELETE = 0x0010;
+const ACCESS3_EXECUTE = 0x0020;
+
+struct ACCESS3args {
+ nfs_fh3 object;
+ uint32 access;
+};
+
+struct ACCESS3resok {
+ post_op_attr obj_attributes;
+ uint32 access;
+};
+
+struct ACCESS3resfail {
+ post_op_attr obj_attributes;
+};
+
+union ACCESS3res switch (nfsstat3 status) {
+case NFS3_OK:
+ ACCESS3resok resok;
+default:
+ ACCESS3resfail resfail;
+};
+
+struct READLINK3args {
+ nfs_fh3 symlink;
+};
+
+struct READLINK3resok {
+ post_op_attr symlink_attributes;
+ nfspath3 data;
+};
+
+struct READLINK3resfail {
+ post_op_attr symlink_attributes;
+};
+
+union READLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READLINK3resok resok;
+default:
+ READLINK3resfail resfail;
+};
+
+struct READ3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+
+struct READ3resok {
+ post_op_attr file_attributes;
+ count3 count;
+ bool eof;
+ opaque data<>;
+};
+
+struct READ3resfail {
+ post_op_attr file_attributes;
+};
+
+union READ3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READ3resok resok;
+default:
+ READ3resfail resfail;
+};
+
+enum stable_how {
+ UNSTABLE = 0,
+ DATA_SYNC = 1,
+ FILE_SYNC = 2
+};
+
+struct WRITE3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+ stable_how stable;
+ opaque data<>;
+};
+
+struct WRITE3resok {
+ wcc_data file_wcc;
+ count3 count;
+ stable_how committed;
+ writeverf3 verf;
+};
+
+struct WRITE3resfail {
+ wcc_data file_wcc;
+};
+
+union WRITE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ WRITE3resok resok;
+default:
+ WRITE3resfail resfail;
+};
+
+
+enum createmode3 {
+ UNCHECKED = 0,
+ GUARDED = 1,
+ EXCLUSIVE = 2
+};
+
+union createhow3 switch (createmode3 mode) {
+case UNCHECKED:
+case GUARDED:
+ sattr3 obj_attributes;
+case EXCLUSIVE:
+ createverf3 verf;
+};
+
+struct CREATE3args {
+ diropargs3 where;
+ createhow3 how;
+};
+
+struct CREATE3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct CREATE3resfail {
+ wcc_data dir_wcc;
+};
+
+union CREATE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ CREATE3resok resok;
+default:
+ CREATE3resfail resfail;
+};
+
+
+struct MKDIR3args {
+ diropargs3 where;
+ sattr3 attributes;
+};
+
+struct MKDIR3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct MKDIR3resfail {
+ wcc_data dir_wcc;
+};
+
+union MKDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ MKDIR3resok resok;
+default:
+ MKDIR3resfail resfail;
+};
+
+
+struct symlinkdata3 {
+ sattr3 symlink_attributes;
+ nfspath3 symlink_data;
+};
+
+struct SYMLINK3args {
+ diropargs3 where;
+ symlinkdata3 symlink;
+};
+
+struct SYMLINK3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct SYMLINK3resfail {
+ wcc_data dir_wcc;
+};
+
+union SYMLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+ SYMLINK3resok resok;
+default:
+ SYMLINK3resfail resfail;
+};
+
+
+struct devicedata3 {
+ sattr3 dev_attributes;
+ specdata3 spec;
+};
+
+union mknoddata3 switch (ftype3 type) {
+case NF3CHR:
+case NF3BLK:
+ devicedata3 device;
+case NF3SOCK:
+case NF3FIFO:
+ sattr3 pipe_attributes;
+default:
+ void;
+};
+
+struct MKNOD3args {
+ diropargs3 where;
+ mknoddata3 what;
+};
+
+struct MKNOD3resok {
+ post_op_fh3 obj;
+ post_op_attr obj_attributes;
+ wcc_data dir_wcc;
+};
+
+struct MKNOD3resfail {
+ wcc_data dir_wcc;
+};
+
+union MKNOD3res switch (nfsstat3 status) {
+case NFS3_OK:
+ MKNOD3resok resok;
+default:
+ MKNOD3resfail resfail;
+};
+
+struct REMOVE3args {
+ diropargs3 object;
+};
+
+struct REMOVE3resok {
+ wcc_data dir_wcc;
+};
+
+struct REMOVE3resfail {
+ wcc_data dir_wcc;
+};
+
+union REMOVE3res switch (nfsstat3 status) {
+case NFS3_OK:
+ REMOVE3resok resok;
+default:
+ REMOVE3resfail resfail;
+};
+
+
+struct RMDIR3args {
+ diropargs3 object;
+};
+
+struct RMDIR3resok {
+ wcc_data dir_wcc;
+};
+
+struct RMDIR3resfail {
+ wcc_data dir_wcc;
+};
+
+union RMDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ RMDIR3resok resok;
+default:
+ RMDIR3resfail resfail;
+};
+
+struct RENAME3args {
+ diropargs3 from;
+ diropargs3 to;
+};
+
+struct RENAME3resok {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+struct RENAME3resfail {
+ wcc_data fromdir_wcc;
+ wcc_data todir_wcc;
+};
+
+union RENAME3res switch (nfsstat3 status) {
+case NFS3_OK:
+ RENAME3resok resok;
+default:
+ RENAME3resfail resfail;
+};
+
+struct LINK3args {
+ nfs_fh3 file;
+ diropargs3 link;
+};
+
+struct LINK3resok {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+
+struct LINK3resfail {
+ post_op_attr file_attributes;
+ wcc_data linkdir_wcc;
+};
+
+union LINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+
+ LINK3resok resok;
+default:
+ LINK3resfail resfail;
+};
+
+struct READDIR3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 count;
+};
+
+struct entry3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ entry3 *nextentry;
+};
+
+struct dirlist3 {
+ entry3 *entries;
+ bool eof;
+};
+
+struct READDIR3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlist3 reply;
+};
+
+struct READDIR3resfail {
+ post_op_attr dir_attributes;
+};
+
+union READDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READDIR3resok resok;
+default:
+ READDIR3resfail resfail;
+};
+
+struct READDIRPLUS3args {
+ nfs_fh3 dir;
+ cookie3 cookie;
+ cookieverf3 cookieverf;
+ count3 dircount;
+ count3 maxcount;
+};
+
+struct entryplus3 {
+ fileid3 fileid;
+ filename3 name;
+ cookie3 cookie;
+ post_op_attr name_attributes;
+ post_op_fh3 name_handle;
+ entryplus3 *nextentry;
+};
+
+struct dirlistplus3 {
+ entryplus3 *entries;
+ bool eof;
+};
+
+struct READDIRPLUS3resok {
+ post_op_attr dir_attributes;
+ cookieverf3 cookieverf;
+ dirlistplus3 reply;
+};
+
+struct READDIRPLUS3resfail {
+ post_op_attr dir_attributes;
+};
+
+union READDIRPLUS3res switch (nfsstat3 status) {
+case NFS3_OK:
+ READDIRPLUS3resok resok;
+default:
+ READDIRPLUS3resfail resfail;
+};
+
+struct FSSTAT3args {
+ nfs_fh3 fsroot;
+};
+
+struct FSSTAT3resok {
+ post_op_attr obj_attributes;
+ size3 tbytes;
+ size3 fbytes;
+ size3 abytes;
+ size3 tfiles;
+ size3 ffiles;
+ size3 afiles;
+ uint32 invarsec;
+};
+
+struct FSSTAT3resfail {
+ post_op_attr obj_attributes;
+};
+
+union FSSTAT3res switch (nfsstat3 status) {
+case NFS3_OK:
+ FSSTAT3resok resok;
+default:
+ FSSTAT3resfail resfail;
+};
+
+const FSF3_LINK = 0x0001;
+const FSF3_SYMLINK = 0x0002;
+const FSF3_HOMOGENEOUS = 0x0008;
+const FSF3_CANSETTIME = 0x0010;
+
+struct FSINFO3args {
+ nfs_fh3 fsroot;
+};
+
+struct FSINFO3resok {
+ post_op_attr obj_attributes;
+ uint32 rtmax;
+ uint32 rtpref;
+ uint32 rtmult;
+ uint32 wtmax;
+ uint32 wtpref;
+ uint32 wtmult;
+ uint32 dtpref;
+
+ size3 maxfilesize;
+ nfstime3 time_delta;
+ uint32 properties;
+};
+
+struct FSINFO3resfail {
+ post_op_attr obj_attributes;
+};
+
+union FSINFO3res switch (nfsstat3 status) {
+case NFS3_OK:
+ FSINFO3resok resok;
+default:
+ FSINFO3resfail resfail;
+};
+
+struct PATHCONF3args {
+ nfs_fh3 object;
+};
+
+struct PATHCONF3resok {
+ post_op_attr obj_attributes;
+ uint32 linkmax;
+ uint32 name_max;
+ bool no_trunc;
+ bool chown_restricted;
+ bool case_insensitive;
+ bool case_preserving;
+};
+
+struct PATHCONF3resfail {
+ post_op_attr obj_attributes;
+};
+
+union PATHCONF3res switch (nfsstat3 status) {
+case NFS3_OK:
+ PATHCONF3resok resok;
+default:
+ PATHCONF3resfail resfail;
+};
+
+struct COMMIT3args {
+ nfs_fh3 file;
+ offset3 offset;
+ count3 count;
+};
+
+struct COMMIT3resok {
+ wcc_data file_wcc;
+ writeverf3 verf;
+};
+
+struct COMMIT3resfail {
+ wcc_data file_wcc;
+};
+
+union COMMIT3res switch (nfsstat3 status) {
+case NFS3_OK:
+ COMMIT3resok resok;
+default:
+ COMMIT3resfail resfail;
+};
+
+
+const MNTPATHLEN = 1024; /* Maximum bytes in a path name */
+const MNTNAMLEN = 255; /* Maximum bytes in a name */
+const FHSIZE3 = 64; /* Maximum bytes in a V3 file handle */
+
+typedef opaque fhandle3<FHSIZE3>;
+typedef string dirpath<MNTPATHLEN>;
+typedef string name<MNTNAMLEN>;
+
+enum mountstat3 {
+ MNT3_OK = 0, /* no error */
+ MNT3ERR_PERM = 1, /* Not owner */
+ MNT3ERR_NOENT = 2, /* No such file or directory */
+ MNT3ERR_IO = 5, /* I/O error */
+ MNT3ERR_ACCES = 13, /* Permission denied */
+ MNT3ERR_NOTDIR = 20, /* Not a directory */
+ MNT3ERR_INVAL = 22, /* Invalid argument */
+ MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
+ MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
+ MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */
+};
+
+
+program MOUNT_PROGRAM {
+ version MOUNT_V3 {
+ void MOUNTPROC3_NULL(void) = 0;
+ mountres3 MOUNTPROC3_MNT(dirpath) = 1;
+ mountlist MOUNTPROC3_DUMP(void) = 2;
+ void MOUNTPROC3_UMNT(dirpath) = 3;
+ void MOUNTPROC3_UMNTALL(void) = 4;
+ exports MOUNTPROC3_EXPORT(void) = 5;
+ } = 3;
+} = 100005;
+
+struct mountres3_ok {
+ fhandle3 fhandle;
+ int auth_flavors<>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case MNT3_OK:
+ mountres3_ok mountinfo;
+default:
+ void;
+};
+
+typedef struct mountbody *mountlist;
+
+struct mountbody {
+ name ml_hostname;
+ dirpath ml_directory;
+ mountlist ml_next;
+};
+
+
+typedef struct groupnode *groups;
+
+struct groupnode {
+ name gr_name;
+ groups gr_next;
+};
+
+typedef struct exportnode *exports;
+
+struct exportnode {
+ dirpath ex_dir;
+ groups ex_groups;
+ exports ex_next;
+};
diff --git a/nfs/rpc_nfs3_prot_xdr.c b/nfs/rpc_nfs3_prot_xdr.c
new file mode 100644
index 0000000000000000000000000000000000000000..57f4a8546ae697f41f98efb24c01b6de739d380f
--- /dev/null
+++ b/nfs/rpc_nfs3_prot_xdr.c
@@ -0,0 +1,1908 @@
+/*
+ * Please do not edit this file.
+ * It was generated using rpcgen.
+ */
+
+#include "rpc_nfs3_prot.h"
+
+bool_t
+xdr_uint64 (XDR *xdrs, uint64 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_u_quad_t (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_int64 (XDR *xdrs, int64 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_quad_t (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_uint32 (XDR *xdrs, uint32 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_u_int (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_int32 (XDR *xdrs, int32 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_int (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_filename3 (XDR *xdrs, filename3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfspath3 (XDR *xdrs, nfspath3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_string (xdrs, objp, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fileid3 (XDR *xdrs, fileid3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_cookie3 (XDR *xdrs, cookie3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_cookieverf3 (XDR *xdrs, cookieverf3 objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_opaque (xdrs, objp, NFS3_COOKIEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_createverf3 (XDR *xdrs, createverf3 objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_opaque (xdrs, objp, NFS3_CREATEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_writeverf3 (XDR *xdrs, writeverf3 objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_opaque (xdrs, objp, NFS3_WRITEVERFSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_uid3 (XDR *xdrs, uid3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_gid3 (XDR *xdrs, gid3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_size3 (XDR *xdrs, size3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_offset3 (XDR *xdrs, offset3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint64 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mode3 (XDR *xdrs, mode3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_count3 (XDR *xdrs, count3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint32 (xdrs, objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfsstat3 (XDR *xdrs, nfsstat3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ftype3 (XDR *xdrs, ftype3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_specdata3 (XDR *xdrs, specdata3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint32 (xdrs, &objp->specdata1))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->specdata2))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfs_fh3 (XDR *xdrs, nfs_fh3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS3_FHSIZE))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_nfstime3 (XDR *xdrs, nfstime3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_uint32 (xdrs, &objp->seconds))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->nseconds))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_fattr3 (XDR *xdrs, fattr3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_ftype3 (xdrs, &objp->type))
+ return FALSE;
+ if (!xdr_mode3 (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->nlink))
+ return FALSE;
+ if (!xdr_uid3 (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_gid3 (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->used))
+ return FALSE;
+ if (!xdr_specdata3 (xdrs, &objp->rdev))
+ return FALSE;
+ if (!xdr_uint64 (xdrs, &objp->fsid))
+ return FALSE;
+ if (!xdr_fileid3 (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_post_op_attr (XDR *xdrs, post_op_attr *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_fattr3 (xdrs, &objp->post_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_wcc_attr (XDR *xdrs, wcc_attr *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_size3 (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->mtime))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->ctime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_pre_op_attr (XDR *xdrs, pre_op_attr *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->attributes_follow))
+ return FALSE;
+ switch (objp->attributes_follow) {
+ case TRUE:
+ if (!xdr_wcc_attr (xdrs, &objp->pre_op_attr_u.attributes))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_wcc_data (XDR *xdrs, wcc_data *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pre_op_attr (xdrs, &objp->before))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->after))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_post_op_fh3 (XDR *xdrs, post_op_fh3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->handle_follows))
+ return FALSE;
+ switch (objp->handle_follows) {
+ case TRUE:
+ if (!xdr_nfs_fh3 (xdrs, &objp->post_op_fh3_u.handle))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_time_how (XDR *xdrs, time_how *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_set_mode3 (XDR *xdrs, set_mode3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_mode3 (xdrs, &objp->set_mode3_u.mode))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_uid3 (XDR *xdrs, set_uid3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_uid3 (xdrs, &objp->set_uid3_u.uid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_gid3 (XDR *xdrs, set_gid3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_gid3 (xdrs, &objp->set_gid3_u.gid))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_size3 (XDR *xdrs, set_size3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case TRUE:
+ if (!xdr_size3 (xdrs, &objp->set_size3_u.size))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_atime (XDR *xdrs, set_atime *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_time_how (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case SET_TO_CLIENT_TIME:
+ if (!xdr_nfstime3 (xdrs, &objp->set_atime_u.atime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_set_mtime (XDR *xdrs, set_mtime *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_time_how (xdrs, &objp->set_it))
+ return FALSE;
+ switch (objp->set_it) {
+ case SET_TO_CLIENT_TIME:
+ if (!xdr_nfstime3 (xdrs, &objp->set_mtime_u.mtime))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_sattr3 (XDR *xdrs, sattr3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_set_mode3 (xdrs, &objp->mode))
+ return FALSE;
+ if (!xdr_set_uid3 (xdrs, &objp->uid))
+ return FALSE;
+ if (!xdr_set_gid3 (xdrs, &objp->gid))
+ return FALSE;
+ if (!xdr_set_size3 (xdrs, &objp->size))
+ return FALSE;
+ if (!xdr_set_atime (xdrs, &objp->atime))
+ return FALSE;
+ if (!xdr_set_mtime (xdrs, &objp->mtime))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_diropargs3 (XDR *xdrs, diropargs3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_filename3 (xdrs, &objp->name))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_GETATTR3args (XDR *xdrs, GETATTR3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_GETATTR3resok (XDR *xdrs, GETATTR3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_fattr3 (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_GETATTR3res (XDR *xdrs, GETATTR3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_GETATTR3resok (xdrs, &objp->GETATTR3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_sattrguard3 (XDR *xdrs, sattrguard3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_bool (xdrs, &objp->check))
+ return FALSE;
+ switch (objp->check) {
+ case TRUE:
+ if (!xdr_nfstime3 (xdrs, &objp->sattrguard3_u.obj_ctime))
+ return FALSE;
+ break;
+ case FALSE:
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_SETATTR3args (XDR *xdrs, SETATTR3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_sattr3 (xdrs, &objp->new_attributes))
+ return FALSE;
+ if (!xdr_sattrguard3 (xdrs, &objp->guard))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SETATTR3resok (XDR *xdrs, SETATTR3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SETATTR3resfail (XDR *xdrs, SETATTR3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->obj_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SETATTR3res (XDR *xdrs, SETATTR3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_SETATTR3resok (xdrs, &objp->SETATTR3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_SETATTR3resfail (xdrs, &objp->SETATTR3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_LOOKUP3args (XDR *xdrs, LOOKUP3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->what))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_LOOKUP3resok (XDR *xdrs, LOOKUP3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_LOOKUP3resfail (XDR *xdrs, LOOKUP3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_LOOKUP3res (XDR *xdrs, LOOKUP3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_LOOKUP3resok (xdrs, &objp->LOOKUP3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_LOOKUP3resfail (xdrs, &objp->LOOKUP3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_ACCESS3args (XDR *xdrs, ACCESS3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ACCESS3resok (XDR *xdrs, ACCESS3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->access))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ACCESS3resfail (XDR *xdrs, ACCESS3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_ACCESS3res (XDR *xdrs, ACCESS3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_ACCESS3resok (xdrs, &objp->ACCESS3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_ACCESS3resfail (xdrs, &objp->ACCESS3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_READLINK3args (XDR *xdrs, READLINK3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READLINK3resok (XDR *xdrs, READLINK3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_nfspath3 (xdrs, &objp->data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READLINK3resfail (XDR *xdrs, READLINK3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->symlink_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READLINK3res (XDR *xdrs, READLINK3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_READLINK3resok (xdrs, &objp->READLINK3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_READLINK3resfail (xdrs, &objp->READLINK3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_READ3args (XDR *xdrs, READ3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_offset3 (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READ3resok (XDR *xdrs, READ3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READ3resfail (XDR *xdrs, READ3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READ3res (XDR *xdrs, READ3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_READ3resok (xdrs, &objp->READ3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_READ3resfail (xdrs, &objp->READ3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_stable_how (XDR *xdrs, stable_how *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_WRITE3args (XDR *xdrs, WRITE3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_offset3 (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_stable_how (xdrs, &objp->stable))
+ return FALSE;
+ if (!xdr_bytes (xdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_WRITE3resok (XDR *xdrs, WRITE3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ if (!xdr_stable_how (xdrs, &objp->committed))
+ return FALSE;
+ if (!xdr_writeverf3 (xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_WRITE3resfail (XDR *xdrs, WRITE3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_WRITE3res (XDR *xdrs, WRITE3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_WRITE3resok (xdrs, &objp->WRITE3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_WRITE3resfail (xdrs, &objp->WRITE3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_createmode3 (XDR *xdrs, createmode3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_enum (xdrs, (enum_t *) objp))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_createhow3 (XDR *xdrs, createhow3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_createmode3 (xdrs, &objp->mode))
+ return FALSE;
+ switch (objp->mode) {
+ case UNCHECKED:
+ case GUARDED:
+ if (!xdr_sattr3 (xdrs, &objp->createhow3_u.obj_attributes))
+ return FALSE;
+ break;
+ case EXCLUSIVE:
+ if (!xdr_createverf3 (xdrs, objp->createhow3_u.verf))
+ return FALSE;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_CREATE3args (XDR *xdrs, CREATE3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_createhow3 (xdrs, &objp->how))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_CREATE3resok (XDR *xdrs, CREATE3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_CREATE3resfail (XDR *xdrs, CREATE3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_CREATE3res (XDR *xdrs, CREATE3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_CREATE3resok (xdrs, &objp->CREATE3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_CREATE3resfail (xdrs, &objp->CREATE3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_MKDIR3args (XDR *xdrs, MKDIR3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_sattr3 (xdrs, &objp->attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_MKDIR3resok (XDR *xdrs, MKDIR3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_MKDIR3resfail (XDR *xdrs, MKDIR3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_MKDIR3res (XDR *xdrs, MKDIR3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_MKDIR3resok (xdrs, &objp->MKDIR3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_MKDIR3resfail (xdrs, &objp->MKDIR3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_symlinkdata3 (XDR *xdrs, symlinkdata3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_sattr3 (xdrs, &objp->symlink_attributes))
+ return FALSE;
+ if (!xdr_nfspath3 (xdrs, &objp->symlink_data))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SYMLINK3args (XDR *xdrs, SYMLINK3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_symlinkdata3 (xdrs, &objp->symlink))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SYMLINK3resok (XDR *xdrs, SYMLINK3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SYMLINK3resfail (XDR *xdrs, SYMLINK3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_SYMLINK3res (XDR *xdrs, SYMLINK3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_SYMLINK3resok (xdrs, &objp->SYMLINK3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_SYMLINK3resfail (xdrs, &objp->SYMLINK3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_devicedata3 (XDR *xdrs, devicedata3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_sattr3 (xdrs, &objp->dev_attributes))
+ return FALSE;
+ if (!xdr_specdata3 (xdrs, &objp->spec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_mknoddata3 (XDR *xdrs, mknoddata3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_ftype3 (xdrs, &objp->type))
+ return FALSE;
+ switch (objp->type) {
+ case NF3CHR:
+ case NF3BLK:
+ if (!xdr_devicedata3 (xdrs, &objp->mknoddata3_u.device))
+ return FALSE;
+ break;
+ case NF3SOCK:
+ case NF3FIFO:
+ if (!xdr_sattr3 (xdrs, &objp->mknoddata3_u.pipe_attributes))
+ return FALSE;
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_MKNOD3args (XDR *xdrs, MKNOD3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->where))
+ return FALSE;
+ if (!xdr_mknoddata3 (xdrs, &objp->what))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_MKNOD3resok (XDR *xdrs, MKNOD3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_fh3 (xdrs, &objp->obj))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_MKNOD3resfail (XDR *xdrs, MKNOD3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_MKNOD3res (XDR *xdrs, MKNOD3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_MKNOD3resok (xdrs, &objp->MKNOD3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_MKNOD3resfail (xdrs, &objp->MKNOD3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_REMOVE3args (XDR *xdrs, REMOVE3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_REMOVE3resok (XDR *xdrs, REMOVE3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_REMOVE3resfail (XDR *xdrs, REMOVE3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_REMOVE3res (XDR *xdrs, REMOVE3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_REMOVE3resok (xdrs, &objp->REMOVE3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_REMOVE3resfail (xdrs, &objp->REMOVE3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_RMDIR3args (XDR *xdrs, RMDIR3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_RMDIR3resok (XDR *xdrs, RMDIR3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_RMDIR3resfail (XDR *xdrs, RMDIR3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->dir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_RMDIR3res (XDR *xdrs, RMDIR3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_RMDIR3resok (xdrs, &objp->RMDIR3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_RMDIR3resfail (xdrs, &objp->RMDIR3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_RENAME3args (XDR *xdrs, RENAME3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_diropargs3 (xdrs, &objp->fromfile))
+ return FALSE;
+ if (!xdr_diropargs3 (xdrs, &objp->tofile))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_RENAME3resok (XDR *xdrs, RENAME3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_RENAME3resfail (XDR *xdrs, RENAME3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->fromdir_wcc))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->todir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_RENAME3res (XDR *xdrs, RENAME3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_RENAME3resok (xdrs, &objp->RENAME3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_RENAME3resfail (xdrs, &objp->RENAME3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_LINK3args (XDR *xdrs, LINK3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_diropargs3 (xdrs, &objp->link))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_LINK3resok (XDR *xdrs, LINK3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_LINK3resfail (XDR *xdrs, LINK3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->file_attributes))
+ return FALSE;
+ if (!xdr_wcc_data (xdrs, &objp->linkdir_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_LINK3res (XDR *xdrs, LINK3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_LINK3resok (xdrs, &objp->LINK3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_LINK3resfail (xdrs, &objp->LINK3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_READDIR3args (XDR *xdrs, READDIR3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entry3 (XDR *xdrs, entry3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_fileid3 (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_filename3 (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entry3), (xdrproc_t) xdr_entry3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirlist3 (XDR *xdrs, dirlist3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entry3), (xdrproc_t) xdr_entry3))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READDIR3resok (XDR *xdrs, READDIR3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_dirlist3 (xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READDIR3resfail (XDR *xdrs, READDIR3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READDIR3res (XDR *xdrs, READDIR3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_READDIR3resok (xdrs, &objp->READDIR3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_READDIR3resfail (xdrs, &objp->READDIR3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_READDIRPLUS3args (XDR *xdrs, READDIRPLUS3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->dir))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->dircount))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->maxcount))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_entryplus3 (XDR *xdrs, entryplus3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_fileid3 (xdrs, &objp->fileid))
+ return FALSE;
+ if (!xdr_filename3 (xdrs, &objp->name))
+ return FALSE;
+ if (!xdr_cookie3 (xdrs, &objp->cookie))
+ return FALSE;
+ if (!xdr_post_op_attr (xdrs, &objp->name_attributes))
+ return FALSE;
+ if (!xdr_post_op_fh3 (xdrs, &objp->name_handle))
+ return FALSE;
+ if (!xdr_pointer (xdrs, (char **)&objp->nextentry, sizeof (entryplus3), (xdrproc_t) xdr_entryplus3))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_dirlistplus3 (XDR *xdrs, dirlistplus3 *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_pointer (xdrs, (char **)&objp->entries, sizeof (entryplus3), (xdrproc_t) xdr_entryplus3))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->eof))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READDIRPLUS3resok (XDR *xdrs, READDIRPLUS3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ if (!xdr_cookieverf3 (xdrs, objp->cookieverf))
+ return FALSE;
+ if (!xdr_dirlistplus3 (xdrs, &objp->reply))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READDIRPLUS3resfail (XDR *xdrs, READDIRPLUS3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->dir_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_READDIRPLUS3res (XDR *xdrs, READDIRPLUS3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_READDIRPLUS3resok (xdrs, &objp->READDIRPLUS3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_READDIRPLUS3resfail (xdrs, &objp->READDIRPLUS3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_FSSTAT3args (XDR *xdrs, FSSTAT3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_FSSTAT3resok (XDR *xdrs, FSSTAT3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->tbytes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->fbytes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->abytes))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->tfiles))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->ffiles))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->afiles))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->invarsec))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_FSSTAT3resfail (XDR *xdrs, FSSTAT3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_FSSTAT3res (XDR *xdrs, FSSTAT3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_FSSTAT3resok (xdrs, &objp->FSSTAT3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_FSSTAT3resfail (xdrs, &objp->FSSTAT3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_FSINFO3args (XDR *xdrs, FSINFO3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->fsroot))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_FSINFO3resok (XDR *xdrs, FSINFO3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->rtmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->rtpref))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->rtmult))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->wtmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->wtpref))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->wtmult))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->dtpref))
+ return FALSE;
+ if (!xdr_size3 (xdrs, &objp->maxfilesize))
+ return FALSE;
+ if (!xdr_nfstime3 (xdrs, &objp->time_delta))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->properties))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_FSINFO3resfail (XDR *xdrs, FSINFO3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_FSINFO3res (XDR *xdrs, FSINFO3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_FSINFO3resok (xdrs, &objp->FSINFO3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_FSINFO3resfail (xdrs, &objp->FSINFO3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_PATHCONF3args (XDR *xdrs, PATHCONF3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->object))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_PATHCONF3resok (XDR *xdrs, PATHCONF3resok *objp)
+{
+ register int32_t *buf;
+
+
+ if (xdrs->x_op == XDR_ENCODE) {
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->name_max))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_bool (xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ IXDR_PUT_BOOL(buf, objp->no_trunc);
+ IXDR_PUT_BOOL(buf, objp->chown_restricted);
+ IXDR_PUT_BOOL(buf, objp->case_insensitive);
+ IXDR_PUT_BOOL(buf, objp->case_preserving);
+ }
+ return TRUE;
+ } else if (xdrs->x_op == XDR_DECODE) {
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->name_max))
+ return FALSE;
+ buf = XDR_INLINE (xdrs, 4 * BYTES_PER_XDR_UNIT);
+ if (buf == NULL) {
+ if (!xdr_bool (xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_preserving))
+ return FALSE;
+ } else {
+ objp->no_trunc = IXDR_GET_BOOL(buf);
+ objp->chown_restricted = IXDR_GET_BOOL(buf);
+ objp->case_insensitive = IXDR_GET_BOOL(buf);
+ objp->case_preserving = IXDR_GET_BOOL(buf);
+ }
+ return TRUE;
+ }
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->linkmax))
+ return FALSE;
+ if (!xdr_uint32 (xdrs, &objp->name_max))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->no_trunc))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->chown_restricted))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_insensitive))
+ return FALSE;
+ if (!xdr_bool (xdrs, &objp->case_preserving))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_PATHCONF3resfail (XDR *xdrs, PATHCONF3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_post_op_attr (xdrs, &objp->obj_attributes))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_PATHCONF3res (XDR *xdrs, PATHCONF3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_PATHCONF3resok (xdrs, &objp->PATHCONF3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_PATHCONF3resfail (xdrs, &objp->PATHCONF3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
+
+bool_t
+xdr_COMMIT3args (XDR *xdrs, COMMIT3args *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfs_fh3 (xdrs, &objp->file))
+ return FALSE;
+ if (!xdr_offset3 (xdrs, &objp->offset))
+ return FALSE;
+ if (!xdr_count3 (xdrs, &objp->count))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_COMMIT3resok (XDR *xdrs, COMMIT3resok *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ if (!xdr_writeverf3 (xdrs, objp->verf))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_COMMIT3resfail (XDR *xdrs, COMMIT3resfail *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_wcc_data (xdrs, &objp->file_wcc))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_COMMIT3res (XDR *xdrs, COMMIT3res *objp)
+{
+ register int32_t *buf;
+
+ if (!xdr_nfsstat3 (xdrs, &objp->status))
+ return FALSE;
+ switch (objp->status) {
+ case NFS3_OK:
+ if (!xdr_COMMIT3resok (xdrs, &objp->COMMIT3res_u.resok))
+ return FALSE;
+ break;
+ default:
+ if (!xdr_COMMIT3resfail (xdrs, &objp->COMMIT3res_u.resfail))
+ return FALSE;
+ break;
+ }
+ return TRUE;
+}
--
2.1.2