From c2c1b0cbdfc5788c1755f0fcf25ada2cc6c47858 Mon Sep 17 00:00:00 2001 From: Mathias Tillman 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 + Copyright(C) 2000 Alexander Neundorf , + 2014 Mathias Tillman 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 #include - -// This is needed on Solaris so that rpc.h defines clnttcp_create etc. -#ifndef PORTMAP -#define PORTMAP -#endif -#include // for rpc calls - -#include -#include -#include #include -#include -#include -#include -#include -#include -#include #include #include #include -#include +#include #include #include -#include - -#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: -"<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)<<"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: "<MAXFHAGE) checkForOldFHs(); - - stripTrailingSlash(path); - qCDebug(LOG_KIO_NFS)<<"getting FH for -"<= '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("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 -"<("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 -"<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: -"<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: -"<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: -"<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 -"< 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 -"<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 "<= '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 + Copyright (C) 2000 Alexander Neundorf , + 2014 Mathias Tillman 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 #include +#include #include #include #include #include #include +#include -#define PORTMAP //this seems to be required to compile on Solaris -#include -#include -#include -#include +#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 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 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 m_usercache; // maps long ==> QString * - QHash 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 - -/* - * 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; - -/* - * The type name is used for arbitrary names (hostnames, groupnames) - */ -typedef string name; - -/* - * 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 -#include -#include - -#include - -/* 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 - -/* - * 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; -typedef string nfspath; - -/* - * 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; -}; - -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; -}; - -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 -#include -#include - -#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 , + 2014 Mathias Tillman + + 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 + +#include + +// This is needed on Solaris so that rpc.h defines clnttcp_create etc. +#ifndef PORTMAP +#define PORTMAP +#endif +#include // for rpc calls + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#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(&readLinkArgs), + (xdrproc_t) xdr_readlinkres, reinterpret_cast(&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(&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(&exportlist->ex_dir), + (xdrproc_t) xdr_fhstatus, reinterpret_cast(&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(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(&listargs), + (xdrproc_t) xdr_readdirres, reinterpret_cast(&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(&createArgs), + (xdrproc_t) xdr_diropres, reinterpret_cast(&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(&readArgs), + (xdrproc_t) xdr_readres, reinterpret_cast(&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(&writeArgs), + (xdrproc_t) xdr_attrstat, reinterpret_cast(&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(&readArgs), + (xdrproc_t) xdr_readres, reinterpret_cast(&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(&writeArgs), + (xdrproc_t) xdr_attrstat, reinterpret_cast(&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(&readArgs), + (xdrproc_t) xdr_readres, reinterpret_cast(&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(&writeArgs), + (xdrproc_t) xdr_attrstat, reinterpret_cast(&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(&args), + (xdrproc_t) xdr_diropres, reinterpret_cast(&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(&fh), + (xdrproc_t) xdr_attrstat, reinterpret_cast(&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(&dirargs), + (xdrproc_t) xdr_diropres, reinterpret_cast(&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(&nfsFH), + (xdrproc_t) xdr_readlinkres, reinterpret_cast(&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(&dirargs), + (xdrproc_t) xdr_nfsstat, reinterpret_cast(&result), + clnt_timeout); + } else { + rpcStatus = clnt_call(m_nfsClient, NFSPROC_RMDIR, + (xdrproc_t) xdr_diropargs, reinterpret_cast(&dirargs), + (xdrproc_t) xdr_nfsstat, reinterpret_cast(&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(&renameArgs), + (xdrproc_t) xdr_nfsstat, reinterpret_cast(&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(&sAttrArgs), + (xdrproc_t) xdr_nfsstat, reinterpret_cast(&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(&symLinkArgs), + (xdrproc_t) xdr_nfsstat, reinterpret_cast(&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 , + 2014 Mathias Tillman + + 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 +#include +#include +#include + +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 m_usercache; + QHash 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 , + 2014 Mathias Tillman + + 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 + +#include + +// This is needed on Solaris so that rpc.h defines clnttcp_create etc. +#ifndef PORTMAP +#define PORTMAP +#endif +#include // for rpc calls + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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(&readLinkArgs), + (xdrproc_t) xdr_READLINK3res, reinterpret_cast(&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(&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(&exportlist->ex_dir), + (xdrproc_t) xdr_mountres3, reinterpret_cast(&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(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(&listargs), + (xdrproc_t) xdr_READDIRPLUS3res, reinterpret_cast(&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(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(&listargs), + (xdrproc_t) xdr_READDIR3res, reinterpret_cast(&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(&createArgs), + (xdrproc_t) xdr_MKDIR3res, reinterpret_cast(&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(&readArgs), + (xdrproc_t) xdr_READ3res, reinterpret_cast(&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(&writeArgs), + (xdrproc_t) xdr_WRITE3res, reinterpret_cast(&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(&readArgs), + (xdrproc_t) xdr_READ3res, reinterpret_cast(&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(&writeArgs), + (xdrproc_t) xdr_WRITE3res, reinterpret_cast(&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(&readArgs), + (xdrproc_t) xdr_READ3res, reinterpret_cast(&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(&writeArgs), + (xdrproc_t) xdr_WRITE3res, reinterpret_cast(&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(&fsArgs), + (xdrproc_t) xdr_FSINFO3res, reinterpret_cast(&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(&args), + (xdrproc_t) xdr_CREATE3res, reinterpret_cast(&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(&args), + (xdrproc_t) xdr_GETATTR3res, reinterpret_cast(&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(&args), + (xdrproc_t) xdr_LOOKUP3res, reinterpret_cast(&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(&readLinkArgs), + (xdrproc_t) xdr_READLINK3res, reinterpret_cast(&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(&args), + (xdrproc_t) xdr_REMOVE3res, reinterpret_cast(&result), + clnt_timeout); + } else { + rpcStatus = clnt_call(m_nfsClient, NFSPROC3_RMDIR, + (xdrproc_t) xdr_RMDIR3args, reinterpret_cast(&args), + (xdrproc_t) xdr_RMDIR3res, reinterpret_cast(&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(&args), + (xdrproc_t) xdr_RENAME3res, reinterpret_cast(&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(&setAttrArgs), + (xdrproc_t) xdr_SETATTR3res, reinterpret_cast(&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(&symLinkArgs), + (xdrproc_t) xdr_SYMLINK3res, reinterpret_cast(&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 , + 2014 Mathias Tillman + + 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 +#include +#include +#include + +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 m_usercache; + QHash 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 + + +#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; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name; + +/* + * 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 + + +#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 + + +#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; +typedef string nfspath; + +/* + * 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; +}; + +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; +}; + +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 + + +#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; +}; + +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; +typedef string dirpath; +typedef string name; + +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