summaryrefslogtreecommitdiffstats
path: root/kioslave/smb/kio_smb_file.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kioslave/smb/kio_smb_file.cpp')
-rw-r--r--kioslave/smb/kio_smb_file.cpp279
1 files changed, 279 insertions, 0 deletions
diff --git a/kioslave/smb/kio_smb_file.cpp b/kioslave/smb/kio_smb_file.cpp
new file mode 100644
index 000000000..67fe0d213
--- /dev/null
+++ b/kioslave/smb/kio_smb_file.cpp
@@ -0,0 +1,279 @@
+////////////////////////////////////////////////////////////////////////////
+//
+// Project: SMB kioslave for KDE2
+//
+// File: kio_smb_file.cpp
+//
+// Abstract: member function implementations for SMBSlave that deal with
+// SMB file access
+//
+// Author(s): Matthew Peterson <[email protected]>
+//
+//---------------------------------------------------------------------------
+//
+// Copyright (c) 2000 Caldera Systems, Inc.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2.1 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, please obtain
+// a copy from http://www.gnu.org/copyleft/gpl.html
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+#include "kio_smb.h"
+#include "kio_smb_internal.h"
+
+#include <kmimetype.h>
+
+//===========================================================================
+void SMBSlave::get( const KURL& kurl )
+{
+ char buf[MAX_XFER_BUF_SIZE];
+ int filefd = 0;
+ ssize_t bytesread = 0;
+ // time_t curtime = 0;
+ time_t lasttime = 0;
+ time_t starttime = 0;
+ KIO::filesize_t totalbytesread = 0;
+ QByteArray filedata;
+ SMBUrl url;
+
+ kdDebug(KIO_SMB) << "SMBSlave::get on " << kurl << endl;
+
+ // check (correct) URL
+ KURL kvurl = checkURL(kurl);
+ // if URL is not valid we have to redirect to correct URL
+ if (kvurl != kurl) {
+ redirection(kvurl);
+ finished();
+ return;
+ }
+
+ if(!auth_initialize_smbc())
+ return;
+
+
+ // Stat
+ url = kurl;
+ if(cache_stat(url,&st) == -1 )
+ {
+ if ( errno == EACCES )
+ error( KIO::ERR_ACCESS_DENIED, url.prettyURL());
+ else
+ error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL());
+ return;
+ }
+ if ( S_ISDIR( st.st_mode ) ) {
+ error( KIO::ERR_IS_DIRECTORY, url.prettyURL());
+ return;
+ }
+
+ // Set the total size
+ totalSize( st.st_size );
+
+ // Open and read the file
+ filefd = smbc_open(url.toSmbcUrl(),O_RDONLY,0);
+ if(filefd >= 0)
+ {
+ if(buf)
+ {
+ bool isFirstPacket = true;
+ lasttime = starttime = time(NULL);
+ while(1)
+ {
+ bytesread = smbc_read(filefd, buf, MAX_XFER_BUF_SIZE);
+ if(bytesread == 0)
+ {
+ // All done reading
+ break;
+ }
+ else if(bytesread < 0)
+ {
+ error( KIO::ERR_COULD_NOT_READ, url.prettyURL());
+ return;
+ }
+
+ filedata.setRawData(buf,bytesread);
+ if (isFirstPacket)
+ {
+ // We need a KMimeType::findByNameAndContent(filename,data)
+ // For now we do: find by extension, and if not found (or extension not reliable)
+ // then find by content.
+ bool accurate = false;
+ KMimeType::Ptr mime = KMimeType::findByURL( kurl, st.st_mode, false, true, &accurate );
+ if ( !mime || mime->name() == KMimeType::defaultMimeType()
+ || !accurate )
+ {
+ KMimeType::Ptr p_mimeType = KMimeType::findByContent(filedata);
+ if ( p_mimeType && p_mimeType->name() != KMimeType::defaultMimeType() )
+ mime = p_mimeType;
+ }
+ mimeType(mime->name());
+ isFirstPacket = false;
+ }
+ data( filedata );
+ filedata.resetRawData(buf,bytesread);
+
+ // increment total bytes read
+ totalbytesread += bytesread;
+
+ processedSize(totalbytesread);
+ }
+ }
+
+ smbc_close(filefd);
+ data( QByteArray() );
+ processedSize(static_cast<KIO::filesize_t>(st.st_size));
+
+ }
+ else
+ {
+ error( KIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL());
+ return;
+ }
+
+ finished();
+}
+
+
+//===========================================================================
+void SMBSlave::put( const KURL& kurl,
+ int permissions,
+ bool overwrite,
+ bool resume )
+{
+
+ void *buf;
+ size_t bufsize;
+
+ m_current_url = kurl;
+
+ int filefd;
+ bool exists;
+ mode_t mode;
+ QByteArray filedata;
+
+ kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl << endl;
+
+
+ exists = (cache_stat(m_current_url, &st) != -1 );
+ if ( exists && !overwrite && !resume)
+ {
+ if (S_ISDIR(st.st_mode))
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already isdir !!"<< endl;
+ error( KIO::ERR_DIR_ALREADY_EXIST, m_current_url.prettyURL());
+ }
+ else
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already exist !!"<< endl;
+ error( KIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyURL());
+ }
+ return;
+ }
+
+ if (exists && !resume && overwrite)
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put exists try to remove " << m_current_url.toSmbcUrl()<< endl;
+ // remove(m_current_url.url().local8Bit());
+ }
+
+
+ if (resume)
+ {
+ // append if resuming
+ kdDebug(KIO_SMB) << "SMBSlave::put resume " << m_current_url.toSmbcUrl()<< endl;
+ filefd = smbc_open(m_current_url.toSmbcUrl(), O_RDWR, 0 );
+ smbc_lseek(filefd, 0, SEEK_END);
+ }
+ else
+ {
+ if (permissions != -1)
+ {
+ mode = permissions | S_IWUSR | S_IRUSR;
+ }
+ else
+ {
+ mode = 600;//0666;
+ }
+
+ kdDebug(KIO_SMB) << "SMBSlave::put NO resume " << m_current_url.toSmbcUrl()<< endl;
+ filefd = smbc_open(m_current_url.toSmbcUrl(), O_CREAT | O_TRUNC | O_WRONLY, mode);
+ }
+
+ if ( filefd < 0 )
+ {
+ if ( errno == EACCES )
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" access denied !!"<< endl;
+ error( KIO::ERR_WRITE_ACCESS_DENIED, m_current_url.prettyURL());
+ }
+ else
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" can not open for writing !!"<< endl;
+ error( KIO::ERR_CANNOT_OPEN_FOR_WRITING, m_current_url.prettyURL());
+ }
+ finished();
+ return;
+ }
+
+ // Loop until we got 0 (end of data)
+ while(1)
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put request data "<< endl;
+ dataReq(); // Request for data
+ kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl;
+
+ if (readData(filedata) <= 0)
+ {
+ kdDebug(KIO_SMB) << "readData <= 0" << endl;
+ break;
+ }
+ kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl;
+ buf = filedata.data();
+ bufsize = filedata.size();
+ int size = smbc_write(filefd, buf, bufsize);
+ if ( size < 0)
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" could not write !!"<< endl;
+ error( KIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL());
+ finished();
+ return;
+ }
+ kdDebug(KIO_SMB ) << "wrote " << size << endl;
+ }
+ kdDebug(KIO_SMB) << "SMBSlave::put close " << m_current_url.toSmbcUrl()<< endl;
+
+ if(smbc_close(filefd))
+ {
+ kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" could not write !!"<< endl;
+ error( KIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL());
+ finished();
+ return;
+ }
+
+ // set final permissions, if the file was just created
+ if ( permissions != -1 && !exists )
+ {
+ // TODO: did the smbc_chmod fail?
+ // TODO: put in call to chmod when it is working!
+ // smbc_chmod(url.toSmbcUrl(),permissions);
+ }
+
+ // We have done our job => finish
+ finished();
+}
+
+
+
+