diff --git a/0001-Port-comicbook-thumbnailer-to-KF5.patch b/0001-Port-comicbook-thumbnailer-to-KF5.patch new file mode 100644 index 0000000..2786b04 --- /dev/null +++ b/0001-Port-comicbook-thumbnailer-to-KF5.patch @@ -0,0 +1,181 @@ +From 92203bdebc4814ef27388ca0fdd6731f2abeab3d Mon Sep 17 00:00:00 2001 +From: Maarten De Meyer +Date: Sun, 28 Sep 2014 17:35:40 +0200 +Subject: [PATCH 1/5] Port comicbook thumbnailer to KF5 + +Mostly standard porting stuff. +Still need to change qdebug calls to qCDebug. +CCBUG: 339456 +REVIEW: 120382 + +(cherry picked from commit 72d25f79050f8cf249b0a640a2be8764c59eca91) +--- + CMakeLists.txt | 1 + + thumbnail/CMakeLists.txt | 22 +++++++++++++--------- + thumbnail/comiccreator.cpp | 41 +++++++++++++++++++---------------------- + 3 files changed, 33 insertions(+), 31 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 34c5fb9f2fe10bb53ab4f1c7c09815494157c263..3d538d4e3f06620e61cbddc375bc4a9652671bf8 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -36,6 +36,7 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS + KIO + KHtml + KDE4Support ++ Pty + Solid + ) + +diff --git a/thumbnail/CMakeLists.txt b/thumbnail/CMakeLists.txt +index cd1263af2444e97b7c7d20f2a25899009db9af01..aec8b8ea9c86f6b8b650caf885c02117dbf014f0 100644 +--- a/thumbnail/CMakeLists.txt ++++ b/thumbnail/CMakeLists.txt +@@ -201,14 +201,18 @@ install(TARGETS svgthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) + # install ( FILES windowsimagethumbnail.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) + # + # ########### next target ############### +-# +-# set(comicbookthumbnail_SRCS comiccreator.cpp) +-# add_library(comicbookthumbnail MODULE ${comicbookthumbnail_SRCS}) +-# target_link_libraries(comicbookthumbnail ${KIO_LIBRARIES}) +-# if (UNIX) +-# target_link_libraries(comicbookthumbnail KF5::Pty) +-# endif () +-# install(TARGETS comicbookthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) ++ ++set(comicbookthumbnail_SRCS comiccreator.cpp) ++add_library(comicbookthumbnail MODULE ${comicbookthumbnail_SRCS}) ++target_link_libraries(comicbookthumbnail ++ Qt5::Gui ++ KF5::Archive ++ KF5::KIOWidgets ++) ++if (UNIX) ++ target_link_libraries(comicbookthumbnail KF5::Pty) ++endif () ++install(TARGETS comicbookthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) + + ########### install files ############### + +@@ -222,5 +226,5 @@ install(FILES + # htmlthumbnail.desktop + # djvuthumbnail.desktop + # desktopthumbnail.desktop +-# comicbookthumbnail.desktop ++ comicbookthumbnail.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) +diff --git a/thumbnail/comiccreator.cpp b/thumbnail/comiccreator.cpp +index 39df58a4ddc1de3d79cdb0766fc0b11c02c9ec2d..4ec0db8c6953e2d9983e4a9d7f542b27404175e4 100644 +--- a/thumbnail/comiccreator.cpp ++++ b/thumbnail/comiccreator.cpp +@@ -29,23 +29,22 @@ + + #include "comiccreator.h" + +-#include +-#include +-#include +- + #include + #include + #include +-#include + #include + + #include + + #include + #include ++#include ++#include + #include ++#include + + // For KIO-Thumbnail debug outputs ++// TODO KF5 qCDebug + #define KIO_THUMB 11371 + + extern "C" +@@ -66,23 +65,25 @@ bool ComicCreator::create(const QString& path, int width, int height, QImage& im + QImage cover; + + // Detect mime type. +- const KMimeType::Ptr mime = KMimeType::findByFileContent(path); ++ QMimeDatabase db; ++ db.mimeTypeForFile(path, QMimeDatabase::MatchContent); ++ const QMimeType mime = db.mimeTypeForFile(path, QMimeDatabase::MatchContent); + +- if (mime->is("application/x-cbz") || mime->name() == "application/zip") { ++ if (mime.inherits("application/x-cbz") || mime.inherits("application/zip")) { + // ZIP archive. + cover = extractArchiveImage(path, ZIP); +- } else if (mime->is("application/x-cbt") || +- mime->name() == "application/x-gzip" || +- mime->name() == "application/x-tar") { ++ } else if (mime.inherits("application/x-cbt") || ++ mime.inherits("application/x-gzip") || ++ mime.inherits("application/x-tar")) { + // TAR archive + cover = extractArchiveImage(path, TAR); +- } else if (mime->is("application/x-cbr") || mime->name() == "application/x-rar") { ++ } else if (mime.inherits("application/x-cbr") || mime.inherits("application/x-rar")) { + // RAR archive. + cover = extractRARImage(path); + } + + if (cover.isNull()) { +- kDebug(KIO_THUMB)<<"Error creating the comic book thumbnail."; ++ qDebug()<<"Error creating the comic book thumbnail."; + return false; + } + +@@ -178,7 +179,7 @@ QImage ComicCreator::extractRARImage(const QString& path) + // Check if unrar is available. Get its path in 'unrarPath'. + QString unrar = unrarPath(); + if (unrar.isEmpty()) { +- kDebug(KIO_THUMB)<<"A suitable version of unrar is not available."; ++ qDebug()<<"A suitable version of unrar is not available."; + return QImage(); + } + +@@ -195,14 +196,12 @@ QImage ComicCreator::extractRARImage(const QString& path) + + // Extract the cover file alone. Use verbose paths. + // unrar x -n path/to/archive /path/to/temp +- KTempDir cUnrarTempDir; +- startProcess(unrar, QStringList() << "x" << "-n" + entries[0] << path << cUnrarTempDir.name()); ++ QTemporaryDir cUnrarTempDir; ++ startProcess(unrar, QStringList() << "x" << "-n" + entries[0] << path << cUnrarTempDir.path()); + + // Load cover file data into image. + QImage cover; +- cover.load(cUnrarTempDir.name() + entries[0]); +- +- cUnrarTempDir.unlink(); ++ cover.load(cUnrarTempDir.path() + QDir::separator() + entries[0]); + + return cover; + } +@@ -223,10 +222,10 @@ QString ComicCreator::unrarPath() const + /// Check the standard paths to see if a suitable unrar is available. + QString unrar = QStandardPaths::findExecutable("unrar"); + if (unrar.isEmpty()) { +- unrar = KStandardDirs::findExe("unrar-nonfree"); ++ unrar = QStandardPaths::findExecutable("unrar-nonfree"); + } + if (unrar.isEmpty()) { +- unrar = KStandardDirs::findExe("rar"); ++ unrar = QStandardPaths::findExecutable("rar"); + } + if (!unrar.isEmpty()) { + QProcess proc; +@@ -313,5 +312,3 @@ ThumbCreator::Flags ComicCreator::flags() const + { + return DrawFrame; + } +- +-#include "comiccreator.moc" +-- +2.1.2 + diff --git a/0002-Port-textcreator-thumbnailer.patch b/0002-Port-textcreator-thumbnailer.patch new file mode 100644 index 0000000..71b8bcd --- /dev/null +++ b/0002-Port-textcreator-thumbnailer.patch @@ -0,0 +1,127 @@ +From 47777a2631fb09eb930e80015e447037b4467ce7 Mon Sep 17 00:00:00 2001 +From: Maarten De Meyer +Date: Mon, 29 Sep 2014 00:32:20 +0200 +Subject: [PATCH 2/5] Port textcreator thumbnailer + +Thumbcreator needs to be a QGuiApplication because we use pixmaps. +CCBUG: 339456 +REVIEW: 120408 + +(cherry picked from commit 7cadf8888ec1b02e30512a44c1bae76202f30f96) +--- + thumbnail/CMakeLists.txt | 25 ++++++++++++++----------- + thumbnail/textcreator.cpp | 14 +++++++------- + thumbnail/thumbnail.cpp | 2 +- + 3 files changed, 22 insertions(+), 19 deletions(-) + +diff --git a/thumbnail/CMakeLists.txt b/thumbnail/CMakeLists.txt +index aec8b8ea9c86f6b8b650caf885c02117dbf014f0..4c2d5e9cab7c500d2d29a5ad479b7dfb514de85c 100644 +--- a/thumbnail/CMakeLists.txt ++++ b/thumbnail/CMakeLists.txt +@@ -107,16 +107,19 @@ target_link_libraries(svgthumbnail + + install(TARGETS svgthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) + +-# ########### next target ############### +-# +-# set(textthumbnail_PART_SRCS textcreator.cpp) +-# +-# add_library(textthumbnail MODULE ${textthumbnail_PART_SRCS}) +-# +-# target_link_libraries(textthumbnail ${KIO_LIBRARIES}) +-# +-# install(TARGETS textthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) +-# ++########### next target ############### ++ ++set(textthumbnail_PART_SRCS textcreator.cpp) ++ ++add_library(textthumbnail MODULE ${textthumbnail_PART_SRCS}) ++ ++target_link_libraries(textthumbnail ++ Qt5::Gui ++ KF5::KIOWidgets ++) ++ ++install(TARGETS textthumbnail DESTINATION ${PLUGIN_INSTALL_DIR}) ++ + # ########### next target ############### + # + # if(NOT WINCE) +@@ -222,7 +225,7 @@ install(FILES + svgthumbnail.desktop + imagethumbnail.desktop + jpegthumbnail.desktop +-# textthumbnail.desktop ++ textthumbnail.desktop + # htmlthumbnail.desktop + # djvuthumbnail.desktop + # desktopthumbnail.desktop +diff --git a/thumbnail/textcreator.cpp b/thumbnail/textcreator.cpp +index d3f633ced1bd780c6e8ce53464fc1607e1ed1795..7c0263c8e8cb4f88d1429b5714c51c2939d817f0 100644 +--- a/thumbnail/textcreator.cpp ++++ b/thumbnail/textcreator.cpp +@@ -21,16 +21,15 @@ + #include "textcreator.h" + + #include ++#include + #include + #include + #include + #include + #include + +- +-#include +-#include +-#include ++// TODO Fix or remove kencodingprober code ++// #include + + extern "C" + { +@@ -60,7 +59,7 @@ static QTextCodec *codecFromContent(const char *data, int dataSize) + #else + QByteArray ba = QByteArray::fromRawData(data, dataSize); + // try to detect UTF text, fall back to locale default (which is usually UTF-8) +- return QTextCodec::codecForUtfText(ba, KGlobal::locale()->codecForEncoding()); ++ return QTextCodec::codecForUtfText(ba, QTextCodec::codecForLocale()); + #endif + } + +@@ -84,7 +83,8 @@ bool TextCreator::create(const QString &path, int width, int height, QImage &img + int yborder = 1 + pixmapSize.height()/16; // minimum y-border + + // this font is supposed to look good at small sizes +- QFont font = KGlobalSettings::smallestReadableFont(); ++ QFont font = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont); ++ + font.setPixelSize( qMax(7, qMin( 10, ( pixmapSize.height() - 2 * yborder ) / 16 ) ) ); + QFontMetrics fm( font ); + +@@ -121,7 +121,7 @@ bool TextCreator::create(const QString &path, int width, int height, QImage &img + foreach ( const QString &line, textLines ) { + QString trimmedLine = line.trimmed(); + if ( trimmedLine.contains( '\t' ) || trimmedLine.contains( " " ) ) { +- font.setFamily( KGlobalSettings::fixedFont().family() ); ++ font.setFamily( QFontDatabase::systemFont(QFontDatabase::FixedFont).family()); + break; + } + } +diff --git a/thumbnail/thumbnail.cpp b/thumbnail/thumbnail.cpp +index 3a38dc916c33243a23e5e3cb9a69a88eb49e30b0..d4a7f35014af21fb1dacaea59128ac7373e6805b 100644 +--- a/thumbnail/thumbnail.cpp ++++ b/thumbnail/thumbnail.cpp +@@ -118,7 +118,7 @@ extern "C" Q_DECL_EXPORT int kdemain( int argc, char **argv ) + // and HTML previews need even KApplication :( + putenv(strdup("SESSION_MANAGER=")); + +- QCoreApplication app( argc, argv); ++ QGuiApplication app(argc, argv); + #endif + + +-- +2.1.2 + diff --git a/0003-don-t-screw-up-the-filenames.patch b/0003-don-t-screw-up-the-filenames.patch new file mode 100644 index 0000000..ec08cab --- /dev/null +++ b/0003-don-t-screw-up-the-filenames.patch @@ -0,0 +1,30 @@ +From 92bbcc70d6aa753757c38bb8747f48e9218bacfc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= +Date: Wed, 8 Oct 2014 21:50:27 +0200 +Subject: [PATCH 3/5] don't screw up the filenames + +save in hex format, just like KIO::filePreview does and what's +mandated by the thumbnail spec: +http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#THUMBSAVE + +(cherry picked from commit 9ddd3441cfca384d73a57ca560bddb19410e460a) +--- + thumbnail/thumbnail.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/thumbnail/thumbnail.cpp b/thumbnail/thumbnail.cpp +index d4a7f35014af21fb1dacaea59128ac7373e6805b..39e8de58d6312cc2ee4eab141470bd88bede809e 100644 +--- a/thumbnail/thumbnail.cpp ++++ b/thumbnail/thumbnail.cpp +@@ -711,7 +711,7 @@ bool ThumbnailProtocol::createSubThumbnail(QImage& thumbnail, const QString& fil + int cacheSize = 0; + QCryptographicHash md5(QCryptographicHash::Md5); + md5.addData(QFile::encodeName(fileName.url())); +- const QString thumbName = QFile::encodeName(md5.result()) + ".png"; ++ const QString thumbName = QFile::encodeName(md5.result().toHex()) + ".png"; + + if (m_thumbBasePath.isEmpty()) { + m_thumbBasePath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/thumbnails/"); +-- +2.1.2 + diff --git a/0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch b/0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch new file mode 100644 index 0000000..e4b9a9e --- /dev/null +++ b/0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch @@ -0,0 +1,16487 @@ +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 + diff --git a/0005-kio_sftp-Use-the-right-type-for-timeout_sec-and-time.patch b/0005-kio_sftp-Use-the-right-type-for-timeout_sec-and-time.patch new file mode 100644 index 0000000..554cfd9 --- /dev/null +++ b/0005-kio_sftp-Use-the-right-type-for-timeout_sec-and-time.patch @@ -0,0 +1,38 @@ +From b85ebdb74fd25916749e72f8db37c6f1818da62c Mon Sep 17 00:00:00 2001 +From: Raphael Kubo da Costa +Date: Thu, 30 Oct 2014 14:33:33 +0200 +Subject: [PATCH 5/5] kio_sftp: Use the right type for timeout_sec and + timeout_usec. + +libssh expects the values passed to the SSH_OPTIONS_TIMEOUT and +SSH_OPTIONS_TIMEOUT_USEC to be longs, not plain ints. + +On 64-bit platforms with sizeof(long) > sizeof(int), this mismatch can +be problematic and potentially result in invalid memory access that +causes the calls to ssh_options_set() to fail. + +Forward-ported from kde-runtime/3dc39e92d34b3612e90f7a0b34d5d845a7af0b72. + +CCBUG: 331674 +REVIEW: 120900 +(cherry picked from commit 3662f8beb435807a9ebc99ec722a877a5877b3fd) +--- + sftp/kio_sftp.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sftp/kio_sftp.cpp b/sftp/kio_sftp.cpp +index 2e0e825a1502f7b7f1c7e9c0c7548bb596cdb3f2..e6849b7f3e24a74cfdef8027edc1102cee7fd4b6 100644 +--- a/sftp/kio_sftp.cpp ++++ b/sftp/kio_sftp.cpp +@@ -528,7 +528,7 @@ bool sftpProtocol::sftpOpenConnection (const AuthInfo& info) + return false; + } + +- int timeout_sec = 30, timeout_usec = 0; ++ long timeout_sec = 30, timeout_usec = 0; + + kDebug(KIO_SFTP_DB) << "Creating the SSH session and setting options"; + +-- +2.1.2 + diff --git a/kio-extras-5.1.0.1.tar.xz b/kio-extras-5.1.0.1.tar.xz deleted file mode 100644 index c91677f..0000000 --- a/kio-extras-5.1.0.1.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d654a1d1a16194798ba9b1e64e526ff431636f0b710cb496268070559a23f49c -size 480740 diff --git a/kio-extras-5.1.1.tar.xz b/kio-extras-5.1.1.tar.xz new file mode 100644 index 0000000..755014b --- /dev/null +++ b/kio-extras-5.1.1.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a97b519bdb83a721c83732dee5fa72dc2116eb3e5a3eb1904d8f66fb6d0a1b15 +size 485648 diff --git a/kio-extras5.changes b/kio-extras5.changes index 9b2ec72..5b697aa 100644 --- a/kio-extras5.changes +++ b/kio-extras5.changes @@ -1,3 +1,25 @@ +------------------------------------------------------------------- +Thu Nov 6 20:14:13 UTC 2014 - hrvoje.senjan@gmail.com + +- Update to 5.1.1: + * Bugfix release + * For more details please see: + https://www.kde.org/announcements/plasma-5.1.1.php +- Added patches from upstream: + 0001-Port-comicbook-thumbnailer-to-KF5.patch, + 0002-Port-textcreator-thumbnailer.patch (kde#339456), + 0003-don-t-screw-up-the-filenames.patch, + 0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch + (kde#268797, kde#309113) + 0005-kio_sftp-Use-the-right-type-for-timeout_sec-and-time.patch + (kde#331674) +- Added kpty-devel BuildRequires + +------------------------------------------------------------------- +Sat Oct 25 17:31:33 UTC 2014 - hrvoje.senjan@gmail.com + +- Recommend lang subpackage + ------------------------------------------------------------------- Thu Oct 9 21:24:30 UTC 2014 - hrvoje.senjan@gmail.com diff --git a/kio-extras5.spec b/kio-extras5.spec index de10adb..83b1612 100644 --- a/kio-extras5.spec +++ b/kio-extras5.spec @@ -17,14 +17,24 @@ Name: kio-extras5 -Version: 5.1.0 +Version: 5.1.1 Release: 0 Summary: Additional KIO-slaves for KDE applications License: GPL-2.0+ Group: System/GUI/KDE Url: http://www.kde.org -Source: kio-extras-%{version}.1.tar.xz +Source: kio-extras-%{version}.tar.xz Source99: %{name}-rpmlintrc +# PATCH-FIX-UPSTREAM 0001-Port-comicbook-thumbnailer-to-KF5.patch +Patch0: 0001-Port-comicbook-thumbnailer-to-KF5.patch +# PATCH-FIX-UPSTREAM 0002-Port-textcreator-thumbnailer.patch +Patch1: 0002-Port-textcreator-thumbnailer.patch +# PATCH-FIX-UPSTREAM 0003-don-t-screw-up-the-filenames.patch +Patch2: 0003-don-t-screw-up-the-filenames.patch +# PATCH-FIX-UPSTREAM 0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch +Patch3: 0004-Added-support-for-NFSv3-major-refactoring-fixed-bugs.patch +# PATCH-FIX-UPSTREAM 0005-kio_sftp-Use-the-right-type-for-timeout_sec-and-time.patch +Patch4: 0005-kio_sftp-Use-the-right-type-for-timeout_sec-and-time.patch BuildRequires: OpenEXR-devel BuildRequires: karchive-devel BuildRequires: kconfig-devel @@ -39,6 +49,7 @@ BuildRequires: khtml-devel BuildRequires: ki18n-devel BuildRequires: kiconthemes-devel BuildRequires: kio-devel +BuildRequires: kpty-devel BuildRequires: libjpeg-devel BuildRequires: libssh-devel BuildRequires: openslp-devel @@ -56,6 +67,7 @@ BuildRequires: pkgconfig(smbclient) # we want some imageformats in Recommends: libqt5-qtimageformats Recommends: kimageformats +Recommends: %{name}-lang #BuildRequires: update-desktop-files Provides: kfileaudiopreview = 4.100.0 Obsoletes: kfileaudiopreview <= 4.100.0 @@ -67,6 +79,11 @@ Additional KIO-slaves for KDE applications. %lang_package %prep %setup -q -n kio-extras-%{version} +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 sed -i '/^add_subdirectory( doc )/d' CMakeLists.txt %build