diff options
Diffstat (limited to 'tdeioslave/nfs')
-rw-r--r-- | tdeioslave/nfs/AUTHORS | 2 | ||||
-rw-r--r-- | tdeioslave/nfs/CMakeLists.txt | 45 | ||||
-rw-r--r-- | tdeioslave/nfs/Makefile.am | 28 | ||||
-rw-r--r-- | tdeioslave/nfs/README | 3 | ||||
-rw-r--r-- | tdeioslave/nfs/TODO | 7 | ||||
-rw-r--r-- | tdeioslave/nfs/kio_nfs.cpp | 1615 | ||||
-rw-r--r-- | tdeioslave/nfs/kio_nfs.h | 109 | ||||
-rw-r--r-- | tdeioslave/nfs/mount.h | 325 | ||||
-rw-r--r-- | tdeioslave/nfs/mount.x | 255 | ||||
-rw-r--r-- | tdeioslave/nfs/mount_xdr.c | 335 | ||||
-rw-r--r-- | tdeioslave/nfs/nfs.protocol | 14 | ||||
-rw-r--r-- | tdeioslave/nfs/nfs_prot.h | 699 | ||||
-rw-r--r-- | tdeioslave/nfs/nfs_prot.x | 365 | ||||
-rw-r--r-- | tdeioslave/nfs/nfs_prot_xdr.c | 886 |
14 files changed, 4688 insertions, 0 deletions
diff --git a/tdeioslave/nfs/AUTHORS b/tdeioslave/nfs/AUTHORS new file mode 100644 index 000000000..062f9d6cb --- /dev/null +++ b/tdeioslave/nfs/AUTHORS @@ -0,0 +1,2 @@ +Written and maintained by: +Alexander Neundorf, neundorf@kde.org diff --git a/tdeioslave/nfs/CMakeLists.txt b/tdeioslave/nfs/CMakeLists.txt new file mode 100644 index 000000000..da9040fc9 --- /dev/null +++ b/tdeioslave/nfs/CMakeLists.txt @@ -0,0 +1,45 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES nfs.protocol DESTINATION ${SERVICES_INSTALL_DIR} ) + + +##### kio_nfs (module) ########################## + +set( target kio_nfs ) + +add_custom_command( OUTPUT mount_xdr.c + COMMAND rpcgen -c -o mount_xdr.c ${CMAKE_CURRENT_SOURCE_DIR}/mount.x + DEPENDS mount.x ) + +add_custom_command( OUTPUT nfs_prot_xdr.c + COMMAND rpcgen -c -o nfs_prot_xdr.c ${CMAKE_CURRENT_SOURCE_DIR}/nfs_prot.x + DEPENDS nfs_prot.x ) + +tde_add_kpart( ${target} AUTOMOC + SOURCES kio_nfs.cpp mount_xdr.c nfs_prot_xdr.c + LINK tdeio-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeioslave/nfs/Makefile.am b/tdeioslave/nfs/Makefile.am new file mode 100644 index 000000000..4ab02fc1d --- /dev/null +++ b/tdeioslave/nfs/Makefile.am @@ -0,0 +1,28 @@ +## Makefile.am of tdebase/tdeioslave/man + +INCLUDES= $(all_includes) +AM_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor + +####### Files + +kde_module_LTLIBRARIES = kio_nfs.la + +kio_nfs_la_SOURCES = kio_nfs.cpp mount_xdr.c nfs_prot_xdr.c +kio_nfs_la_LIBADD = -lkio $(LIBRPC) +kio_nfs_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +noinst_HEADERS = nfs_prot.h mount.h + +kdelnk_DATA = nfs.protocol +kdelnkdir = $(kde_servicesdir) + +METASOURCES = AUTO + +$(srcdir)/mount_xdr.c: $(srcdir)/mount.x + cd $(srcdir) && rpcgen ./mount.x + + +$(srcdir)/nfs_prot_xdr.c: $(srcdir)/nfs_prot.x + cd $(srcdir) && rpcgen ./nfs_prot.x + +messages: + $(XGETTEXT) *.cpp -o $(podir)/tdeio_nfs.pot diff --git a/tdeioslave/nfs/README b/tdeioslave/nfs/README new file mode 100644 index 000000000..671934e2c --- /dev/null +++ b/tdeioslave/nfs/README @@ -0,0 +1,3 @@ +this is an ioslave for KDE 2 for NFS, version 2. + +Alex diff --git a/tdeioslave/nfs/TODO b/tdeioslave/nfs/TODO new file mode 100644 index 000000000..6e5525127 --- /dev/null +++ b/tdeioslave/nfs/TODO @@ -0,0 +1,7 @@ +-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 + +Alex diff --git a/tdeioslave/nfs/kio_nfs.cpp b/tdeioslave/nfs/kio_nfs.cpp new file mode 100644 index 000000000..8148a7745 --- /dev/null +++ b/tdeioslave/nfs/kio_nfs.cpp @@ -0,0 +1,1615 @@ +/* This file is part of the KDE project + + Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org> + + 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. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/utsname.h> + +#include <arpa/inet.h> + +// This is needed on Solaris so that rpc.h defines clnttcp_create etc. +#ifndef PORTMAP +#define PORTMAP +#endif +#include <rpc/rpc.h> // for rpc calls + +#include <errno.h> +#include <grp.h> +#include <memory.h> +#include <netdb.h> +#include <pwd.h> +#include <stdlib.h> +#include <strings.h> +#include <stdio.h> +#include <time.h> +#include <unistd.h> + +#include <tqfile.h> +#include <tqdir.h> + +#include <kdebug.h> +#include <kinstance.h> +#include <klocale.h> + +#include <tdeio/global.h> +#include <iostream> + +#include "nfs_prot.h" +#define fhandle _fhandle +#include "mount.h" +#include "kio_nfs.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) + +using namespace TDEIO; +using namespace std; + +//this is taken from tdelibs/tdecore/fakes.cpp +//#if !defined(HAVE_GETDOMAINNAME) + +int x_getdomainname(char *name, size_t len) +{ + struct utsname uts; + struct hostent *hent; + int rv = -1; + + if (name == 0L) + errno = EINVAL; + else + { + name[0] = '\0'; + if (uname(&uts) >= 0) + { + if ((hent = gethostbyname(uts.nodename)) != 0L) + { + char *p = strchr(hent->h_name, '.'); + if (p != 0L) + { + ++p; + if (strlen(p) > len-1) + errno = EINVAL; + else + { + strcpy(name, p); + rv = 0; + } + } + } + } + } + return rv; +} +//#endif + + +extern "C" { int KDE_EXPORT kdemain(int argc, char **argv); } + +int kdemain( int argc, char **argv ) +{ + TDEInstance instance( "kio_nfs" ); + + if (argc != 4) + { + fprintf(stderr, "Usage: kio_nfs protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + kdDebug(7121) << "NFS: kdemain: starting" << endl; + + NFSProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + return 0; +} + +static bool isRoot(const TQString& path) +{ + return (path.isEmpty() || (path=="/")); +} + +static bool isAbsoluteLink(const TQString& path) +{ + //hmm, don't know + if (path.isEmpty()) return TRUE; + if (path[0]=='/') return TRUE; + return FALSE; +} + +static void createVirtualDirEntry(UDSEntry & entry) +{ + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFDIR; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_USER; + atom.m_str = "root"; + entry.append( atom ); + atom.m_uds = TDEIO::UDS_GROUP; + atom.m_str = "root"; + entry.append( atom ); + + //a dummy size + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = 1024; + entry.append( atom ); +} + + +static void stripTrailingSlash(TQString& path) +{ + //if (path=="/") return; + if (path=="/") path=""; + else if (path[path.length()-1]=='/') path.truncate(path.length()-1); +} + +static void getLastPart(const TQString& path, TQString& lastPart, TQString& rest) +{ + int slashPos=path.findRev("/"); + lastPart=path.mid(slashPos+1); + rest=path.left(slashPos+1); +} + +static TQString removeFirstPart(const TQString& path) +{ + TQString result(""); + if (path.isEmpty()) return result; + result=path.mid(1); + int slashPos=result.find("/"); + return result.mid(slashPos+1); +} + +NFSFileHandle::NFSFileHandle() +:m_isInvalid(FALSE) +{ + memset(m_handle,'\0',NFS_FHSIZE+1); +// m_detectTime=time(0); +} + +NFSFileHandle::NFSFileHandle(const NFSFileHandle & handle) +:m_isInvalid(FALSE) +{ + m_handle[NFS_FHSIZE]='\0'; + memcpy(m_handle,handle.m_handle,NFS_FHSIZE); + m_isInvalid=handle.m_isInvalid; +// m_detectTime=handle.m_detectTime; +} + +NFSFileHandle::~NFSFileHandle() +{} + +NFSFileHandle& NFSFileHandle::operator= (const NFSFileHandle& src) +{ + memcpy(m_handle,src.m_handle,NFS_FHSIZE); + m_isInvalid=src.m_isInvalid; +// m_detectTime=src.m_detectTime; + return *this; +} + +NFSFileHandle& NFSFileHandle::operator= (const char* src) +{ + if (src==0) + { + m_isInvalid=TRUE; + return *this; + }; + memcpy(m_handle,src,NFS_FHSIZE); + m_isInvalid=FALSE; +// m_detectTime=time(0); + return *this; +} + +/*time_t NFSFileHandle::age() const +{ + return (time(0)-m_detectTime); +}*/ + + +NFSProtocol::NFSProtocol (const TQCString &pool, const TQCString &app ) +:SlaveBase( "nfs", pool, app ) +,m_client(0) +,m_sock(-1) +,m_lastCheck(time(0)) +{ + kdDebug(7121)<<"NFS::NFS: -"<<pool<<"-"<<endl; +} + +NFSProtocol::~NFSProtocol() +{ + 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() +{ + kdDebug(7121)<<"checking for fhs older than "<<MAXFHAGE<<endl; + kdDebug(7121)<<"current items: "<<m_handleCache.count()<<endl; + NFSFileHandleMap::Iterator it=m_handleCache.begin(); + NFSFileHandleMap::Iterator lastIt=it; + while (it!=m_handleCache.end()) + { + kdDebug(7121)<<it.data().age()<<flush; + if (it.data().age()>MAXFHAGE) + { + kdDebug(7121)<<"removing"<<endl; + m_handleCache.remove(it); + if (it==lastIt) + { + it=m_handleCache.begin(); + lastIt=it; + } + else + it=lastIt; + } + lastIt=it; + it++; + }; + kdDebug(7121)<<"left items: "<<m_handleCache.count()<<endl; + m_lastCheck=time(0); +}*/ + +void NFSProtocol::closeConnection() +{ + close(m_sock); + m_sock=-1; + if (m_client==0) return; + CLNT_DESTROY(m_client); + + m_client=0; +} + +bool NFSProtocol::isExportedDir(const TQString& path) +{ + return (m_exportedDirs.find(path.mid(1))!=m_exportedDirs.end()); +} + +/* This one works recursive. + It tries to get the file handle out of the file handle cache. + If this doesn't succeed, it needs to do a nfs rpc call + in order to obtain one. + */ +NFSFileHandle NFSProtocol::getFileHandle(TQString path) +{ + if (m_client==0) openConnection(); + + //I'm not sure if this is useful + //if ((time(0)-m_lastCheck)>MAXFHAGE) checkForOldFHs(); + + stripTrailingSlash(path); + kdDebug(7121)<<"getting FH for -"<<path<<"-"<<endl; + //now the path looks like "/root/some/dir" or "" if it was "/" + NFSFileHandle parentFH; + //we didn't find it + if (path.isEmpty()) + { + kdDebug(7121)<<"path is empty, invalidating the FH"<<endl; + parentFH.setInvalid(); + return parentFH; + } + //check wether we have this filehandle cached + //the filehandles of the exported root dirs are always in the cache + if (m_handleCache.find(path)!=m_handleCache.end()) + { + kdDebug(7121)<<"path is in the cache, returning the FH -"<<m_handleCache[path]<<"-"<<endl; + return m_handleCache[path]; + } + TQString rest, lastPart; + getLastPart(path,lastPart,rest); + kdDebug(7121)<<"splitting path into rest -"<<rest<<"- and lastPart -"<<lastPart<<"-"<<endl; + + parentFH=getFileHandle(rest); + //f*ck, it's invalid + if (parentFH.isInvalid()) + { + kdDebug(7121)<<"the parent FH is invalid"<<endl; + return parentFH; + } + // do the rpc call + diropargs dirargs; + diropres dirres; + memcpy(dirargs.dir.data,(const char*)parentFH,NFS_FHSIZE); + TQCString tmpStr=TQFile::encodeName(lastPart); + dirargs.name=tmpStr.data(); + + //cerr<<"calling rpc: FH: -"<<parentFH<<"- with name -"<<dirargs.name<<"-"<<endl; + + int clnt_stat = clnt_call(m_client, NFSPROC_LOOKUP, + (xdrproc_t) xdr_diropargs, (char*)&dirargs, + (xdrproc_t) xdr_diropres, (char*)&dirres,total_timeout); + + if ((clnt_stat!=RPC_SUCCESS) || (dirres.status!=NFS_OK)) + { + //we failed + kdDebug(7121)<<"lookup of filehandle failed"<<endl; + parentFH.setInvalid(); + return parentFH; + } + //everything went fine up to now :-) + parentFH=dirres.diropres_u.diropres.file.data; + //kdDebug(7121)<<"filesize: "<<dirres.diropres_u.diropres.attributes.size<<endl; + m_handleCache.insert(path,parentFH); + kdDebug(7121)<<"return FH -"<<parentFH<<"-"<<endl; + return parentFH; +} + +/* Open connection connects to the mount daemon on the server side. + In order to do this it needs authentication and calls auth_unix_create(). + Then it asks the mount daemon for the exported shares. Then it tries + to mount all these shares. If this succeeded for at least one of them, + a client for the nfs daemon is created. + */ +void NFSProtocol::openConnection() +{ + kdDebug(7121)<<"NFS::openConnection for -" << m_currentHost.latin1() << "-" << endl; + if (m_currentHost.isEmpty()) + { + error(ERR_UNKNOWN_HOST,""); + return; + } + struct sockaddr_in server_addr; + if (m_currentHost[0] >= '0' && m_currentHost[0] <= '9') + { + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(m_currentHost.latin1()); + } + else + { + struct hostent *hp=gethostbyname(m_currentHost.latin1()); + if (hp==0) + { + error( ERR_UNKNOWN_HOST, m_currentHost.latin1() ); + return; + } + server_addr.sin_family = AF_INET; + memcpy(&server_addr.sin_addr, hp->h_addr, hp->h_length); + } + + // create mount deamon client + closeConnection(); + server_addr.sin_port = 0; + m_sock = RPC_ANYSOCK; + m_client=clnttcp_create(&server_addr,MOUNTPROG, MOUNTVERS, &m_sock, 0, 0); + if (m_client==0) + { + server_addr.sin_port = 0; + m_sock = RPC_ANYSOCK; + pertry_timeout.tv_sec = 3; + pertry_timeout.tv_usec = 0; + m_client = clntudp_create(&server_addr,MOUNTPROG, MOUNTVERS, pertry_timeout, &m_sock); + if (m_client==0) + { + clnt_pcreateerror(const_cast<char *>("mount clntudp_create")); + error(ERR_COULD_NOT_CONNECT, m_currentHost.latin1()); + return; + } + } + TQCString hostName("localhost"); + char nameBuffer[1024]; + nameBuffer[0] = '\0'; + if (gethostname(nameBuffer, 1024)==0) + { + nameBuffer[sizeof(nameBuffer)-1] = '\0'; + hostName=nameBuffer; + // I have the same problem here as Stefan Westerfeld, that's why I use + // the getdomainname() from fakes.cpp (renamed to x_getdomainname()), this one works + // taken from tdelibs/arts/mcopy/mcoputils.cc + nameBuffer[0] = '\0'; + if (x_getdomainname(nameBuffer, 1024)==0) + { + nameBuffer[sizeof(nameBuffer)-1] = '\0'; + /* + * I don't know why, but on my linux machine, the domainname + * always ends up being (none), which is certainly no valid + * domainname + */ + if(strcmp(nameBuffer,"(none)") != 0) { + hostName += "."; + hostName += nameBuffer; + } + } + } + kdDebug(7121) << "hostname is -" << hostName << "-" << endl; + m_client->cl_auth = authunix_create(hostName.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.latin1())) return; + + fhstatus fhStatus; + bool atLeastOnceSucceeded(FALSE); + for(; exportlist!=0;exportlist = exportlist->ex_next) { + kdDebug(7121) << "found export: " << exportlist->ex_dir << endl; + + 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; + TQString fname; + if ( exportlist->ex_dir[0] == '/' ) + fname = TDEIO::encodeFileName(exportlist->ex_dir + 1); + else + fname = TDEIO::encodeFileName(exportlist->ex_dir); + m_handleCache.insert(TQString("/")+fname,fh); + m_exportedDirs.append(fname); + // kdDebug() <<"appending file -"<<fname<<"- with FH: -"<<fhStatus.fhstatus_u.fhs_fhandle<<"-"<<endl; + } + } + if (!atLeastOnceSucceeded) + { + closeConnection(); + error( ERR_COULD_NOT_AUTHENTICATE, m_currentHost.latin1()); + return; + } + server_addr.sin_port = 0; + + //now create the client for the nfs daemon + //first get rid of the old one + closeConnection(); + m_sock = RPC_ANYSOCK; + m_client = clnttcp_create(&server_addr,NFSPROG,NFSVERS,&m_sock,0,0); + if (m_client == 0) + { + server_addr.sin_port = 0; + m_sock = RPC_ANYSOCK; + pertry_timeout.tv_sec = 3; + pertry_timeout.tv_usec = 0; + m_client = clntudp_create(&server_addr,NFSPROG, NFSVERS, pertry_timeout, &m_sock); + if (m_client==0) + { + clnt_pcreateerror(const_cast<char *>("NFS clntudp_create")); + error(ERR_COULD_NOT_CONNECT, m_currentHost.latin1()); + return; + } + } + m_client->cl_auth = authunix_create(hostName.data(),geteuid(),getegid(),0,0); + connected(); + kdDebug(7121)<<"openConnection succeeded"<<endl; +} + +void NFSProtocol::listDir( const KURL& _url) +{ + KURL url(_url); + TQString path( TQFile::encodeName(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)) + { + kdDebug(7121)<<"listing root"<<endl; + totalSize( m_exportedDirs.count()); + //in this case we don't need to do a real listdir + UDSEntry entry; + for (TQStringList::Iterator it=m_exportedDirs.begin(); it!=m_exportedDirs.end(); it++) + { + UDSAtom atom; + entry.clear(); + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = (*it); + kdDebug(7121)<<"listing "<<(*it)<<endl; + entry.append( atom ); + createVirtualDirEntry(entry); + listEntry( entry, false); + } + listEntry( entry, true ); // ready + finished(); + return; + } + + TQStringList filesToList; + kdDebug(7121)<<"getting subdir -"<<path<<"-"<<endl; + stripTrailingSlash(path); + NFSFileHandle fh=getFileHandle(path); + //cerr<<"this is the fh: -"<<fh<<"-"<<endl; + if (fh.isInvalid()) + { + error( ERR_DOES_NOT_EXIST, path); + return; + } + readdirargs listargs; + memset(&listargs,0,sizeof(listargs)); + listargs.count=1024*16; + memcpy(listargs.dir.data,fh,NFS_FHSIZE); + readdirres listres; + do + { + memset(&listres,'\0',sizeof(listres)); + 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 ((TQString(".")!=dirEntry->name) && (TQString("..")!=dirEntry->name)) + filesToList.append(dirEntry->name); + } + } while (!listres.readdirres_u.reply.eof); + totalSize( filesToList.count()); + + UDSEntry entry; + //stat all files in filesToList + for (TQStringList::Iterator it=filesToList.begin(); it!=filesToList.end(); it++) + { + UDSAtom atom; + diropargs dirargs; + diropres dirres; + memcpy(dirargs.dir.data,fh,NFS_FHSIZE); + TQCString tmpStr=TQFile::encodeName(*it); + dirargs.name=tmpStr.data(); + + kdDebug(7121)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-"<<endl; + + int clnt_stat= clnt_call(m_client, NFSPROC_LOOKUP, + (xdrproc_t) xdr_diropargs, (char*)&dirargs, + (xdrproc_t) xdr_diropres, (char*)&dirres,total_timeout); + if (!checkForError(clnt_stat,dirres.status,(*it))) return; + + NFSFileHandle tmpFH; + tmpFH=dirres.diropres_u.diropres.file.data; + m_handleCache.insert(path+"/"+(*it),tmpFH); + + entry.clear(); + + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = (*it); + entry.append( atom ); + + //is it a symlink ? + if (S_ISLNK(dirres.diropres_u.diropres.attributes.mode)) + { + kdDebug(7121)<<"it's a symlink !"<<endl; + //cerr<<"fh: "<<tmpFH<<endl; + nfs_fh nfsFH; + memcpy(nfsFH.data,dirres.diropres_u.diropres.file.data,NFS_FHSIZE); + //get the link dest + readlinkres readLinkRes; + char nameBuf[NFS_MAXPATHLEN]; + readLinkRes.readlinkres_u.data=nameBuf; + int clnt_stat=clnt_call(m_client, NFSPROC_READLINK, + (xdrproc_t) xdr_nfs_fh, (char*)&nfsFH, + (xdrproc_t) xdr_readlinkres, (char*)&readLinkRes,total_timeout); + if (!checkForError(clnt_stat,readLinkRes.status,(*it))) return; + kdDebug(7121)<<"link dest is -"<<readLinkRes.readlinkres_u.data<<"-"<<endl; + TQCString linkDest(readLinkRes.readlinkres_u.data); + atom.m_uds = TDEIO::UDS_LINK_DEST; + atom.m_str = linkDest; + entry.append( atom ); + + bool isValid=isValidLink(path,linkDest); + if (!isValid) + { + completeBadLinkUDSEntry(entry,dirres.diropres_u.diropres.attributes); + } + else + { + if (isAbsoluteLink(linkDest)) + { + completeAbsoluteLinkUDSEntry(entry,linkDest); + } + else + { + tmpStr=TQDir::cleanDirPath(path+TQString("/")+TQString(linkDest)).latin1(); + dirargs.name=tmpStr.data(); + tmpFH=getFileHandle(tmpStr); + memcpy(dirargs.dir.data,tmpFH,NFS_FHSIZE); + + attrstat attrAndStat; + + kdDebug(7121)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-"<<endl; + + clnt_stat = clnt_call(m_client, NFSPROC_GETATTR, + (xdrproc_t) xdr_diropargs, (char*)&dirargs, + (xdrproc_t) xdr_attrstat, (char*)&attrAndStat,total_timeout); + if (!checkForError(clnt_stat,attrAndStat.status,tmpStr)) return; + completeUDSEntry(entry,attrAndStat.attrstat_u.attributes); + } + } + } + else + completeUDSEntry(entry,dirres.diropres_u.diropres.attributes); + listEntry( entry, false); + } + listEntry( entry, true ); // ready + finished(); +} + +void NFSProtocol::stat( const KURL & url) +{ + TQString path( TQFile::encodeName(url.path())); + stripTrailingSlash(path); + kdDebug(7121)<<"NFS::stat for -"<<path<<"-"<<endl; + TQString tmpPath=path; + if ((tmpPath.length()>1) && (tmpPath[0]=='/')) tmpPath=tmpPath.mid(1); + // We can't stat root, but we know it's a dir + if (isRoot(path) || isExportedDir(path)) + { + UDSEntry entry; + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = path; + entry.append( atom ); + createVirtualDirEntry(entry); + // no size + statEntry( entry ); + finished(); + kdDebug(7121)<<"succeeded"<<endl; + 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); + TQCString tmpStr=TQFile::encodeName(path); + dirargs.name=tmpStr.data(); + + kdDebug(7121)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-"<<endl; + + int clnt_stat = clnt_call(m_client, NFSPROC_GETATTR, + (xdrproc_t) xdr_diropargs, (char*)&dirargs, + (xdrproc_t) xdr_attrstat, (char*)&attrAndStat,total_timeout); + if (!checkForError(clnt_stat,attrAndStat.status,path)) return; + UDSEntry entry; + entry.clear(); + + UDSAtom atom; + + TQString fileName, parentDir; + getLastPart(path, fileName, parentDir); + stripTrailingSlash(parentDir); + + atom.m_uds = TDEIO::UDS_NAME; + atom.m_str = fileName; + entry.append( atom ); + + //is it a symlink ? + if (S_ISLNK(attrAndStat.attrstat_u.attributes.mode)) + { + kdDebug(7121)<<"it's a symlink !"<<endl; + nfs_fh nfsFH; + memcpy(nfsFH.data,fh,NFS_FHSIZE); + //get the link dest + readlinkres readLinkRes; + char nameBuf[NFS_MAXPATHLEN]; + readLinkRes.readlinkres_u.data=nameBuf; + + int clnt_stat=clnt_call(m_client, NFSPROC_READLINK, + (xdrproc_t) xdr_nfs_fh, (char*)&nfsFH, + (xdrproc_t) xdr_readlinkres, (char*)&readLinkRes,total_timeout); + if (!checkForError(clnt_stat,readLinkRes.status,path)) return; + kdDebug(7121)<<"link dest is -"<<readLinkRes.readlinkres_u.data<<"-"<<endl; + TQCString linkDest(readLinkRes.readlinkres_u.data); + atom.m_uds = TDEIO::UDS_LINK_DEST; + atom.m_str = linkDest; + entry.append( atom ); + + bool isValid=isValidLink(parentDir,linkDest); + if (!isValid) + { + completeBadLinkUDSEntry(entry,attrAndStat.attrstat_u.attributes); + } + else + { + if (isAbsoluteLink(linkDest)) + { + completeAbsoluteLinkUDSEntry(entry,linkDest); + } + else + { + + tmpStr=TQDir::cleanDirPath(parentDir+TQString("/")+TQString(linkDest)).latin1(); + diropargs dirargs; + dirargs.name=tmpStr.data(); + NFSFileHandle tmpFH; + tmpFH=getFileHandle(tmpStr); + memcpy(dirargs.dir.data,tmpFH,NFS_FHSIZE); + + kdDebug(7121)<<"calling rpc: FH: -"<<fh<<"- with name -"<<dirargs.name<<"-"<<endl; + clnt_stat = clnt_call(m_client, NFSPROC_GETATTR, + (xdrproc_t) xdr_diropargs, (char*)&dirargs, + (xdrproc_t) xdr_attrstat, (char*)&attrAndStat,total_timeout); + if (!checkForError(clnt_stat,attrAndStat.status,tmpStr)) return; + completeUDSEntry(entry,attrAndStat.attrstat_u.attributes); + } + } + } + else + completeUDSEntry(entry,attrAndStat.attrstat_u.attributes); + statEntry( entry ); + finished(); +} + +void NFSProtocol::completeAbsoluteLinkUDSEntry(UDSEntry& entry, const TQCString& path) +{ + //taken from file.cc + struct stat buff; + if ( ::stat( path.data(), &buff ) == -1 ) return; + + UDSAtom atom; + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = buff.st_mode & S_IFMT; // extract file type + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = buff.st_mode & 07777; // extract permissions + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = buff.st_size; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; + atom.m_long = buff.st_mtime; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_USER; + uid_t uid = buff.st_uid; + TQString *temp = m_usercache.find( uid ); + + if ( !temp ) + { + struct passwd *user = getpwuid( uid ); + if ( user ) + { + m_usercache.insert( uid, new TQString(TQString::fromLatin1(user->pw_name)) ); + atom.m_str = user->pw_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_GROUP; + gid_t gid = buff.st_gid; + temp = m_groupcache.find( gid ); + if ( !temp ) + { + struct group *grp = getgrgid( gid ); + if ( grp ) + { + m_groupcache.insert( gid, new TQString(TQString::fromLatin1(grp->gr_name)) ); + atom.m_str = grp->gr_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS_TIME; + atom.m_long = buff.st_atime; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_CREATION_TIME; + atom.m_long = buff.st_ctime; + entry.append( atom ); +} + +void NFSProtocol::completeBadLinkUDSEntry(UDSEntry& entry, fattr& attributes) +{ + // It is a link pointing to nowhere + completeUDSEntry(entry,attributes); + + UDSAtom atom; + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long = S_IFMT - 1; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = S_IRWXU | S_IRWXG | S_IRWXO; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = 0L; + entry.append( atom ); +} + +void NFSProtocol::completeUDSEntry(UDSEntry& entry, fattr& attributes) +{ + UDSAtom atom; + + atom.m_uds = TDEIO::UDS_SIZE; + atom.m_long = attributes.size; + entry.append(atom); + + atom.m_uds = TDEIO::UDS_MODIFICATION_TIME; + atom.m_long = attributes.mtime.seconds; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS_TIME; + atom.m_long = attributes.atime.seconds; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_CREATION_TIME; + atom.m_long = attributes.ctime.seconds; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_ACCESS; + atom.m_long = (attributes.mode & 07777); + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_FILE_TYPE; + atom.m_long =attributes.mode & S_IFMT; // extract file type + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_USER; + uid_t uid = attributes.uid; + TQString *temp = m_usercache.find( uid ); + if ( !temp ) + { + struct passwd *user = getpwuid( uid ); + if ( user ) + { + m_usercache.insert( uid, new TQString(user->pw_name) ); + atom.m_str = user->pw_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + + atom.m_uds = TDEIO::UDS_GROUP; + gid_t gid = attributes.gid; + temp = m_groupcache.find( gid ); + if ( !temp ) + { + struct group *grp = getgrgid( gid ); + if ( grp ) + { + m_groupcache.insert( gid, new TQString(grp->gr_name) ); + atom.m_str = grp->gr_name; + } + else + atom.m_str = "???"; + } + else + atom.m_str = *temp; + entry.append( atom ); + +/* TDEIO::UDSEntry::ConstIterator it = entry.begin(); + for( ; it != entry.end(); it++ ) { + switch ((*it).m_uds) { + case TDEIO::UDS_FILE_TYPE: + kdDebug(7121) << "File Type : " << (mode_t)((*it).m_long) << endl; + break; + case TDEIO::UDS_ACCESS: + kdDebug(7121) << "Access permissions : " << (mode_t)((*it).m_long) << endl; + break; + case TDEIO::UDS_USER: + kdDebug(7121) << "User : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_GROUP: + kdDebug(7121) << "Group : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_NAME: + kdDebug(7121) << "Name : " << ((*it).m_str.ascii() ) << endl; + //m_strText = decodeFileName( (*it).m_str ); + break; + case TDEIO::UDS_URL: + kdDebug(7121) << "URL : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_MIME_TYPE: + kdDebug(7121) << "MimeType : " << ((*it).m_str.ascii() ) << endl; + break; + case TDEIO::UDS_LINK_DEST: + kdDebug(7121) << "LinkDest : " << ((*it).m_str.ascii() ) << endl; + break; + } + }*/ +} + +void NFSProtocol::setHost(const TQString& host, int /*port*/, const TQString& /*user*/, const TQString& /*pass*/) +{ + kdDebug(7121)<<"setHost: -"<<host<<"-"<<endl; + if (host.isEmpty()) + { + error(ERR_UNKNOWN_HOST,""); + return; + } + if (host==m_currentHost) return; + m_currentHost=host; + m_handleCache.clear(); + m_exportedDirs.clear(); + closeConnection(); +} + +void NFSProtocol::mkdir( const KURL& url, int permissions ) +{ + kdDebug(7121)<<"mkdir"<<endl; + TQString thePath( TQFile::encodeName(url.path())); + stripTrailingSlash(thePath); + TQString dirName, parentDir; + getLastPart(thePath, dirName, parentDir); + stripTrailingSlash(parentDir); + kdDebug(7121)<<"path: -"<<thePath<<"- dir: -"<<dirName<<"- parentDir: -"<<parentDir<<"-"<<endl; + if (isRoot(parentDir)) + { + error(ERR_WRITE_ACCESS_DENIED,thePath); + return; + } + NFSFileHandle fh=getFileHandle(parentDir); + if (fh.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,thePath); + return; + } + + createargs createArgs; + memcpy(createArgs.where.dir.data,fh,NFS_FHSIZE); + TQCString tmpName=TQFile::encodeName(dirName); + createArgs.where.name=tmpName.data(); + if (permissions==-1) createArgs.attributes.mode=0755; + else createArgs.attributes.mode=permissions; + + diropres dirres; + + int clnt_stat = clnt_call(m_client, NFSPROC_MKDIR, + (xdrproc_t) xdr_createargs, (char*)&createArgs, + (xdrproc_t) xdr_diropres, (char*)&dirres,total_timeout); + if (!checkForError(clnt_stat,dirres.status,thePath)) return; + finished(); +} + +bool NFSProtocol::checkForError(int clientStat, int nfsStat, const TQString& text) +{ + if (clientStat!=RPC_SUCCESS) + { + kdDebug(7121)<<"rpc error: "<<clientStat<<endl; + //does this mapping make sense ? + error(ERR_CONNECTION_BROKEN,i18n("An RPC error occurred.")); + return FALSE; + } + if (nfsStat!=NFS_OK) + { + kdDebug(7121)<<"nfs error: "<<nfsStat<<endl; + switch (nfsStat) + { + case NFSERR_PERM: + error(ERR_ACCESS_DENIED,text); + break; + case NFSERR_NOENT: + error(ERR_DOES_NOT_EXIST,text); + break; + //does this mapping make sense ? + case NFSERR_IO: + error(ERR_INTERNAL_SERVER,text); + break; + //does this mapping make sense ? + case NFSERR_NXIO: + error(ERR_DOES_NOT_EXIST,text); + break; + case NFSERR_ACCES: + error(ERR_ACCESS_DENIED,text); + break; + case NFSERR_EXIST: + error(ERR_FILE_ALREADY_EXIST,text); + break; + //does this mapping make sense ? + case NFSERR_NODEV: + error(ERR_DOES_NOT_EXIST,text); + break; + case NFSERR_NOTDIR: + error(ERR_IS_FILE,text); + break; + case NFSERR_ISDIR: + error(ERR_IS_DIRECTORY,text); + break; + //does this mapping make sense ? + case NFSERR_FBIG: + error(ERR_INTERNAL_SERVER,text); + break; + //does this mapping make sense ? + case NFSERR_NOSPC: + error(ERR_INTERNAL_SERVER,i18n("No space left on device")); + break; + case NFSERR_ROFS: + error(ERR_COULD_NOT_WRITE,i18n("Read only file system")); + break; + case NFSERR_NAMETOOLONG: + error(ERR_INTERNAL_SERVER,i18n("Filename too long")); + break; + case NFSERR_NOTEMPTY: + error(ERR_COULD_NOT_RMDIR,text); + break; + //does this mapping make sense ? + case NFSERR_DQUOT: + error(ERR_INTERNAL_SERVER,i18n("Disk quota exceeded")); + break; + case NFSERR_STALE: + error(ERR_DOES_NOT_EXIST,text); + break; + default: + error(ERR_UNKNOWN,text); + break; + } + return FALSE; + } + return TRUE; +} + +void NFSProtocol::del( const KURL& url, bool isfile) +{ + TQString thePath( TQFile::encodeName(url.path())); + stripTrailingSlash(thePath); + + TQString fileName, parentDir; + getLastPart(thePath, fileName, parentDir); + stripTrailingSlash(parentDir); + kdDebug(7121)<<"del(): path: -"<<thePath<<"- file -"<<fileName<<"- parentDir: -"<<parentDir<<"-"<<endl; + if (isRoot(parentDir)) + { + error(ERR_ACCESS_DENIED,thePath); + return; + } + + NFSFileHandle fh=getFileHandle(parentDir); + if (fh.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,thePath); + return; + } + + if (isfile) + { + kdDebug(7121)<<"Deleting file "<<thePath<<endl; + diropargs dirOpArgs; + memcpy(dirOpArgs.dir.data,fh,NFS_FHSIZE); + TQCString tmpName=TQFile::encodeName(fileName); + dirOpArgs.name=tmpName.data(); + + nfsstat nfsStat; + + int clnt_stat = clnt_call(m_client, NFSPROC_REMOVE, + (xdrproc_t) xdr_diropargs, (char*)&dirOpArgs, + (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout); + if (!checkForError(clnt_stat,nfsStat,thePath)) return; + kdDebug(7121)<<"removing "<<thePath<<" from cache"<<endl; + m_handleCache.remove(m_handleCache.find(thePath)); + finished(); + } + else + { + kdDebug(7121)<<"Deleting directory "<<thePath<<endl; + diropargs dirOpArgs; + memcpy(dirOpArgs.dir.data,fh,NFS_FHSIZE); + TQCString tmpName=TQFile::encodeName(fileName); + dirOpArgs.name=tmpName.data(); + + nfsstat nfsStat; + + int clnt_stat = clnt_call(m_client, NFSPROC_RMDIR, + (xdrproc_t) xdr_diropargs, (char*)&dirOpArgs, + (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout); + if (!checkForError(clnt_stat,nfsStat,thePath)) return; + kdDebug(7121)<<"removing "<<thePath<<" from cache"<<endl; + m_handleCache.remove(m_handleCache.find(thePath)); + finished(); + } +} + +void NFSProtocol::chmod( const KURL& url, int permissions ) +{ + TQString thePath( TQFile::encodeName(url.path())); + stripTrailingSlash(thePath); + kdDebug( 7121 ) << "chmod -"<< thePath << "-"<<endl; + if (isRoot(thePath) || isExportedDir(thePath)) + { + error(ERR_ACCESS_DENIED,thePath); + return; + } + + NFSFileHandle fh=getFileHandle(thePath); + if (fh.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,thePath); + return; + } + + sattrargs sAttrArgs; + memcpy(sAttrArgs.file.data,fh,NFS_FHSIZE); + sAttrArgs.attributes.uid=(unsigned int)-1; + sAttrArgs.attributes.gid=(unsigned int)-1; + sAttrArgs.attributes.size=(unsigned int)-1; + sAttrArgs.attributes.atime.seconds=(unsigned int)-1; + sAttrArgs.attributes.atime.useconds=(unsigned int)-1; + sAttrArgs.attributes.mtime.seconds=(unsigned int)-1; + sAttrArgs.attributes.mtime.useconds=(unsigned int)-1; + + sAttrArgs.attributes.mode=permissions; + + nfsstat nfsStat; + + int clnt_stat = clnt_call(m_client, NFSPROC_SETATTR, + (xdrproc_t) xdr_sattrargs, (char*)&sAttrArgs, + (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout); + if (!checkForError(clnt_stat,nfsStat,thePath)) return; + + finished(); +} + +void NFSProtocol::get( const KURL& url ) +{ + TQString thePath( TQFile::encodeName(url.path())); + kdDebug(7121)<<"get() -"<<thePath<<"-"<<endl; + NFSFileHandle fh=getFileHandle(thePath); + if (fh.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,thePath); + return; + } + readargs readArgs; + memcpy(readArgs.file.data,fh,NFS_FHSIZE); + readArgs.offset=0; + readArgs.count=NFS_MAXDATA; + readArgs.totalcount=NFS_MAXDATA; + readres readRes; + int offset(0); + char buf[NFS_MAXDATA]; + readRes.readres_u.reply.data.data_val=buf; + + TQByteArray array; + do + { + int clnt_stat = clnt_call(m_client, NFSPROC_READ, + (xdrproc_t) xdr_readargs, (char*)&readArgs, + (xdrproc_t) xdr_readres, (char*)&readRes,total_timeout); + if (!checkForError(clnt_stat,readRes.status,thePath)) return; + if (readArgs.offset==0) + totalSize(readRes.readres_u.reply.attributes.size); + + offset=readRes.readres_u.reply.data.data_len; + //kdDebug(7121)<<"read "<<offset<<" bytes"<<endl; + readArgs.offset+=offset; + if (offset>0) + { + array.setRawData(readRes.readres_u.reply.data.data_val, offset); + data( array ); + array.resetRawData(readRes.readres_u.reply.data.data_val, offset); + + processedSize(readArgs.offset); + } + + } while (offset>0); + data( TQByteArray() ); + finished(); +} + +//TODO the partial putting thing is not yet implemented +void NFSProtocol::put( const KURL& url, int _mode, bool _overwrite, bool /*_resume*/ ) +{ + TQString destPath( TQFile::encodeName(url.path())); + kdDebug( 7121 ) << "Put -" << destPath <<"-"<<endl; + /*TQString dest_part( dest_orig ); + dest_part += ".part";*/ + + stripTrailingSlash(destPath); + TQString parentDir, fileName; + getLastPart(destPath,fileName, parentDir); + if (isRoot(parentDir)) + { + error(ERR_WRITE_ACCESS_DENIED,destPath); + return; + } + + NFSFileHandle destFH; + destFH=getFileHandle(destPath); + kdDebug(7121)<<"file handle for -"<<destPath<<"- is "<<destFH<<endl; + + //the file exists and we don't want to overwrite + if ((!_overwrite) && (!destFH.isInvalid())) + { + error(ERR_FILE_ALREADY_EXIST,destPath); + return; + } + //TODO: is this correct ? + //we have to "create" the file anyway, no matter if it already + //exists or not + //if we don't create it new, written text will be, hmm, "inserted" + //in the existing file, i.e. a file could not become smaller, since + //write only overwrites or extends, but doesn't remove stuff from a file (aleXXX) + + kdDebug(7121)<<"creating the file -"<<fileName<<"-"<<endl; + NFSFileHandle parentFH; + parentFH=getFileHandle(parentDir); + //cerr<<"fh for parent dir: "<<parentFH<<endl; + //the directory doesn't exist + if (parentFH.isInvalid()) + { + kdDebug(7121)<<"parent directory -"<<parentDir<<"- does not exist"<<endl; + error(ERR_DOES_NOT_EXIST,parentDir); + return; + } + createargs createArgs; + memcpy(createArgs.where.dir.data,(const char*)parentFH,NFS_FHSIZE); + TQCString tmpName=TQFile::encodeName(fileName); + createArgs.where.name=tmpName.data(); + + //the mode is apparently ignored if the file already exists + if (_mode==-1) createArgs.attributes.mode=0644; + else createArgs.attributes.mode=_mode; + createArgs.attributes.uid=geteuid(); + createArgs.attributes.gid=getegid(); + //this is required, otherwise we are not able to write shorter files + createArgs.attributes.size=0; + //hmm, do we need something here ? I don't think so + createArgs.attributes.atime.seconds=(unsigned int)-1; + createArgs.attributes.atime.useconds=(unsigned int)-1; + createArgs.attributes.mtime.seconds=(unsigned int)-1; + createArgs.attributes.mtime.useconds=(unsigned int)-1; + + diropres dirOpRes; + int clnt_stat = clnt_call(m_client, NFSPROC_CREATE, + (xdrproc_t) xdr_createargs, (char*)&createArgs, + (xdrproc_t) xdr_diropres, (char*)&dirOpRes,total_timeout); + if (!checkForError(clnt_stat,dirOpRes.status,fileName)) return; + //we created the file successfully + //destFH=getFileHandle(destPath); + destFH=dirOpRes.diropres_u.diropres.file.data; + kdDebug(7121)<<"file -"<<fileName<<"- in dir -"<<parentDir<<"- created successfully"<<endl; + //cerr<<"with fh "<<destFH<<endl; + + //now we can put + int result; + // Loop until we got 0 (end of data) + writeargs writeArgs; + memcpy(writeArgs.file.data,(const char*)destFH,NFS_FHSIZE); + writeArgs.beginoffset=0; + writeArgs.totalcount=0; + writeArgs.offset=0; + attrstat attrStat; + int bytesWritten(0); + kdDebug(7121)<<"starting to put"<<endl; + do + { + TQByteArray buffer; + dataReq(); // Request for data + result = readData( buffer ); + //kdDebug(7121)<<"received "<<result<<" bytes for putting"<<endl; + char * data=buffer.data(); + int bytesToWrite=buffer.size(); + int writeNow(0); + if (result > 0) + { + do + { + if (bytesToWrite>NFS_MAXDATA) + { + writeNow=NFS_MAXDATA; + } + else + { + writeNow=bytesToWrite; + }; + writeArgs.data.data_val=data; + writeArgs.data.data_len=writeNow; + + int clnt_stat = clnt_call(m_client, NFSPROC_WRITE, + (xdrproc_t) xdr_writeargs, (char*)&writeArgs, + (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout); + //kdDebug(7121)<<"written"<<endl; + 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(); +} + +void NFSProtocol::rename( const KURL &src, const KURL &dest, bool _overwrite ) +{ + TQString srcPath( TQFile::encodeName(src.path())); + TQString destPath( TQFile::encodeName(dest.path())); + stripTrailingSlash(srcPath); + stripTrailingSlash(destPath); + kdDebug(7121)<<"renaming -"<<srcPath<<"- to -"<<destPath<<"-"<<endl; + + if (isRoot(srcPath) || isExportedDir(srcPath)) + { + error(ERR_CANNOT_RENAME,srcPath); + return; + } + + if (!_overwrite) + { + NFSFileHandle testFH; + testFH=getFileHandle(destPath); + if (!testFH.isInvalid()) + { + error(ERR_FILE_ALREADY_EXIST,destPath); + return; + } + } + + TQString srcFileName, srcParentDir, destFileName, destParentDir; + + getLastPart(srcPath, srcFileName, srcParentDir); + NFSFileHandle srcFH=getFileHandle(srcParentDir); + if (srcFH.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,srcParentDir); + return; + } + renameargs renameArgs; + memcpy(renameArgs.from.dir.data,srcFH,NFS_FHSIZE); + TQCString tmpName=TQFile::encodeName(srcFileName); + renameArgs.from.name=tmpName.data(); + + getLastPart(destPath, destFileName, destParentDir); + NFSFileHandle destFH=getFileHandle(destParentDir); + if (destFH.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,destParentDir); + return; + } + memcpy(renameArgs.to.dir.data,destFH,NFS_FHSIZE); + TQCString tmpName2=TQFile::encodeName(destFileName); + renameArgs.to.name=tmpName2.data(); + nfsstat nfsStat; + + int clnt_stat = clnt_call(m_client, NFSPROC_RENAME, + (xdrproc_t) xdr_renameargs, (char*)&renameArgs, + (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout); + if (!checkForError(clnt_stat,nfsStat,destPath)) return; + finished(); +} + +void NFSProtocol::copy( const KURL &src, const KURL &dest, int _mode, bool _overwrite ) +{ + //prepare the source + TQString thePath( TQFile::encodeName(src.path())); + stripTrailingSlash(thePath); + kdDebug( 7121 ) << "Copy to -" << thePath <<"-"<<endl; + NFSFileHandle fh=getFileHandle(thePath); + if (fh.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,thePath); + return; + }; + + //create the destination + TQString destPath( TQFile::encodeName(dest.path())); + stripTrailingSlash(destPath); + TQString parentDir, fileName; + getLastPart(destPath,fileName, parentDir); + if (isRoot(parentDir)) + { + error(ERR_ACCESS_DENIED,destPath); + return; + } + NFSFileHandle destFH; + destFH=getFileHandle(destPath); + kdDebug(7121)<<"file handle for -"<<destPath<<"- is "<<destFH<<endl; + + //the file exists and we don't want to overwrite + if ((!_overwrite) && (!destFH.isInvalid())) + { + error(ERR_FILE_ALREADY_EXIST,destPath); + return; + } + //TODO: is this correct ? + //we have to "create" the file anyway, no matter if it already + //exists or not + //if we don't create it new, written text will be, hmm, "inserted" + //in the existing file, i.e. a file could not become smaller, since + //write only overwrites or extends, but doesn't remove stuff from a file + + kdDebug(7121)<<"creating the file -"<<fileName<<"-"<<endl; + NFSFileHandle parentFH; + parentFH=getFileHandle(parentDir); + //the directory doesn't exist + if (parentFH.isInvalid()) + { + kdDebug(7121)<<"parent directory -"<<parentDir<<"- does not exist"<<endl; + error(ERR_DOES_NOT_EXIST,parentDir); + return; + }; + createargs createArgs; + memcpy(createArgs.where.dir.data,(const char*)parentFH,NFS_FHSIZE); + TQCString tmpName=TQFile::encodeName(fileName); + createArgs.where.name=tmpName.data(); + if (_mode==-1) createArgs.attributes.mode=0644; + else createArgs.attributes.mode=_mode; + createArgs.attributes.uid=geteuid(); + createArgs.attributes.gid=getegid(); + createArgs.attributes.size=0; + createArgs.attributes.atime.seconds=(unsigned int)-1; + createArgs.attributes.atime.useconds=(unsigned int)-1; + createArgs.attributes.mtime.seconds=(unsigned int)-1; + createArgs.attributes.mtime.useconds=(unsigned int)-1; + + diropres dirOpRes; + int clnt_stat = clnt_call(m_client, NFSPROC_CREATE, + (xdrproc_t) xdr_createargs, (char*)&createArgs, + (xdrproc_t) xdr_diropres, (char*)&dirOpRes,total_timeout); + if (!checkForError(clnt_stat,dirOpRes.status,destPath)) return; + //we created the file successfully + destFH=dirOpRes.diropres_u.diropres.file.data; + kdDebug(7121)<<"file -"<<fileName<<"- in dir -"<<parentDir<<"- created successfully"<<endl; + + char buf[NFS_MAXDATA]; + writeargs writeArgs; + memcpy(writeArgs.file.data,(const char*)destFH,NFS_FHSIZE); + writeArgs.beginoffset=0; + writeArgs.totalcount=0; + writeArgs.offset=0; + writeArgs.data.data_val=buf; + attrstat attrStat; + + readargs readArgs; + memcpy(readArgs.file.data,fh,NFS_FHSIZE); + readArgs.offset=0; + readArgs.count=NFS_MAXDATA; + readArgs.totalcount=NFS_MAXDATA; + readres readRes; + readRes.readres_u.reply.data.data_val=buf; + + int bytesRead(0); + do + { + //first read + int clnt_stat = clnt_call(m_client, NFSPROC_READ, + (xdrproc_t) xdr_readargs, (char*)&readArgs, + (xdrproc_t) xdr_readres, (char*)&readRes,total_timeout); + if (!checkForError(clnt_stat,readRes.status,thePath)) return; + if (readArgs.offset==0) + totalSize(readRes.readres_u.reply.attributes.size); + + bytesRead=readRes.readres_u.reply.data.data_len; + //kdDebug(7121)<<"read "<<bytesRead<<" bytes"<<endl; + //then write + if (bytesRead>0) + { + readArgs.offset+=bytesRead; + + writeArgs.data.data_len=bytesRead; + + clnt_stat = clnt_call(m_client, NFSPROC_WRITE, + (xdrproc_t) xdr_writeargs, (char*)&writeArgs, + (xdrproc_t) xdr_attrstat, (char*)&attrStat,total_timeout); + //kdDebug(7121)<<"written"<<endl; + if (!checkForError(clnt_stat,attrStat.status,destPath)) return; + writeArgs.offset+=bytesRead; + } + } while (bytesRead>0); + + finished(); +} + +//TODO why isn't this even called ? +void NFSProtocol::symlink( const TQString &target, const KURL &dest, bool ) +{ + kdDebug(7121)<<"symlinking "<<endl; + TQString destPath=dest.path(); + stripTrailingSlash(destPath); + + TQString parentDir, fileName; + getLastPart(destPath,fileName, parentDir); + kdDebug(7121)<<"symlinking "<<parentDir<<" "<<fileName<<" to "<<target<<endl; + NFSFileHandle fh=getFileHandle(parentDir); + if (fh.isInvalid()) + { + error(ERR_DOES_NOT_EXIST,parentDir); + return; + } + if (isRoot(parentDir)) + { + error(ERR_ACCESS_DENIED,destPath); + return; + } + + kdDebug(7121)<<"tach"<<endl; + TQCString tmpStr=target.latin1(); + symlinkargs symLinkArgs; + symLinkArgs.to=tmpStr.data(); + memcpy(symLinkArgs.from.dir.data,(const char*)fh,NFS_FHSIZE); + TQCString tmpStr2=TQFile::encodeName(destPath); + symLinkArgs.from.name=tmpStr2.data(); + + nfsstat nfsStat; + int clnt_stat = clnt_call(m_client, NFSPROC_SYMLINK, + (xdrproc_t) xdr_symlinkargs, (char*)&symLinkArgs, + (xdrproc_t) xdr_nfsstat, (char*)&nfsStat,total_timeout); + if (!checkForError(clnt_stat,nfsStat,destPath)) return; + + finished(); + +} + +bool NFSProtocol::isValidLink(const TQString& parentDir, const TQString& linkDest) +{ + kdDebug(7121)<<"isValidLink: parent: "<<parentDir<<" link: "<<linkDest<<endl; + if (linkDest.isEmpty()) return FALSE; + if (isAbsoluteLink(linkDest)) + { + kdDebug(7121)<<"is an absolute link"<<endl; + return TQFile::exists(linkDest); + } + else + { + kdDebug(7121)<<"is a relative link"<<endl; + TQString absDest=parentDir+"/"+linkDest; + kdDebug(7121)<<"pointing abs to "<<absDest<<endl; + absDest=removeFirstPart(absDest); + kdDebug(7121)<<"removed first part "<<absDest<<endl; + absDest=TQDir::cleanDirPath(absDest); + kdDebug(7121)<<"simplified to "<<absDest<<endl; + if (absDest.find("../")==0) + return FALSE; + + kdDebug(7121)<<"is inside the nfs tree"<<endl; + absDest=parentDir+"/"+linkDest; + absDest=TQDir::cleanDirPath(absDest); + kdDebug(7121)<<"getting file handle of "<<absDest<<endl; + NFSFileHandle fh=getFileHandle(absDest); + return (!fh.isInvalid()); + } + return FALSE; +} + diff --git a/tdeioslave/nfs/kio_nfs.h b/tdeioslave/nfs/kio_nfs.h new file mode 100644 index 000000000..b548fc487 --- /dev/null +++ b/tdeioslave/nfs/kio_nfs.h @@ -0,0 +1,109 @@ +/* This file is part of the KDE project + Copyright (C) 2000 Alexander Neundorf <neundorf@kde.org> + + 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_NFS_H +#define KIO_NFS_H + +#include <tdeio/slavebase.h> +#include <tdeio/global.h> + +#include <tqmap.h> +#include <tqstring.h> +#include <tqstringlist.h> +#include <tqintdict.h> +#include <tqtimer.h> + +#define PORTMAP //this seems to be required to compile on Solaris +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <sys/time.h> + +class NFSFileHandle +{ + 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; +}; + +//ostream& operator<<(ostream&, const NFSFileHandle&); + +typedef TQMap<TQString,NFSFileHandle> NFSFileHandleMap; + + +class NFSProtocol : public TDEIO::SlaveBase +{ + public: + NFSProtocol (const TQCString &pool, const TQCString &app ); + virtual ~NFSProtocol(); + + virtual void openConnection(); + virtual void closeConnection(); + + virtual void setHost( const TQString& host, int port, const TQString& user, const TQString& pass ); + + virtual void put( const KURL& url, int _mode,bool _overwrite, bool _resume ); + virtual void get( const KURL& url ); + virtual void listDir( const KURL& url); + virtual void symlink( const TQString &target, const KURL &dest, bool ); + virtual void stat( const KURL & url); + virtual void mkdir( const KURL& url, int permissions ); + virtual void del( const KURL& url, bool isfile); + virtual void chmod(const KURL& url, int permissions ); + virtual void rename(const KURL &src, const KURL &dest, bool overwrite); + virtual void copy( const KURL& src, const KURL &dest, int mode, bool overwrite ); + protected: +// void createVirtualDirEntry(TDEIO::UDSEntry & entry); + bool checkForError(int clientStat, int nfsStat, const TQString& text); + bool isExportedDir(const TQString& path); + void completeUDSEntry(TDEIO::UDSEntry& entry, fattr& attributes); + void completeBadLinkUDSEntry(TDEIO::UDSEntry& entry, fattr& attributes); + void completeAbsoluteLinkUDSEntry(TDEIO::UDSEntry& entry, const TQCString& path); + bool isValidLink(const TQString& parentDir, const TQString& linkDest); +// bool isAbsoluteLink(const TQString& path); + + NFSFileHandle getFileHandle(TQString path); + + NFSFileHandleMap m_handleCache; + TQIntDict<TQString> m_usercache; // maps long ==> TQString * + TQIntDict<TQString> m_groupcache; + + TQStringList m_exportedDirs; + TQString m_currentHost; + CLIENT *m_client; + CLIENT *m_nfsClient; + timeval total_timeout; + timeval pertry_timeout; + int m_sock; + time_t m_lastCheck; + void checkForOldFHs(); +}; + +#endif diff --git a/tdeioslave/nfs/mount.h b/tdeioslave/nfs/mount.h new file mode 100644 index 000000000..c3b8c217f --- /dev/null +++ b/tdeioslave/nfs/mount.h @@ -0,0 +1,325 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _MOUNT_H_RPCGEN +#define _MOUNT_H_RPCGEN + +#include <rpc/rpc.h> + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Copyright (c) 1985, 1990 by Sun Microsystems, Inc. + */ + +/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */ +#ifndef _rpcsvc_mount_h +#define _rpcsvc_mount_h +#define MNTPATHLEN 1024 +#define MNTNAMLEN 255 +#define FHSIZE 32 + +typedef char fhandle[FHSIZE]; +#ifdef __cplusplus +extern "C" bool_t xdr_fhandle(XDR *, fhandle); +#elif __STDC__ +extern bool_t xdr_fhandle(XDR *, fhandle); +#else /* Old Style C */ +bool_t xdr_fhandle(); +#endif /* Old Style C */ + + +struct fhstatus { + u_int fhs_status; + union { + fhandle fhs_fhandle; + } fhstatus_u; +}; +typedef struct fhstatus fhstatus; +#ifdef __cplusplus +extern "C" bool_t xdr_fhstatus(XDR *, fhstatus*); +#elif __STDC__ +extern bool_t xdr_fhstatus(XDR *, fhstatus*); +#else /* Old Style C */ +bool_t xdr_fhstatus(); +#endif /* Old Style C */ + + +typedef char *dirpath; +#ifdef __cplusplus +extern "C" bool_t xdr_dirpath(XDR *, dirpath*); +#elif __STDC__ +extern bool_t xdr_dirpath(XDR *, dirpath*); +#else /* Old Style C */ +bool_t xdr_dirpath(); +#endif /* Old Style C */ + + +typedef char *name; +#ifdef __cplusplus +extern "C" bool_t xdr_name(XDR *, name*); +#elif __STDC__ +extern bool_t xdr_name(XDR *, name*); +#else /* Old Style C */ +bool_t xdr_name(); +#endif /* Old Style C */ + + +typedef struct mountbody *mountlist; +#ifdef __cplusplus +extern "C" bool_t xdr_mountlist(XDR *, mountlist*); +#elif __STDC__ +extern bool_t xdr_mountlist(XDR *, mountlist*); +#else /* Old Style C */ +bool_t xdr_mountlist(); +#endif /* Old Style C */ + + +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; +typedef struct mountbody mountbody; +#ifdef __cplusplus +extern "C" bool_t xdr_mountbody(XDR *, mountbody*); +#elif __STDC__ +extern bool_t xdr_mountbody(XDR *, mountbody*); +#else /* Old Style C */ +bool_t xdr_mountbody(); +#endif /* Old Style C */ + + +typedef struct groupnode *groups; +#ifdef __cplusplus +extern "C" bool_t xdr_groups(XDR *, groups*); +#elif __STDC__ +extern bool_t xdr_groups(XDR *, groups*); +#else /* Old Style C */ +bool_t xdr_groups(); +#endif /* Old Style C */ + + +struct groupnode { + name gr_name; + groups gr_next; +}; +typedef struct groupnode groupnode; +#ifdef __cplusplus +extern "C" bool_t xdr_groupnode(XDR *, groupnode*); +#elif __STDC__ +extern bool_t xdr_groupnode(XDR *, groupnode*); +#else /* Old Style C */ +bool_t xdr_groupnode(); +#endif /* Old Style C */ + + +typedef struct exportnode *exports; +#ifdef __cplusplus +extern "C" bool_t xdr_exports(XDR *, exports*); +#elif __STDC__ +extern bool_t xdr_exports(XDR *, exports*); +#else /* Old Style C */ +bool_t xdr_exports(); +#endif /* Old Style C */ + + +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; +typedef struct exportnode exportnode; +#ifdef __cplusplus +extern "C" bool_t xdr_exportnode(XDR *, exportnode*); +#elif __STDC__ +extern bool_t xdr_exportnode(XDR *, exportnode*); +#else /* Old Style C */ +bool_t xdr_exportnode(); +#endif /* Old Style C */ + + +struct ppathcnf { + int pc_link_max; + short pc_max_canon; + short pc_max_input; + short pc_name_max; + short pc_path_max; + short pc_pipe_buf; + u_char pc_vdisable; + char pc_xxx; + short pc_mask[2]; +}; +typedef struct ppathcnf ppathcnf; +#ifdef __cplusplus +extern "C" bool_t xdr_ppathcnf(XDR *, ppathcnf*); +#elif __STDC__ +extern bool_t xdr_ppathcnf(XDR *, ppathcnf*); +#else /* Old Style C */ +bool_t xdr_ppathcnf(); +#endif /* Old Style C */ + +#endif /*!_rpcsvc_mount_h*/ + +#define MOUNTPROG ((u_long)100005) +#define MOUNTVERS ((u_long)1) + +#ifdef __cplusplus +#define MOUNTPROC_NULL ((u_long)0) +extern "C" void * mountproc_null_1(void *, CLIENT *); +extern "C" void * mountproc_null_1_svc(void *, struct svc_req *); +#define MOUNTPROC_MNT ((u_long)1) +extern "C" fhstatus * mountproc_mnt_1(dirpath *, CLIENT *); +extern "C" fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *); +#define MOUNTPROC_DUMP ((u_long)2) +extern "C" mountlist * mountproc_dump_1(void *, CLIENT *); +extern "C" mountlist * mountproc_dump_1_svc(void *, struct svc_req *); +#define MOUNTPROC_UMNT ((u_long)3) +extern "C" void * mountproc_umnt_1(dirpath *, CLIENT *); +extern "C" void * mountproc_umnt_1_svc(dirpath *, struct svc_req *); +#define MOUNTPROC_UMNTALL ((u_long)4) +extern "C" void * mountproc_umntall_1(void *, CLIENT *); +extern "C" void * mountproc_umntall_1_svc(void *, struct svc_req *); +#define MOUNTPROC_EXPORT ((u_long)5) +extern "C" exports * mountproc_export_1(void *, CLIENT *); +extern "C" exports * mountproc_export_1_svc(void *, struct svc_req *); +#define MOUNTPROC_EXPORTALL ((u_long)6) +extern "C" exports * mountproc_exportall_1(void *, CLIENT *); +extern "C" exports * mountproc_exportall_1_svc(void *, struct svc_req *); + +#elif __STDC__ +#define MOUNTPROC_NULL ((u_long)0) +extern void * mountproc_null_1(void *, CLIENT *); +extern void * mountproc_null_1_svc(void *, struct svc_req *); +#define MOUNTPROC_MNT ((u_long)1) +extern fhstatus * mountproc_mnt_1(dirpath *, CLIENT *); +extern fhstatus * mountproc_mnt_1_svc(dirpath *, struct svc_req *); +#define MOUNTPROC_DUMP ((u_long)2) +extern mountlist * mountproc_dump_1(void *, CLIENT *); +extern mountlist * mountproc_dump_1_svc(void *, struct svc_req *); +#define MOUNTPROC_UMNT ((u_long)3) +extern void * mountproc_umnt_1(dirpath *, CLIENT *); +extern void * mountproc_umnt_1_svc(dirpath *, struct svc_req *); +#define MOUNTPROC_UMNTALL ((u_long)4) +extern void * mountproc_umntall_1(void *, CLIENT *); +extern void * mountproc_umntall_1_svc(void *, struct svc_req *); +#define MOUNTPROC_EXPORT ((u_long)5) +extern exports * mountproc_export_1(void *, CLIENT *); +extern exports * mountproc_export_1_svc(void *, struct svc_req *); +#define MOUNTPROC_EXPORTALL ((u_long)6) +extern exports * mountproc_exportall_1(void *, CLIENT *); +extern exports * mountproc_exportall_1_svc(void *, struct svc_req *); + +#else /* Old Style C */ +#define MOUNTPROC_NULL ((u_long)0) +extern void * mountproc_null_1(); +extern void * mountproc_null_1_svc(); +#define MOUNTPROC_MNT ((u_long)1) +extern fhstatus * mountproc_mnt_1(); +extern fhstatus * mountproc_mnt_1_svc(); +#define MOUNTPROC_DUMP ((u_long)2) +extern mountlist * mountproc_dump_1(); +extern mountlist * mountproc_dump_1_svc(); +#define MOUNTPROC_UMNT ((u_long)3) +extern void * mountproc_umnt_1(); +extern void * mountproc_umnt_1_svc(); +#define MOUNTPROC_UMNTALL ((u_long)4) +extern void * mountproc_umntall_1(); +extern void * mountproc_umntall_1_svc(); +#define MOUNTPROC_EXPORT ((u_long)5) +extern exports * mountproc_export_1(); +extern exports * mountproc_export_1_svc(); +#define MOUNTPROC_EXPORTALL ((u_long)6) +extern exports * mountproc_exportall_1(); +extern exports * mountproc_exportall_1_svc(); +#endif /* Old Style C */ +#define MOUNTVERS_POSIX ((u_long)2) + +#ifdef __cplusplus +extern "C" void * mountproc_null_2(void *, CLIENT *); +extern "C" void * mountproc_null_2_svc(void *, struct svc_req *); +extern "C" fhstatus * mountproc_mnt_2(dirpath *, CLIENT *); +extern "C" fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *); +extern "C" mountlist * mountproc_dump_2(void *, CLIENT *); +extern "C" mountlist * mountproc_dump_2_svc(void *, struct svc_req *); +extern "C" void * mountproc_umnt_2(dirpath *, CLIENT *); +extern "C" void * mountproc_umnt_2_svc(dirpath *, struct svc_req *); +extern "C" void * mountproc_umntall_2(void *, CLIENT *); +extern "C" void * mountproc_umntall_2_svc(void *, struct svc_req *); +extern "C" exports * mountproc_export_2(void *, CLIENT *); +extern "C" exports * mountproc_export_2_svc(void *, struct svc_req *); +extern "C" exports * mountproc_exportall_2(void *, CLIENT *); +extern "C" exports * mountproc_exportall_2_svc(void *, struct svc_req *); +#define MOUNTPROC_PATHCONF ((u_long)7) +extern "C" ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *); +extern "C" ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *); + +#elif __STDC__ +extern void * mountproc_null_2(void *, CLIENT *); +extern void * mountproc_null_2_svc(void *, struct svc_req *); +extern fhstatus * mountproc_mnt_2(dirpath *, CLIENT *); +extern fhstatus * mountproc_mnt_2_svc(dirpath *, struct svc_req *); +extern mountlist * mountproc_dump_2(void *, CLIENT *); +extern mountlist * mountproc_dump_2_svc(void *, struct svc_req *); +extern void * mountproc_umnt_2(dirpath *, CLIENT *); +extern void * mountproc_umnt_2_svc(dirpath *, struct svc_req *); +extern void * mountproc_umntall_2(void *, CLIENT *); +extern void * mountproc_umntall_2_svc(void *, struct svc_req *); +extern exports * mountproc_export_2(void *, CLIENT *); +extern exports * mountproc_export_2_svc(void *, struct svc_req *); +extern exports * mountproc_exportall_2(void *, CLIENT *); +extern exports * mountproc_exportall_2_svc(void *, struct svc_req *); +#define MOUNTPROC_PATHCONF ((u_long)7) +extern ppathcnf * mountproc_pathconf_2(dirpath *, CLIENT *); +extern ppathcnf * mountproc_pathconf_2_svc(dirpath *, struct svc_req *); + +#else /* Old Style C */ +extern void * mountproc_null_2(); +extern void * mountproc_null_2_svc(); +extern fhstatus * mountproc_mnt_2(); +extern fhstatus * mountproc_mnt_2_svc(); +extern mountlist * mountproc_dump_2(); +extern mountlist * mountproc_dump_2_svc(); +extern void * mountproc_umnt_2(); +extern void * mountproc_umnt_2_svc(); +extern void * mountproc_umntall_2(); +extern void * mountproc_umntall_2_svc(); +extern exports * mountproc_export_2(); +extern exports * mountproc_export_2_svc(); +extern exports * mountproc_exportall_2(); +extern exports * mountproc_exportall_2_svc(); +#define MOUNTPROC_PATHCONF ((u_long)7) +extern ppathcnf * mountproc_pathconf_2(); +extern ppathcnf * mountproc_pathconf_2_svc(); +#endif /* Old Style C */ + +#endif /* !_MOUNT_H_RPCGEN */ diff --git a/tdeioslave/nfs/mount.x b/tdeioslave/nfs/mount.x new file mode 100644 index 000000000..4aaf97de9 --- /dev/null +++ b/tdeioslave/nfs/mount.x @@ -0,0 +1,255 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +%/* +% * Copyright (c) 1985, 1990 by Sun Microsystems, Inc. +% */ +% +%/* from @(#)mount.x 1.3 91/03/11 TIRPC 1.0 */ + +/* + * Protocol description for the mount program + */ + +#ifdef RPC_HDR +%#ifndef _rpcsvc_mount_h +%#define _rpcsvc_mount_h +#endif + +const MNTPATHLEN = 1024; /* maximum bytes in a pathname argument */ +const MNTNAMLEN = 255; /* maximum bytes in a name argument */ +const FHSIZE = 32; /* size in bytes of a file handle */ + +/* + * The fhandle is the file handle that the server passes to the client. + * All file operations are done using the file handles to refer to a file + * or a directory. The file handle can contain whatever information the + * server needs to distinguish an individual file. + */ +typedef opaque fhandle[FHSIZE]; + +/* + * If a status of zero is returned, the call completed successfully, and + * a file handle for the directory follows. A non-zero status indicates + * some sort of error. The status corresponds with UNIX error numbers. + */ +union fhstatus switch (unsigned fhs_status) { +case 0: + fhandle fhs_fhandle; +default: + void; +}; + +/* + * The type dirpath is the pathname of a directory + */ +typedef string dirpath<MNTPATHLEN>; + +/* + * The type name is used for arbitrary names (hostnames, groupnames) + */ +typedef string name<MNTNAMLEN>; + +/* + * A list of who has what mounted + */ +typedef struct mountbody *mountlist; +struct mountbody { + name ml_hostname; + dirpath ml_directory; + mountlist ml_next; +}; + +/* + * A list of netgroups + */ +typedef struct groupnode *groups; +struct groupnode { + name gr_name; + groups gr_next; +}; + +/* + * A list of what is exported and to whom + */ +typedef struct exportnode *exports; +struct exportnode { + dirpath ex_dir; + groups ex_groups; + exports ex_next; +}; + +/* + * POSIX pathconf information + */ +struct ppathcnf { + int pc_link_max; /* max links allowed */ + short pc_max_canon; /* max line len for a tty */ + short pc_max_input; /* input a tty can eat all at once */ + short pc_name_max; /* max file name length (dir entry) */ + short pc_path_max; /* max path name length (/x/y/x/.. ) */ + short pc_pipe_buf; /* size of a pipe (bytes) */ + u_char pc_vdisable; /* safe char to turn off c_cc[i] */ + char pc_xxx; /* alignment padding; cc_t == char */ + short pc_mask[2]; /* validity and boolean bits */ +}; + +program MOUNTPROG { + /* + * Version one of the mount protocol communicates with version two + * of the NFS protocol. The only connecting point is the fhandle + * structure, which is the same for both protocols. + */ + version MOUNTVERS { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. This file handle may + * be used in the NFS protocol. This procedure also adds + * a new entry to the mount list for this client mounting + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + } = 1; + + /* + * Version two of the mount protocol communicates with version two + * of the NFS protocol. + * The only difference from version one is the addition of a POSIX + * pathconf call. + */ + version MOUNTVERS_POSIX { + /* + * Does no work. It is made available in all RPC services + * to allow server reponse testing and timing + */ + void + MOUNTPROC_NULL(void) = 0; + + /* + * If fhs_status is 0, then fhs_fhandle contains the + * file handle for the directory. This file handle may + * be used in the NFS protocol. This procedure also adds + * a new entry to the mount list for this client mounting + * the directory. + * Unix authentication required. + */ + fhstatus + MOUNTPROC_MNT(dirpath) = 1; + + /* + * Returns the list of remotely mounted filesystems. The + * mountlist contains one entry for each hostname and + * directory pair. + */ + mountlist + MOUNTPROC_DUMP(void) = 2; + + /* + * Removes the mount list entry for the directory + * Unix authentication required. + */ + void + MOUNTPROC_UMNT(dirpath) = 3; + + /* + * Removes all of the mount list entries for this client + * Unix authentication required. + */ + void + MOUNTPROC_UMNTALL(void) = 4; + + /* + * Returns a list of all the exported filesystems, and which + * machines are allowed to import it. + */ + exports + MOUNTPROC_EXPORT(void) = 5; + + /* + * Identical to MOUNTPROC_EXPORT above + */ + exports + MOUNTPROC_EXPORTALL(void) = 6; + + /* + * POSIX pathconf info (Sun hack) + */ + ppathcnf + MOUNTPROC_PATHCONF(dirpath) = 7; + } = 2; +} = 100005; + +#ifdef RPC_HDR +%#endif /*!_rpcsvc_mount_h*/ +#endif diff --git a/tdeioslave/nfs/mount_xdr.c b/tdeioslave/nfs/mount_xdr.c new file mode 100644 index 000000000..38a43ca28 --- /dev/null +++ b/tdeioslave/nfs/mount_xdr.c @@ -0,0 +1,335 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <arpa/inet.h> + +#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/tdeioslave/nfs/nfs.protocol b/tdeioslave/nfs/nfs.protocol new file mode 100644 index 000000000..8f62d779a --- /dev/null +++ b/tdeioslave/nfs/nfs.protocol @@ -0,0 +1,14 @@ +[Protocol] +exec=kio_nfs +protocol=nfs +input=none +output=filesystem +listing=Name,Type,Size,Date,AccessDate,CreationDate,Access,Owner,Group,Link +reading=true +writing=true +makedir=true +deleting=true +linking=true +moving=true +DocPath=tdeioslave/nfs.html +Icon=nfs_mount diff --git a/tdeioslave/nfs/nfs_prot.h b/tdeioslave/nfs/nfs_prot.h new file mode 100644 index 000000000..5ed218f20 --- /dev/null +++ b/tdeioslave/nfs/nfs_prot.h @@ -0,0 +1,699 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#ifndef _NFS_PROT_H_RPCGEN +#define _NFS_PROT_H_RPCGEN + +#include <rpc/rpc.h> + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Copyright (c) 1987, 1990 by Sun Microsystems, Inc. + */ + +/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */ +#ifndef _rpcsvc_nfs_prot_h +#define _rpcsvc_nfs_prot_h +#define NFS_PORT 2049 +#define NFS_MAXDATA 8192 +#define NFS_MAXPATHLEN 1024 +#define NFS_MAXNAMLEN 255 +#define NFS_FHSIZE 32 +#define NFS_COOKIESIZE 4 +#define NFS_FIFO_DEV -1 +#define NFSMODE_FMT 0170000 +#define NFSMODE_DIR 0040000 +#define NFSMODE_CHR 0020000 +#define NFSMODE_BLK 0060000 +#define NFSMODE_REG 0100000 +#define NFSMODE_LNK 0120000 +#define NFSMODE_SOCK 0140000 +#define NFSMODE_FIFO 0010000 + +enum nfsstat { + NFS_OK = 0, + NFSERR_PERM = 1, + NFSERR_NOENT = 2, + NFSERR_IO = 5, + NFSERR_NXIO = 6, + NFSERR_ACCES = 13, + NFSERR_EXIST = 17, + NFSERR_NODEV = 19, + NFSERR_NOTDIR = 20, + NFSERR_ISDIR = 21, + NFSERR_INVAL = 22, + NFSERR_FBIG = 27, + NFSERR_NOSPC = 28, + NFSERR_ROFS = 30, + NFSERR_NAMETOOLONG = 63, + NFSERR_NOTEMPTY = 66, + NFSERR_DQUOT = 69, + NFSERR_STALE = 70, + NFSERR_WFLUSH = 99 +}; +typedef enum nfsstat nfsstat; +#ifdef __cplusplus +extern "C" bool_t xdr_nfsstat(XDR *, nfsstat*); +#elif __STDC__ +extern bool_t xdr_nfsstat(XDR *, nfsstat*); +#else /* Old Style C */ +bool_t xdr_nfsstat(); +#endif /* Old Style C */ + + +enum ftype { + NFNON = 0, + NFREG = 1, + NFDIR = 2, + NFBLK = 3, + NFCHR = 4, + NFLNK = 5, + NFSOCK = 6, + NFBAD = 7, + NFFIFO = 8 +}; +typedef enum ftype ftype; +#ifdef __cplusplus +extern "C" bool_t xdr_ftype(XDR *, ftype*); +#elif __STDC__ +extern bool_t xdr_ftype(XDR *, ftype*); +#else /* Old Style C */ +bool_t xdr_ftype(); +#endif /* Old Style C */ + + +struct nfs_fh { + char data[NFS_FHSIZE]; +}; +typedef struct nfs_fh nfs_fh; +#ifdef __cplusplus +extern "C" bool_t xdr_nfs_fh(XDR *, nfs_fh*); +#elif __STDC__ +extern bool_t xdr_nfs_fh(XDR *, nfs_fh*); +#else /* Old Style C */ +bool_t xdr_nfs_fh(); +#endif /* Old Style C */ + + +struct nfstime { + u_int seconds; + u_int useconds; +}; +typedef struct nfstime nfstime; +#ifdef __cplusplus +extern "C" bool_t xdr_nfstime(XDR *, nfstime*); +#elif __STDC__ +extern bool_t xdr_nfstime(XDR *, nfstime*); +#else /* Old Style C */ +bool_t xdr_nfstime(); +#endif /* Old Style C */ + + +struct fattr { + ftype type; + u_int mode; + u_int nlink; + u_int uid; + u_int gid; + u_int size; + u_int blocksize; + u_int rdev; + u_int blocks; + u_int fsid; + u_int fileid; + nfstime atime; + nfstime mtime; + nfstime ctime; +}; +typedef struct fattr fattr; +#ifdef __cplusplus +extern "C" bool_t xdr_fattr(XDR *, fattr*); +#elif __STDC__ +extern bool_t xdr_fattr(XDR *, fattr*); +#else /* Old Style C */ +bool_t xdr_fattr(); +#endif /* Old Style C */ + + +struct sattr { + u_int mode; + u_int uid; + u_int gid; + u_int size; + nfstime atime; + nfstime mtime; +}; +typedef struct sattr sattr; +#ifdef __cplusplus +extern "C" bool_t xdr_sattr(XDR *, sattr*); +#elif __STDC__ +extern bool_t xdr_sattr(XDR *, sattr*); +#else /* Old Style C */ +bool_t xdr_sattr(); +#endif /* Old Style C */ + + +typedef char *filename; +#ifdef __cplusplus +extern "C" bool_t xdr_filename(XDR *, filename*); +#elif __STDC__ +extern bool_t xdr_filename(XDR *, filename*); +#else /* Old Style C */ +bool_t xdr_filename(); +#endif /* Old Style C */ + + +typedef char *nfspath; +#ifdef __cplusplus +extern "C" bool_t xdr_nfspath(XDR *, nfspath*); +#elif __STDC__ +extern bool_t xdr_nfspath(XDR *, nfspath*); +#else /* Old Style C */ +bool_t xdr_nfspath(); +#endif /* Old Style C */ + + +struct attrstat { + nfsstat status; + union { + fattr attributes; + } attrstat_u; +}; +typedef struct attrstat attrstat; +#ifdef __cplusplus +extern "C" bool_t xdr_attrstat(XDR *, attrstat*); +#elif __STDC__ +extern bool_t xdr_attrstat(XDR *, attrstat*); +#else /* Old Style C */ +bool_t xdr_attrstat(); +#endif /* Old Style C */ + + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; +typedef struct sattrargs sattrargs; +#ifdef __cplusplus +extern "C" bool_t xdr_sattrargs(XDR *, sattrargs*); +#elif __STDC__ +extern bool_t xdr_sattrargs(XDR *, sattrargs*); +#else /* Old Style C */ +bool_t xdr_sattrargs(); +#endif /* Old Style C */ + + +struct diropargs { + nfs_fh dir; + filename name; +}; +typedef struct diropargs diropargs; +#ifdef __cplusplus +extern "C" bool_t xdr_diropargs(XDR *, diropargs*); +#elif __STDC__ +extern bool_t xdr_diropargs(XDR *, diropargs*); +#else /* Old Style C */ +bool_t xdr_diropargs(); +#endif /* Old Style C */ + + +struct diropokres { + nfs_fh file; + fattr attributes; +}; +typedef struct diropokres diropokres; +#ifdef __cplusplus +extern "C" bool_t xdr_diropokres(XDR *, diropokres*); +#elif __STDC__ +extern bool_t xdr_diropokres(XDR *, diropokres*); +#else /* Old Style C */ +bool_t xdr_diropokres(); +#endif /* Old Style C */ + + +struct diropres { + nfsstat status; + union { + diropokres diropres; + } diropres_u; +}; +typedef struct diropres diropres; +#ifdef __cplusplus +extern "C" bool_t xdr_diropres(XDR *, diropres*); +#elif __STDC__ +extern bool_t xdr_diropres(XDR *, diropres*); +#else /* Old Style C */ +bool_t xdr_diropres(); +#endif /* Old Style C */ + + +struct readlinkres { + nfsstat status; + union { + nfspath data; + } readlinkres_u; +}; +typedef struct readlinkres readlinkres; +#ifdef __cplusplus +extern "C" bool_t xdr_readlinkres(XDR *, readlinkres*); +#elif __STDC__ +extern bool_t xdr_readlinkres(XDR *, readlinkres*); +#else /* Old Style C */ +bool_t xdr_readlinkres(); +#endif /* Old Style C */ + + +struct readargs { + nfs_fh file; + u_int offset; + u_int count; + u_int totalcount; +}; +typedef struct readargs readargs; +#ifdef __cplusplus +extern "C" bool_t xdr_readargs(XDR *, readargs*); +#elif __STDC__ +extern bool_t xdr_readargs(XDR *, readargs*); +#else /* Old Style C */ +bool_t xdr_readargs(); +#endif /* Old Style C */ + + +struct readokres { + fattr attributes; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct readokres readokres; +#ifdef __cplusplus +extern "C" bool_t xdr_readokres(XDR *, readokres*); +#elif __STDC__ +extern bool_t xdr_readokres(XDR *, readokres*); +#else /* Old Style C */ +bool_t xdr_readokres(); +#endif /* Old Style C */ + + +struct readres { + nfsstat status; + union { + readokres reply; + } readres_u; +}; +typedef struct readres readres; +#ifdef __cplusplus +extern "C" bool_t xdr_readres(XDR *, readres*); +#elif __STDC__ +extern bool_t xdr_readres(XDR *, readres*); +#else /* Old Style C */ +bool_t xdr_readres(); +#endif /* Old Style C */ + + +struct writeargs { + nfs_fh file; + u_int beginoffset; + u_int offset; + u_int totalcount; + struct { + u_int data_len; + char *data_val; + } data; +}; +typedef struct writeargs writeargs; +#ifdef __cplusplus +extern "C" bool_t xdr_writeargs(XDR *, writeargs*); +#elif __STDC__ +extern bool_t xdr_writeargs(XDR *, writeargs*); +#else /* Old Style C */ +bool_t xdr_writeargs(); +#endif /* Old Style C */ + + +struct createargs { + diropargs where; + sattr attributes; +}; +typedef struct createargs createargs; +#ifdef __cplusplus +extern "C" bool_t xdr_createargs(XDR *, createargs*); +#elif __STDC__ +extern bool_t xdr_createargs(XDR *, createargs*); +#else /* Old Style C */ +bool_t xdr_createargs(); +#endif /* Old Style C */ + + +struct renameargs { + diropargs from; + diropargs to; +}; +typedef struct renameargs renameargs; +#ifdef __cplusplus +extern "C" bool_t xdr_renameargs(XDR *, renameargs*); +#elif __STDC__ +extern bool_t xdr_renameargs(XDR *, renameargs*); +#else /* Old Style C */ +bool_t xdr_renameargs(); +#endif /* Old Style C */ + + +struct linkargs { + nfs_fh from; + diropargs to; +}; +typedef struct linkargs linkargs; +#ifdef __cplusplus +extern "C" bool_t xdr_linkargs(XDR *, linkargs*); +#elif __STDC__ +extern bool_t xdr_linkargs(XDR *, linkargs*); +#else /* Old Style C */ +bool_t xdr_linkargs(); +#endif /* Old Style C */ + + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; +typedef struct symlinkargs symlinkargs; +#ifdef __cplusplus +extern "C" bool_t xdr_symlinkargs(XDR *, symlinkargs*); +#elif __STDC__ +extern bool_t xdr_symlinkargs(XDR *, symlinkargs*); +#else /* Old Style C */ +bool_t xdr_symlinkargs(); +#endif /* Old Style C */ + + +typedef char nfscookie[NFS_COOKIESIZE]; +#ifdef __cplusplus +extern "C" bool_t xdr_nfscookie(XDR *, nfscookie); +#elif __STDC__ +extern bool_t xdr_nfscookie(XDR *, nfscookie); +#else /* Old Style C */ +bool_t xdr_nfscookie(); +#endif /* Old Style C */ + + +struct readdirargs { + nfs_fh dir; + nfscookie cookie; + u_int count; +}; +typedef struct readdirargs readdirargs; +#ifdef __cplusplus +extern "C" bool_t xdr_readdirargs(XDR *, readdirargs*); +#elif __STDC__ +extern bool_t xdr_readdirargs(XDR *, readdirargs*); +#else /* Old Style C */ +bool_t xdr_readdirargs(); +#endif /* Old Style C */ + + +struct entry { + u_int fileid; + filename name; + nfscookie cookie; + struct entry *nextentry; +}; +typedef struct entry entry; +#ifdef __cplusplus +extern "C" bool_t xdr_entry(XDR *, entry*); +#elif __STDC__ +extern bool_t xdr_entry(XDR *, entry*); +#else /* Old Style C */ +bool_t xdr_entry(); +#endif /* Old Style C */ + + +struct dirlist { + entry *entries; + bool_t eof; +}; +typedef struct dirlist dirlist; +#ifdef __cplusplus +extern "C" bool_t xdr_dirlist(XDR *, dirlist*); +#elif __STDC__ +extern bool_t xdr_dirlist(XDR *, dirlist*); +#else /* Old Style C */ +bool_t xdr_dirlist(); +#endif /* Old Style C */ + + +struct readdirres { + nfsstat status; + union { + dirlist reply; + } readdirres_u; +}; +typedef struct readdirres readdirres; +#ifdef __cplusplus +extern "C" bool_t xdr_readdirres(XDR *, readdirres*); +#elif __STDC__ +extern bool_t xdr_readdirres(XDR *, readdirres*); +#else /* Old Style C */ +bool_t xdr_readdirres(); +#endif /* Old Style C */ + + +struct statfsokres { + u_int tsize; + u_int bsize; + u_int blocks; + u_int bfree; + u_int bavail; +}; +typedef struct statfsokres statfsokres; +#ifdef __cplusplus +extern "C" bool_t xdr_statfsokres(XDR *, statfsokres*); +#elif __STDC__ +extern bool_t xdr_statfsokres(XDR *, statfsokres*); +#else /* Old Style C */ +bool_t xdr_statfsokres(); +#endif /* Old Style C */ + + +struct statfsres { + nfsstat status; + union { + statfsokres reply; + } statfsres_u; +}; +typedef struct statfsres statfsres; +#ifdef __cplusplus +extern "C" bool_t xdr_statfsres(XDR *, statfsres*); +#elif __STDC__ +extern bool_t xdr_statfsres(XDR *, statfsres*); +#else /* Old Style C */ +bool_t xdr_statfsres(); +#endif /* Old Style C */ + +#endif /*!_rpcsvc_nfs_prot_h*/ + +#define NFS_PROGRAM ((u_long)100003) +#define NFS_VERSION ((u_long)2) + +#ifdef __cplusplus +#define NFSPROC_NULL ((u_long)0) +extern "C" void * nfsproc_null_2(void *, CLIENT *); +extern "C" void * nfsproc_null_2_svc(void *, struct svc_req *); +#define NFSPROC_GETATTR ((u_long)1) +extern "C" attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *); +extern "C" attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *); +#define NFSPROC_SETATTR ((u_long)2) +extern "C" attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *); +extern "C" attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *); +#define NFSPROC_ROOT ((u_long)3) +extern "C" void * nfsproc_root_2(void *, CLIENT *); +extern "C" void * nfsproc_root_2_svc(void *, struct svc_req *); +#define NFSPROC_LOOKUP ((u_long)4) +extern "C" diropres * nfsproc_lookup_2(diropargs *, CLIENT *); +extern "C" diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_READLINK ((u_long)5) +extern "C" readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *); +extern "C" readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *); +#define NFSPROC_READ ((u_long)6) +extern "C" readres * nfsproc_read_2(readargs *, CLIENT *); +extern "C" readres * nfsproc_read_2_svc(readargs *, struct svc_req *); +#define NFSPROC_WRITECACHE ((u_long)7) +extern "C" void * nfsproc_writecache_2(void *, CLIENT *); +extern "C" void * nfsproc_writecache_2_svc(void *, struct svc_req *); +#define NFSPROC_WRITE ((u_long)8) +extern "C" attrstat * nfsproc_write_2(writeargs *, CLIENT *); +extern "C" attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *); +#define NFSPROC_CREATE ((u_long)9) +extern "C" diropres * nfsproc_create_2(createargs *, CLIENT *); +extern "C" diropres * nfsproc_create_2_svc(createargs *, struct svc_req *); +#define NFSPROC_REMOVE ((u_long)10) +extern "C" nfsstat * nfsproc_remove_2(diropargs *, CLIENT *); +extern "C" nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_RENAME ((u_long)11) +extern "C" nfsstat * nfsproc_rename_2(renameargs *, CLIENT *); +extern "C" nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *); +#define NFSPROC_LINK ((u_long)12) +extern "C" nfsstat * nfsproc_link_2(linkargs *, CLIENT *); +extern "C" nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *); +#define NFSPROC_SYMLINK ((u_long)13) +extern "C" nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *); +extern "C" nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *); +#define NFSPROC_MKDIR ((u_long)14) +extern "C" diropres * nfsproc_mkdir_2(createargs *, CLIENT *); +extern "C" diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *); +#define NFSPROC_RMDIR ((u_long)15) +extern "C" nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *); +extern "C" nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_READDIR ((u_long)16) +extern "C" readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *); +extern "C" readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *); +#define NFSPROC_STATFS ((u_long)17) +extern "C" statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *); +extern "C" statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *); + +#elif __STDC__ +#define NFSPROC_NULL ((u_long)0) +extern void * nfsproc_null_2(void *, CLIENT *); +extern void * nfsproc_null_2_svc(void *, struct svc_req *); +#define NFSPROC_GETATTR ((u_long)1) +extern attrstat * nfsproc_getattr_2(nfs_fh *, CLIENT *); +extern attrstat * nfsproc_getattr_2_svc(nfs_fh *, struct svc_req *); +#define NFSPROC_SETATTR ((u_long)2) +extern attrstat * nfsproc_setattr_2(sattrargs *, CLIENT *); +extern attrstat * nfsproc_setattr_2_svc(sattrargs *, struct svc_req *); +#define NFSPROC_ROOT ((u_long)3) +extern void * nfsproc_root_2(void *, CLIENT *); +extern void * nfsproc_root_2_svc(void *, struct svc_req *); +#define NFSPROC_LOOKUP ((u_long)4) +extern diropres * nfsproc_lookup_2(diropargs *, CLIENT *); +extern diropres * nfsproc_lookup_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_READLINK ((u_long)5) +extern readlinkres * nfsproc_readlink_2(nfs_fh *, CLIENT *); +extern readlinkres * nfsproc_readlink_2_svc(nfs_fh *, struct svc_req *); +#define NFSPROC_READ ((u_long)6) +extern readres * nfsproc_read_2(readargs *, CLIENT *); +extern readres * nfsproc_read_2_svc(readargs *, struct svc_req *); +#define NFSPROC_WRITECACHE ((u_long)7) +extern void * nfsproc_writecache_2(void *, CLIENT *); +extern void * nfsproc_writecache_2_svc(void *, struct svc_req *); +#define NFSPROC_WRITE ((u_long)8) +extern attrstat * nfsproc_write_2(writeargs *, CLIENT *); +extern attrstat * nfsproc_write_2_svc(writeargs *, struct svc_req *); +#define NFSPROC_CREATE ((u_long)9) +extern diropres * nfsproc_create_2(createargs *, CLIENT *); +extern diropres * nfsproc_create_2_svc(createargs *, struct svc_req *); +#define NFSPROC_REMOVE ((u_long)10) +extern nfsstat * nfsproc_remove_2(diropargs *, CLIENT *); +extern nfsstat * nfsproc_remove_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_RENAME ((u_long)11) +extern nfsstat * nfsproc_rename_2(renameargs *, CLIENT *); +extern nfsstat * nfsproc_rename_2_svc(renameargs *, struct svc_req *); +#define NFSPROC_LINK ((u_long)12) +extern nfsstat * nfsproc_link_2(linkargs *, CLIENT *); +extern nfsstat * nfsproc_link_2_svc(linkargs *, struct svc_req *); +#define NFSPROC_SYMLINK ((u_long)13) +extern nfsstat * nfsproc_symlink_2(symlinkargs *, CLIENT *); +extern nfsstat * nfsproc_symlink_2_svc(symlinkargs *, struct svc_req *); +#define NFSPROC_MKDIR ((u_long)14) +extern diropres * nfsproc_mkdir_2(createargs *, CLIENT *); +extern diropres * nfsproc_mkdir_2_svc(createargs *, struct svc_req *); +#define NFSPROC_RMDIR ((u_long)15) +extern nfsstat * nfsproc_rmdir_2(diropargs *, CLIENT *); +extern nfsstat * nfsproc_rmdir_2_svc(diropargs *, struct svc_req *); +#define NFSPROC_READDIR ((u_long)16) +extern readdirres * nfsproc_readdir_2(readdirargs *, CLIENT *); +extern readdirres * nfsproc_readdir_2_svc(readdirargs *, struct svc_req *); +#define NFSPROC_STATFS ((u_long)17) +extern statfsres * nfsproc_statfs_2(nfs_fh *, CLIENT *); +extern statfsres * nfsproc_statfs_2_svc(nfs_fh *, struct svc_req *); + +#else /* Old Style C */ +#define NFSPROC_NULL ((u_long)0) +extern void * nfsproc_null_2(); +extern void * nfsproc_null_2_svc(); +#define NFSPROC_GETATTR ((u_long)1) +extern attrstat * nfsproc_getattr_2(); +extern attrstat * nfsproc_getattr_2_svc(); +#define NFSPROC_SETATTR ((u_long)2) +extern attrstat * nfsproc_setattr_2(); +extern attrstat * nfsproc_setattr_2_svc(); +#define NFSPROC_ROOT ((u_long)3) +extern void * nfsproc_root_2(); +extern void * nfsproc_root_2_svc(); +#define NFSPROC_LOOKUP ((u_long)4) +extern diropres * nfsproc_lookup_2(); +extern diropres * nfsproc_lookup_2_svc(); +#define NFSPROC_READLINK ((u_long)5) +extern readlinkres * nfsproc_readlink_2(); +extern readlinkres * nfsproc_readlink_2_svc(); +#define NFSPROC_READ ((u_long)6) +extern readres * nfsproc_read_2(); +extern readres * nfsproc_read_2_svc(); +#define NFSPROC_WRITECACHE ((u_long)7) +extern void * nfsproc_writecache_2(); +extern void * nfsproc_writecache_2_svc(); +#define NFSPROC_WRITE ((u_long)8) +extern attrstat * nfsproc_write_2(); +extern attrstat * nfsproc_write_2_svc(); +#define NFSPROC_CREATE ((u_long)9) +extern diropres * nfsproc_create_2(); +extern diropres * nfsproc_create_2_svc(); +#define NFSPROC_REMOVE ((u_long)10) +extern nfsstat * nfsproc_remove_2(); +extern nfsstat * nfsproc_remove_2_svc(); +#define NFSPROC_RENAME ((u_long)11) +extern nfsstat * nfsproc_rename_2(); +extern nfsstat * nfsproc_rename_2_svc(); +#define NFSPROC_LINK ((u_long)12) +extern nfsstat * nfsproc_link_2(); +extern nfsstat * nfsproc_link_2_svc(); +#define NFSPROC_SYMLINK ((u_long)13) +extern nfsstat * nfsproc_symlink_2(); +extern nfsstat * nfsproc_symlink_2_svc(); +#define NFSPROC_MKDIR ((u_long)14) +extern diropres * nfsproc_mkdir_2(); +extern diropres * nfsproc_mkdir_2_svc(); +#define NFSPROC_RMDIR ((u_long)15) +extern nfsstat * nfsproc_rmdir_2(); +extern nfsstat * nfsproc_rmdir_2_svc(); +#define NFSPROC_READDIR ((u_long)16) +extern readdirres * nfsproc_readdir_2(); +extern readdirres * nfsproc_readdir_2_svc(); +#define NFSPROC_STATFS ((u_long)17) +extern statfsres * nfsproc_statfs_2(); +extern statfsres * nfsproc_statfs_2_svc(); +#endif /* Old Style C */ + +#endif /* !_NFS_PROT_H_RPCGEN */ diff --git a/tdeioslave/nfs/nfs_prot.x b/tdeioslave/nfs/nfs_prot.x new file mode 100644 index 000000000..cd21123c7 --- /dev/null +++ b/tdeioslave/nfs/nfs_prot.x @@ -0,0 +1,365 @@ +%/* +% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for +% * unrestricted use provided that this legend is included on all tape +% * media and as a part of the software program in whole or part. Users +% * may copy or modify Sun RPC without charge, but are not authorized +% * to license or distribute it to anyone else except as part of a product or +% * program developed by the user or with the express written consent of +% * Sun Microsystems, Inc. +% * +% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE +% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. +% * +% * Sun RPC is provided with no support and without any obligation on the +% * part of Sun Microsystems, Inc. to assist in its use, correction, +% * modification or enhancement. +% * +% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE +% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC +% * OR ANY PART THEREOF. +% * +% * In no event will Sun Microsystems, Inc. be liable for any lost revenue +% * or profits or other special, indirect and consequential damages, even if +% * Sun has been advised of the possibility of such damages. +% * +% * Sun Microsystems, Inc. +% * 2550 Garcia Avenue +% * Mountain View, California 94043 +% */ + +%/* +% * Copyright (c) 1987, 1990 by Sun Microsystems, Inc. +% */ +% +%/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */ + +#ifdef RPC_HDR +%#ifndef _rpcsvc_nfs_prot_h +%#define _rpcsvc_nfs_prot_h +#endif + +const NFS_PORT = 2049; +const NFS_MAXDATA = 8192; +const NFS_MAXPATHLEN = 1024; +const NFS_MAXNAMLEN = 255; +const NFS_FHSIZE = 32; +const NFS_COOKIESIZE = 4; +const NFS_FIFO_DEV = -1; /* size kludge for named pipes */ + +/* + * File types + */ +const NFSMODE_FMT = 0170000; /* type of file */ +const NFSMODE_DIR = 0040000; /* directory */ +const NFSMODE_CHR = 0020000; /* character special */ +const NFSMODE_BLK = 0060000; /* block special */ +const NFSMODE_REG = 0100000; /* regular */ +const NFSMODE_LNK = 0120000; /* symbolic link */ +const NFSMODE_SOCK = 0140000; /* socket */ +const NFSMODE_FIFO = 0010000; /* fifo */ + +/* + * Error status + */ +enum nfsstat { + NFS_OK= 0, /* no error */ + NFSERR_PERM=1, /* Not owner */ + NFSERR_NOENT=2, /* No such file or directory */ + NFSERR_IO=5, /* I/O error */ + NFSERR_NXIO=6, /* No such device or address */ + NFSERR_ACCES=13, /* Permission denied */ + NFSERR_EXIST=17, /* File exists */ + NFSERR_NODEV=19, /* No such device */ + NFSERR_NOTDIR=20, /* Not a directory*/ + NFSERR_ISDIR=21, /* Is a directory */ + NFSERR_INVAL=22, /* invalid argument */ + NFSERR_FBIG=27, /* File too large */ + NFSERR_NOSPC=28, /* No space left on device */ + NFSERR_ROFS=30, /* Read-only file system */ + NFSERR_NAMETOOLONG=63, /* File name too long */ + NFSERR_NOTEMPTY=66, /* Directory not empty */ + NFSERR_DQUOT=69, /* Disc quota exceeded */ + NFSERR_STALE=70, /* Stale NFS file handle */ + NFSERR_WFLUSH=99 /* write cache flushed */ +}; + +/* + * File types + */ +enum ftype { + NFNON = 0, /* non-file */ + NFREG = 1, /* regular file */ + NFDIR = 2, /* directory */ + NFBLK = 3, /* block special */ + NFCHR = 4, /* character special */ + NFLNK = 5, /* symbolic link */ + NFSOCK = 6, /* unix domain sockets */ + NFBAD = 7, /* unused */ + NFFIFO = 8 /* named pipe */ +}; + +/* + * File access handle + */ +struct nfs_fh { + opaque data[NFS_FHSIZE]; +}; + +/* + * Timeval + */ +struct nfstime { + unsigned seconds; + unsigned useconds; +}; + + +/* + * File attributes + */ +struct fattr { + ftype type; /* file type */ + unsigned mode; /* protection mode bits */ + unsigned nlink; /* # hard links */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + unsigned blocksize; /* prefered block size */ + unsigned rdev; /* special device # */ + unsigned blocks; /* Kb of disk used by file */ + unsigned fsid; /* device # */ + unsigned fileid; /* inode # */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ + nfstime ctime; /* time of last change */ +}; + +/* + * File attributes which can be set + */ +struct sattr { + unsigned mode; /* protection mode bits */ + unsigned uid; /* owner user id */ + unsigned gid; /* owner group id */ + unsigned size; /* file size in bytes */ + nfstime atime; /* time of last access */ + nfstime mtime; /* time of last modification */ +}; + + +typedef string filename<NFS_MAXNAMLEN>; +typedef string nfspath<NFS_MAXPATHLEN>; + +/* + * Reply status with file attributes + */ +union attrstat switch (nfsstat status) { +case NFS_OK: + fattr attributes; +default: + void; +}; + +struct sattrargs { + nfs_fh file; + sattr attributes; +}; + +/* + * Arguments for directory operations + */ +struct diropargs { + nfs_fh dir; /* directory file handle */ + filename name; /* name (up to NFS_MAXNAMLEN bytes) */ +}; + +struct diropokres { + nfs_fh file; + fattr attributes; +}; + +/* + * Results from directory operation + */ +union diropres switch (nfsstat status) { +case NFS_OK: + diropokres diropres; +default: + void; +}; + +union readlinkres switch (nfsstat status) { +case NFS_OK: + nfspath data; +default: + void; +}; + +/* + * Arguments to remote read + */ +struct readargs { + nfs_fh file; /* handle for file */ + unsigned offset; /* byte offset in file */ + unsigned count; /* immediate read count */ + unsigned totalcount; /* total read count (from this offset)*/ +}; + +/* + * Status OK portion of remote read reply + */ +struct readokres { + fattr attributes; /* attributes, need for pagin*/ + opaque data<NFS_MAXDATA>; +}; + +union readres switch (nfsstat status) { +case NFS_OK: + readokres reply; +default: + void; +}; + +/* + * Arguments to remote write + */ +struct writeargs { + nfs_fh file; /* handle for file */ + unsigned beginoffset; /* beginning byte offset in file */ + unsigned offset; /* current byte offset in file */ + unsigned totalcount; /* total write count (to this offset)*/ + opaque data<NFS_MAXDATA>; +}; + +struct createargs { + diropargs where; + sattr attributes; +}; + +struct renameargs { + diropargs from; + diropargs to; +}; + +struct linkargs { + nfs_fh from; + diropargs to; +}; + +struct symlinkargs { + diropargs from; + nfspath to; + sattr attributes; +}; + + +typedef opaque nfscookie[NFS_COOKIESIZE]; + +/* + * Arguments to readdir + */ +struct readdirargs { + nfs_fh dir; /* directory handle */ + nfscookie cookie; + unsigned count; /* number of directory bytes to read */ +}; + +struct entry { + unsigned fileid; + filename name; + nfscookie cookie; + entry *nextentry; +}; + +struct dirlist { + entry *entries; + bool eof; +}; + +union readdirres switch (nfsstat status) { +case NFS_OK: + dirlist reply; +default: + void; +}; + +struct statfsokres { + unsigned tsize; /* preferred transfer size in bytes */ + unsigned bsize; /* fundamental file system block size */ + unsigned blocks; /* total blocks in file system */ + unsigned bfree; /* free blocks in fs */ + unsigned bavail; /* free blocks avail to non-superuser */ +}; + +union statfsres switch (nfsstat status) { +case NFS_OK: + statfsokres reply; +default: + void; +}; + +/* + * Remote file service routines + */ +program NFS_PROGRAM { + version NFS_VERSION { + void + NFSPROC_NULL(void) = 0; + + attrstat + NFSPROC_GETATTR(nfs_fh) = 1; + + attrstat + NFSPROC_SETATTR(sattrargs) = 2; + + void + NFSPROC_ROOT(void) = 3; + + diropres + NFSPROC_LOOKUP(diropargs) = 4; + + readlinkres + NFSPROC_READLINK(nfs_fh) = 5; + + readres + NFSPROC_READ(readargs) = 6; + + void + NFSPROC_WRITECACHE(void) = 7; + + attrstat + NFSPROC_WRITE(writeargs) = 8; + + diropres + NFSPROC_CREATE(createargs) = 9; + + nfsstat + NFSPROC_REMOVE(diropargs) = 10; + + nfsstat + NFSPROC_RENAME(renameargs) = 11; + + nfsstat + NFSPROC_LINK(linkargs) = 12; + + nfsstat + NFSPROC_SYMLINK(symlinkargs) = 13; + + diropres + NFSPROC_MKDIR(createargs) = 14; + + nfsstat + NFSPROC_RMDIR(diropargs) = 15; + + readdirres + NFSPROC_READDIR(readdirargs) = 16; + + statfsres + NFSPROC_STATFS(nfs_fh) = 17; + } = 2; +} = 100003; + +#ifdef RPC_HDR +%#endif /*!_rpcsvc_nfs_prot_h*/ +#endif diff --git a/tdeioslave/nfs/nfs_prot_xdr.c b/tdeioslave/nfs/nfs_prot_xdr.c new file mode 100644 index 000000000..57d446489 --- /dev/null +++ b/tdeioslave/nfs/nfs_prot_xdr.c @@ -0,0 +1,886 @@ +/* + * Please do not edit this file. + * It was generated using rpcgen. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <arpa/inet.h> + +#include "nfs_prot.h" +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Copyright (c) 1987, 1990 by Sun Microsystems, Inc. + */ + +/* from @(#)nfs_prot.x 1.3 91/03/11 TIRPC 1.0 */ + +bool_t +xdr_nfsstat(XDR *xdrs, nfsstat *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_ftype(XDR *xdrs, ftype *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_enum(xdrs, (enum_t *)objp)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_nfs_fh(XDR *xdrs, nfs_fh *objp) +{ + + register int32_t *buf=buf; + + int i=i; + if (!xdr_opaque(xdrs, objp->data, NFS_FHSIZE)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_nfstime(XDR *xdrs, nfstime *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_u_int(xdrs, &objp->seconds)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->useconds)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_fattr(XDR *xdrs, fattr *objp) +{ + + register int32_t *buf=buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_ftype(xdrs, &objp->type)) { + return (FALSE); + } + buf = XDR_INLINE(xdrs,10 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->nlink)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocksize)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->rdev)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocks)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fsid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fileid)) { + return (FALSE); + } + + } + else { + IXDR_PUT_U_LONG(buf,objp->mode); + IXDR_PUT_U_LONG(buf,objp->nlink); + IXDR_PUT_U_LONG(buf,objp->uid); + IXDR_PUT_U_LONG(buf,objp->gid); + IXDR_PUT_U_LONG(buf,objp->size); + IXDR_PUT_U_LONG(buf,objp->blocksize); + IXDR_PUT_U_LONG(buf,objp->rdev); + IXDR_PUT_U_LONG(buf,objp->blocks); + IXDR_PUT_U_LONG(buf,objp->fsid); + IXDR_PUT_U_LONG(buf,objp->fileid); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->ctime)) { + return (FALSE); + } + + return (TRUE); + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_ftype(xdrs, &objp->type)) { + return (FALSE); + } + buf = XDR_INLINE(xdrs,10 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->nlink)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocksize)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->rdev)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocks)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fsid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fileid)) { + return (FALSE); + } + + } + else { + objp->mode = IXDR_GET_U_LONG(buf); + objp->nlink = IXDR_GET_U_LONG(buf); + objp->uid = IXDR_GET_U_LONG(buf); + objp->gid = IXDR_GET_U_LONG(buf); + objp->size = IXDR_GET_U_LONG(buf); + objp->blocksize = IXDR_GET_U_LONG(buf); + objp->rdev = IXDR_GET_U_LONG(buf); + objp->blocks = IXDR_GET_U_LONG(buf); + objp->fsid = IXDR_GET_U_LONG(buf); + objp->fileid = IXDR_GET_U_LONG(buf); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->ctime)) { + return (FALSE); + } + return(TRUE); + } + + if (!xdr_ftype(xdrs, &objp->type)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->nlink)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocksize)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->rdev)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->blocks)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fsid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->fileid)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->ctime)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_sattr(XDR *xdrs, sattr *objp) +{ + + register int32_t *buf=buf; + + + if (xdrs->x_op == XDR_ENCODE) { + buf = XDR_INLINE(xdrs,4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + + } + else { + IXDR_PUT_U_LONG(buf,objp->mode); + IXDR_PUT_U_LONG(buf,objp->uid); + IXDR_PUT_U_LONG(buf,objp->gid); + IXDR_PUT_U_LONG(buf,objp->size); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + + return (TRUE); + } else if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE(xdrs,4 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + + } + else { + objp->mode = IXDR_GET_U_LONG(buf); + objp->uid = IXDR_GET_U_LONG(buf); + objp->gid = IXDR_GET_U_LONG(buf); + objp->size = IXDR_GET_U_LONG(buf); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + return(TRUE); + } + + if (!xdr_u_int(xdrs, &objp->mode)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->uid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->gid)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->size)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->atime)) { + return (FALSE); + } + if (!xdr_nfstime(xdrs, &objp->mtime)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_filename(XDR *xdrs, filename *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_string(xdrs, objp, NFS_MAXNAMLEN)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_nfspath(XDR *xdrs, nfspath *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_attrstat(XDR *xdrs, attrstat *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_fattr(xdrs, &objp->attrstat_u.attributes)) { + return (FALSE); + } + break; + default: + break; + } + return (TRUE); +} + +bool_t +xdr_sattrargs(XDR *xdrs, sattrargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_sattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_diropargs(XDR *xdrs, diropargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfs_fh(xdrs, &objp->dir)) { + return (FALSE); + } + if (!xdr_filename(xdrs, &objp->name)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_diropokres(XDR *xdrs, diropokres *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_fattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_diropres(XDR *xdrs, diropres *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_diropokres(xdrs, &objp->diropres_u.diropres)) { + return (FALSE); + } + break; + default: + break; + } + return (TRUE); +} + +bool_t +xdr_readlinkres(XDR *xdrs, readlinkres *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_nfspath(xdrs, &objp->readlinkres_u.data)) { + return (FALSE); + } + break; + default: + break; + } + return (TRUE); +} + +bool_t +xdr_readargs(XDR *xdrs, readargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->offset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->count)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->totalcount)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_readokres(XDR *xdrs, readokres *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_fattr(xdrs, &objp->attributes)) { + return (FALSE); + } + if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_readres(XDR *xdrs, readres *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfsstat(xdrs, &objp->status)) { + return (FALSE); + } + switch (objp->status) { + case NFS_OK: + if (!xdr_readokres(xdrs, &objp->readres_u.reply)) { + return (FALSE); + } + break; + default: + break; + } + return (TRUE); +} + +bool_t +xdr_writeargs(XDR *xdrs, writeargs *objp) +{ + + register int32_t *buf=buf; + + + if (xdrs->x_op == XDR_ENCODE) { + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + buf = XDR_INLINE(xdrs,3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int(xdrs, &objp->beginoffset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->offset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->totalcount)) { + return (FALSE); + } + + } + else { + IXDR_PUT_U_LONG(buf,objp->beginoffset); + IXDR_PUT_U_LONG(buf,objp->offset); + IXDR_PUT_U_LONG(buf,objp->totalcount); + } + if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) { + return (FALSE); + } + + return (TRUE); + } else if (xdrs->x_op == XDR_DECODE) { + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + buf = XDR_INLINE(xdrs,3 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (!xdr_u_int(xdrs, &objp->beginoffset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->offset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->totalcount)) { + return (FALSE); + } + + } + else { + objp->beginoffset = IXDR_GET_U_LONG(buf); + objp->offset = IXDR_GET_U_LONG(buf); + objp->totalcount = IXDR_GET_U_LONG(buf); + } + if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) { + return (FALSE); + } + return(TRUE); + } + + if (!xdr_nfs_fh(xdrs, &objp->file)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->beginoffset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->offset)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->totalcount)) { + return (FALSE); + } + if (!xdr_bytes(xdrs, (char **)&objp->data.data_val, (u_int *)&objp->data.data_len, NFS_MAXDATA)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_createargs(XDR *xdrs, createargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_diropargs(xdrs, &objp->where)) { + return (FALSE); + } + if (!xdr_sattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_renameargs(XDR *xdrs, renameargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_diropargs(xdrs, &objp->from)) { + return (FALSE); + } + if (!xdr_diropargs(xdrs, &objp->to)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_linkargs(XDR *xdrs, linkargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfs_fh(xdrs, &objp->from)) { + return (FALSE); + } + if (!xdr_diropargs(xdrs, &objp->to)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_symlinkargs(XDR *xdrs, symlinkargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_diropargs(xdrs, &objp->from)) { + return (FALSE); + } + if (!xdr_nfspath(xdrs, &objp->to)) { + return (FALSE); + } + if (!xdr_sattr(xdrs, &objp->attributes)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_nfscookie(XDR *xdrs, nfscookie objp) +{ + + register int32_t *buf=buf; + + if (!xdr_opaque(xdrs, objp, NFS_COOKIESIZE)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_readdirargs(XDR *xdrs, readdirargs *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_nfs_fh(xdrs, &objp->dir)) { + return (FALSE); + } + if (!xdr_nfscookie(xdrs, objp->cookie)) { + return (FALSE); + } + if (!xdr_u_int(xdrs, &objp->count)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_entry(XDR *xdrs, entry *objp) +{ + + register int32_t *buf=buf; + + if (!xdr_u_int(xdrs, &objp->fileid)) { + return (FALSE); + } + if (!xdr_filename(xdrs, &objp->name)) { + return (FALSE); + } + if (!xdr_nfscookie(xdrs, objp->cookie)) { + return (FALSE); + } + if (!xdr_pointer(xdrs, &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); +} |