--0-1798721820-1210124127=:87480 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Content-Id: Content-Disposition: inline Hi, I'd like to commit the attached KIO fixes to kdelibs and kdebase. Following are descriptions of the patches: file_fix_open_flags.diff: - Fix translation of the mode from QIODevice to POSIX flag. smb_fixes.diff: - Don't rely on errno because its value changes after the first read. Instead, save its value in a new variable. - Ensure passed parameters and return values to samba functions match their prototype in libsmbclient.h . - Fix file open flags in FileJob functions - Implement SMBSlave::write sftp_fix_open_flags.diff: - Fix translation of the mode from QIODevice to POSIX flag. respect_copyjob_permissions.diff: - Fix KIO::file_move to respect its permissions parameter instead of just ignoring it. KIO::file_copy already respects the user-specified permissions. kdelibs_largefile.diff: - Compile kdelibs with -D_LARGE_FILES instead of -D_LARGEFILE64_SOURCE, and drop the redundant -D_LARGEFILE64_SOURCE flag in kio. kdebase_largefile.diff: - Compile kdebase with -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE to support large files. Please let me know if there are any objections to my committing these fixes. Thanks, Vlad ____________________________________________________________________________________ Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ --0-1798721820-1210124127=:87480 Content-Type: text/x-patch; name="file_fix_open_flags.diff" Content-Description: 3106349870-file_fix_open_flags.diff Content-Disposition: inline; filename="file_fix_open_flags.diff" Index: kioslave/file/file.cpp =================================================================== --- kioslave/file/file.cpp (revision 804348) +++ kioslave/file/file.cpp (working copy) @@ -470,17 +470,19 @@ int flags = 0; if (mode & QIODevice::ReadOnly) { - flags |= O_RDONLY; + if (mode & QIODevice::WriteOnly) { + flags = O_RDWR | O_CREAT; + } else { + flags = O_RDONLY; + } + } else if (mode & QIODevice::WriteOnly) { + flags = O_WRONLY | O_CREAT; } - if (mode & QIODevice::WriteOnly) { - flags |= O_WRONLY | O_CREAT; - } + if (mode & QIODevice::Append) { - flags |= O_WRONLY | O_APPEND; - } else if (mode & QIODevice::WriteOnly) { - if (!(mode & QIODevice::ReadOnly) || mode & QIODevice::Truncate) { - flags |= O_TRUNC; - } + flags |= O_APPEND; + } else if (mode & QIODevice::Truncate) { + flags |= O_TRUNC; } int fd = KDE_open( openPath.data(), flags); @@ -490,8 +492,12 @@ } // Determine the mimetype of the file to be retrieved, and emit it. // This is mandatory in all slaves (for KRun/BrowserRun to work). - KMimeType::Ptr mt = KMimeType::findByUrl( url, buff.st_mode, true /* local URL */ ); - emit mimeType( mt->name() ); + // If we're not opening the file ReadOnly or ReadWrite, don't attempt to + // read the file and send the mimetype. + if (mode & QIODevice::ReadOnly){ + KMimeType::Ptr mt = KMimeType::findByUrl( url, buff.st_mode, true /* local URL */ ); + emit mimeType( mt->name() ); + } totalSize( buff.st_size ); position( 0 ); --0-1798721820-1210124127=:87480 Content-Type: text/x-patch; name="kdebase_largefile.diff" Content-Description: 2252635123-kdebase_largefile.diff Content-Disposition: inline; filename="kdebase_largefile.diff" Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 804348) +++ CMakeLists.txt (working copy) @@ -7,6 +7,8 @@ include (MacroLibrary) include(MacroOptionalAddSubdirectory) +add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE) # for off_t + # are these two really required ? find_package(ZLIB REQUIRED) if (APPLE) --0-1798721820-1210124127=:87480 Content-Type: text/x-patch; name="kdelibs_largefile.diff" Content-Description: 706246257-kdelibs_largefile.diff Content-Disposition: inline; filename="kdelibs_largefile.diff" Index: CMakeLists.txt =================================================================== --- CMakeLists.txt (revision 804348) +++ CMakeLists.txt (working copy) @@ -61,7 +61,7 @@ ######################################################################### -add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES) # for off_t +add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE) # for off_t remove_definitions(-DQT3_SUPPORT_WARNINGS -DQT3_SUPPORT) # for including config.h and for includes like Index: kio/CMakeLists.txt =================================================================== --- kio/CMakeLists.txt (revision 804348) +++ kio/CMakeLists.txt (working copy) @@ -1,8 +1,6 @@ project(kio) macro_optional_find_package(FAM) -add_definitions(-D_LARGEFILE64_SOURCE ) - if(OPENSSL_FOUND) set(KSSL_HAVE_SSL 1) include_directories(${OPENSSL_INCLUDE_DIR}) --0-1798721820-1210124127=:87480 Content-Type: text/x-patch; name="respect_copyjob_permissions.diff" Content-Description: 2315708230-respect_copyjob_permissions.diff Content-Disposition: inline; filename="respect_copyjob_permissions.diff" Index: kio/kio/job.cpp =================================================================== --- kio/kio/job.cpp (revision 804348) +++ kio/kio/job.cpp (working copy) @@ -1638,8 +1638,8 @@ FileCopyJobPrivate(const KUrl& src, const KUrl& dest, int permissions, bool move, JobFlags flags) : m_sourceSize(filesize_t(-1)), m_src(src), m_dest(dest), m_moveJob(0), m_copyJob(0), m_delJob(0), - m_getJob(0), m_putJob(0), m_permissions(permissions), - m_move(move), m_flags(flags) + m_chmodJob(0), m_getJob(0), m_putJob(0), m_permissions(permissions), + m_move(move), m_mustChmod(0), m_flags(flags) { } KIO::filesize_t m_sourceSize; @@ -1650,12 +1650,14 @@ SimpleJob *m_moveJob; SimpleJob *m_copyJob; SimpleJob *m_delJob; + SimpleJob *m_chmodJob; TransferJob *m_getJob; TransferJob *m_putJob; int m_permissions; bool m_move:1; bool m_canResume:1; bool m_resumeAnswerSent:1; + bool m_mustChmod:1; JobFlags m_flags; void startBestCopyMethod(); @@ -1831,6 +1833,7 @@ void FileCopyJobPrivate::startRenameJob(const KUrl &slave_url) { Q_Q(FileCopyJob); + m_mustChmod = true; // CMD_RENAME by itself doesn't change permissions KIO_ARGS << m_src << m_dest << (qint8) (m_flags & Overwrite); m_moveJob = SimpleJobPrivate::newJob(slave_url, CMD_RENAME, packedArgs); q->addSubjob( m_moveJob ); @@ -2110,6 +2113,12 @@ return; } + if (d->m_mustChmod) + { + d->m_chmodJob = chmod(d->m_dest, d->m_permissions); + d->m_mustChmod = false; + } + if (job == d->m_moveJob) { d->m_moveJob = 0; // Finished @@ -2152,6 +2161,12 @@ { d->m_delJob = 0; // Finished } + + if (job == d->m_chmodJob) + { + d->m_chmodJob = 0; // Finished + } + removeSubjob(job); if ( !hasSubjobs() ) emitResult(); --0-1798721820-1210124127=:87480 Content-Type: text/x-patch; name="sftp_fix_open_flags.diff" Content-Description: 1215049261-sftp_fix_open_flags.diff Content-Disposition: inline; filename="sftp_fix_open_flags.diff" Index: runtime/kioslave/sftp/kio_sftp.cpp =================================================================== --- runtime/kioslave/sftp/kio_sftp.cpp (revision 804348) +++ runtime/kioslave/sftp/kio_sftp.cpp (working copy) @@ -837,6 +837,7 @@ _DEBUG << url.url() << endl; openConnection(); if (!mConnected) { + error(KIO::ERR_CONNECTION_BROKEN, url.prettyUrl()); return; } @@ -865,60 +866,63 @@ attr.clear(); quint32 pflags = 0; + if (mode & QIODevice::ReadOnly) { - pflags |= SSH2_FXF_READ; + if (mode & QIODevice::WriteOnly) { + pflags = SSH2_FXF_READ | SSH2_FXF_WRITE | SSH2_FXF_CREAT; + } else { + pflags = SSH2_FXF_READ; + } + } else if (mode & QIODevice::WriteOnly) { + pflags = SSH2_FXF_WRITE | SSH2_FXF_CREAT; } - if (mode & QIODevice::WriteOnly) { - pflags |= SSH2_FXF_WRITE | SSH2_FXF_CREAT; - } + if (mode & QIODevice::Append) { - pflags |= SSH2_FXF_WRITE | SSH2_FXF_APPEND; - } else if (mode & QIODevice::WriteOnly) { - if (!(mode & QIODevice::ReadOnly) || mode & QIODevice::Truncate) { - pflags |= SSH2_FXF_TRUNC; - } + pflags |= SSH2_FXF_APPEND; + } else if (mode & QIODevice::Truncate) { + pflags |= SSH2_FXF_TRUNC; } - if (sftpOpen(url, pflags, attr, openHandle) != SSH2_FX_OK) { + code = sftpOpen(url, pflags, attr, openHandle); + if (code != SSH2_FX_OK) { _DEBUG << "sftpOpen error" << endl; - error(KIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyUrl()); + processStatus(code, url.prettyUrl()); return; } // Determine the mimetype of the file to be retrieved, and emit it. // This is mandatory in all slaves (for KRun/BrowserRun to work). - QByteArray buffer; - if ((code = sftpRead(openHandle, 0, 1024, buffer)) == SSH2_FX_OK) { + // If we're not opening the file ReadOnly or ReadWrite, don't attempt to + // read the file and send the mimetype. + if (mode & QIODevice::ReadOnly){ + QByteArray buffer; + code = sftpRead(openHandle, 0, 1024, buffer); + if ((code != SSH2_FX_OK) && (code != SSH2_FX_EOF)){ + _DEBUG << "error on mime type detection" << endl; + processStatus(code, url.prettyUrl()); + close(); + return; + } KMimeType::Ptr mime = KMimeType::findByNameAndContent(url.fileName(), buffer); mimeType(mime->name()); - totalSize(fileSize); - position(0); - opened(); - } else { - _DEBUG << "error on mime type detection" << endl; - processStatus(code, url.prettyUrl()); - return; } openUrl = url; openOffset = 0; + totalSize(fileSize); + position(0); + opened(); } void sftpProtocol::read(KIO::filesize_t bytes) { _DEBUG << "read, offset = " << openOffset << ", bytes = " << bytes << endl; QByteArray buffer; - int code; - - if ((code = sftpRead(openHandle, openOffset, bytes, buffer)) == SSH2_FX_OK) { + int code = sftpRead(openHandle, openOffset, bytes, buffer); + if ((code == SSH2_FX_OK) || (code == SSH2_FX_EOF)) { openOffset += buffer.size(); data(buffer); - buffer.clear(); } else { - // empty array designates eof - if (code == SSH2_FX_EOF) { - data(QByteArray()); - } processStatus(code, openUrl.prettyUrl()); close(); } @@ -927,10 +931,10 @@ void sftpProtocol::write(const QByteArray &data) { _DEBUG << "write" << endl; - int code; - if ((code = sftpWrite(openHandle, openOffset, data)) == SSH2_FX_OK) { + int code = sftpWrite(openHandle, openOffset, data); + if (code == SSH2_FX_OK) { + openOffset += data.size(); written(data.size()); - openOffset += data.size(); } else { processStatus(code, openUrl.prettyUrl()); close(); @@ -940,8 +944,8 @@ void sftpProtocol::seek(KIO::filesize_t offset) { _DEBUG << "seek, offset = " << offset << endl; + openOffset = offset; position(offset); - openOffset = offset; } void sftpProtocol::close() @@ -1710,11 +1714,14 @@ { case SSH2_FX_OK: case SSH2_FX_EOF: + res.text = i18n("End of file."); break; case SSH2_FX_NO_SUCH_FILE: + res.text = i18n("File does not exist."); res.code = ERR_DOES_NOT_EXIST; break; case SSH2_FX_PERMISSION_DENIED: + res.text = i18n("Access is denied."); res.code = ERR_ACCESS_DENIED; break; case SSH2_FX_FAILURE: @@ -1740,8 +1747,9 @@ /** Process SSH_FXP_STATUS packets. */ void sftpProtocol::processStatus(quint8 code, const QString& message){ Status st = doProcessStatus( code, message ); - if( st.code != 0 ) + if( st.code != 0 ){ error( st.code, st.text ); + } } /** Opens a directory handle for url.path. Returns true if succeeds. */ --0-1798721820-1210124127=:87480 Content-Type: text/x-patch; name="smb_fixes.diff" Content-Description: 2767726281-smb_fixes.diff Content-Disposition: inline; filename="smb_fixes.diff" Index: runtime/kioslave/smb/kio_smb_browse.cpp =================================================================== --- runtime/kioslave/smb/kio_smb_browse.cpp (revision 804348) +++ runtime/kioslave/smb/kio_smb_browse.cpp (working copy) @@ -44,19 +44,25 @@ int SMBSlave::cache_stat(const SMBUrl &url, struct stat* st ) { + int cacheStatErr; int result = smbc_stat( url.toSmbcUrl(), st); - kDebug(KIO_SMB) << "smbc_stat " << url << " " << errno << " " << result; + if (result == 0){ + cacheStatErr = 0; + } else { + cacheStatErr = errno; + } kDebug(KIO_SMB) << "size " << (KIO::filesize_t)st->st_size; - return result; + return cacheStatErr; } //--------------------------------------------------------------------------- bool SMBSlave::browse_stat_path(const SMBUrl& _url, UDSEntry& udsentry, bool ignore_errors) // Returns: true on success, false on failure { - SMBUrl url = _url; + SMBUrl url = _url; - if(cache_stat(url, &st) == 0) + int cacheStatErr = cache_stat(url, &st); + if(cacheStatErr == 0) { if(!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) { @@ -94,14 +100,14 @@ else { if (!ignore_errors) { - if (errno == EPERM || errno == EACCES) + if (cacheStatErr == EPERM || cacheStatErr == EACCES) if (checkPassword(url)) { redirection( url ); return false; } - reportError(url); - } else if (errno == ENOENT || errno == ENOTDIR) { + reportError(url, cacheStatErr); + } else if (cacheStatErr == ENOENT || cacheStatErr == ENOTDIR) { warning(i18n("File does not exist: %1", url.url())); } kDebug(KIO_SMB) << "SMBSlave::browse_stat_path ERROR!!"; @@ -206,10 +212,11 @@ return url; } -void SMBSlave::reportError(const SMBUrl &url) +void SMBSlave::reportError(const SMBUrl &url, const int &errNum) { - kDebug(KIO_SMB) << "reportError " << url << " " << perror; - switch(errno) + kDebug(KIO_SMB) << "errNum" << errNum; + + switch(errNum) { case ENOENT: if (url.getType() == SMBURLTYPE_ENTIRE_NETWORK) @@ -279,7 +286,7 @@ "if they ask for it)") ); break; default: - error( ERR_INTERNAL, i18n("Unknown error condition in stat: %1", QString::fromLocal8Bit( strerror(errno))) ); + error( ERR_INTERNAL, i18n("Unknown error condition in stat: %1", QString::fromLocal8Bit( strerror(errNum))) ); } } @@ -287,6 +294,7 @@ void SMBSlave::listDir( const KUrl& kurl ) { kDebug(KIO_SMB) << "SMBSlave::listDir on " << kurl; + int errNum = 0; // check (correct) URL KUrl url = checkURL(kurl); @@ -305,6 +313,12 @@ UDSEntry udsentry; dirfd = smbc_opendir( m_current_url.toSmbcUrl() ); + if (dirfd > 0){ + errNum = 0; + } else { + errNum = errno; + } + kDebug(KIO_SMB) << "SMBSlave::listDir open " << m_current_url.toSmbcUrl() << " " << m_current_url.getType() << " " << dirfd; if(dirfd >= 0) { @@ -416,14 +430,15 @@ } else { - if (errno == EPERM || errno == EACCES) + if (errNum == EPERM || errNum == EACCES) { if (checkPassword(m_current_url)) { redirection( m_current_url ); finished(); return; } + } - reportError(m_current_url); + reportError(m_current_url, errNum); finished(); return; } Index: runtime/kioslave/smb/kio_smb_auth.cpp =================================================================== --- runtime/kioslave/smb/kio_smb_auth.cpp (revision 804348) +++ runtime/kioslave/smb/kio_smb_auth.cpp (working copy) @@ -47,6 +47,7 @@ //========================================================================== { if (context != NULL) { + // FIXME deprecated use smbc_getOption*() functions instead SMBSlave *theSlave = (SMBSlave*)smbc_option_get(context, "user_data"); theSlave->auth_smbc_get_data(server, share, workgroup,wgmaxlen, @@ -188,11 +189,12 @@ smb_context->debug = debug_level; smb_context->callbacks.auth_fn = NULL; + // FIXME deprecated use smbc_setOption*() functions instead. smbc_option_set(smb_context, "auth_function", (void*)::auth_smbc_get_data); smbc_option_set(smb_context, "user_data", this); if (!smbc_init_context(smb_context)) { - smbc_free_context(smb_context, false); + smbc_free_context(smb_context, 0); smb_context = NULL; SlaveBase::error(ERR_INTERNAL, i18n("libsmbclient failed to initialize context")); return false; Index: runtime/kioslave/smb/kio_smb_dir.cpp =================================================================== --- runtime/kioslave/smb/kio_smb_dir.cpp (revision 804348) +++ runtime/kioslave/smb/kio_smb_dir.cpp (working copy) @@ -44,10 +44,11 @@ SMBUrl src; SMBUrl dst; mode_t initialmode; - int n; + ssize_t n; int dstflags; int srcfd = -1; int dstfd = -1; + int errNum = 0; KIO::filesize_t processed_size = 0; unsigned char buf[MAX_XFER_BUF_SIZE]; @@ -58,9 +59,10 @@ dst = kdst; // Obtain information about source - if(cache_stat(src, &st ) == -1) + errNum = cache_stat(src, &st ); + if( errNum != 0 ) { - if ( errno == EACCES ) + if ( errNum == EACCES ) { error( KIO::ERR_ACCESS_DENIED, src.prettyUrl()); } @@ -78,7 +80,8 @@ totalSize(st.st_size); // Check to se if the destination exists - if(cache_stat(dst, &st) != -1) + errNum = cache_stat(dst, &st); + if( errNum == 0 ) { if(S_ISDIR(st.st_mode)) { @@ -94,9 +97,15 @@ // Open the source file srcfd = smbc_open(src.toSmbcUrl(), O_RDONLY, 0); + if (srcfd < 0){ + errNum = errno; + } else { + errNum = 0; + } + if(srcfd < 0) { - if(errno == EACCES) + if(errNum == EACCES) { error( KIO::ERR_ACCESS_DENIED, src.prettyUrl() ); } @@ -125,9 +134,15 @@ dstflags |= O_EXCL; } dstfd = smbc_open(dst.toSmbcUrl(), dstflags, initialmode); + if (dstfd < 0){ + errNum = errno; + } else { + errNum = 0; + } + if(dstfd < 0) { - if(errno == EACCES) + if(errNum == EACCES) { error(KIO::ERR_WRITE_ACCESS_DENIED, dst.prettyUrl()); } @@ -135,10 +150,11 @@ { error(KIO::ERR_CANNOT_OPEN_FOR_READING, dst.prettyUrl()); } - if(srcfd >= 0 ) - { - smbc_close(srcfd); - } + + if(srcfd >= 0 ) + { + smbc_close(srcfd); + } return; } @@ -201,30 +217,39 @@ { kDebug(KIO_SMB) << "SMBSlave::del on " << kurl; m_current_url = kurl; + int errNum = 0; + int retVal = 0; if(isfile) { // Delete file kDebug(KIO_SMB) << "SMBSlave:: unlink " << kurl; - if(smbc_unlink(m_current_url.toSmbcUrl()) == -1) + retVal = smbc_unlink(m_current_url.toSmbcUrl()); + if ( retVal < 0 ){ + errNum = errno; + } else { + errNum = 0; + } + + if( retVal < 0 ) { - switch(errno) - { - case EISDIR: - error( KIO::ERR_IS_DIRECTORY, m_current_url.prettyUrl()); - break; - default: - reportError(kurl); - } + reportError(kurl, errNum); } } else { kDebug(KIO_SMB) << "SMBSlave:: rmdir " << kurl; // Delete directory - if(smbc_rmdir(m_current_url.toSmbcUrl()) == -1) + retVal = smbc_rmdir(m_current_url.toSmbcUrl()); + if( retVal < 0 ) { + errNum = errno; + } else { + errNum = 0; + } + + if( retVal < 0 ) { - reportError(kurl); + reportError(kurl, errNum); } } @@ -235,12 +260,22 @@ void SMBSlave::mkdir( const KUrl &kurl, int permissions ) { kDebug(KIO_SMB) << "SMBSlave::mkdir on " << kurl; + int errNum = 0; + int retVal = 0; m_current_url = kurl; - if(smbc_mkdir(m_current_url.toSmbcUrl(), 0777) != 0) + retVal = smbc_mkdir(m_current_url.toSmbcUrl(), 0777); + if( retVal < 0 ){ + errNum = errno; + } else { + errNum = 0; + } + + if( retVal < 0 ) { - if (errno == EEXIST) { - if(cache_stat(m_current_url, &st ) == 0) + if (errNum == EEXIST) { + errNum = cache_stat(m_current_url, &st ); + if( errNum == 0 ) { if(S_ISDIR(st.st_mode )) { @@ -252,7 +287,7 @@ error( KIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyUrl()); } } else - reportError(kurl); + reportError(kurl, errNum); kDebug(KIO_SMB) << "SMBSlave::mkdir exit with error " << kurl; } else @@ -274,6 +309,8 @@ SMBUrl src; SMBUrl dst; + int errNum = 0; + int retVal = 0; kDebug(KIO_SMB) << "SMBSlave::rename, old name = " << ksrc << ", new name = " << kdest; @@ -283,7 +320,8 @@ // Check to se if the destination exists kDebug(KIO_SMB) << "SMBSlave::rename stat dst"; - if(cache_stat(dst, &st) != -1) + errNum = cache_stat(dst, &st); + if( errNum == 0 ) { if(S_ISDIR(st.st_mode)) { @@ -301,15 +339,23 @@ } } kDebug(KIO_SMB ) << "smbc_rename " << src.toSmbcUrl() << " " << dst.toSmbcUrl(); - if(smbc_rename(src.toSmbcUrl(), dst.toSmbcUrl())!=0) + retVal = smbc_rename(src.toSmbcUrl(), dst.toSmbcUrl()); + if( retVal < 0 ){ + errNum = errno; + } else { + errNum = 0; + } + + if( retVal < 0 ) { - kDebug(KIO_SMB ) << "failed " << perror; - switch(errno) + kDebug(KIO_SMB ) << "failed "; + switch(errNum) { case ENOENT: - if(cache_stat(src, &st) == -1) + errNum = cache_stat(src, &st); + if( errNum != 0 ) { - if(errno == EACCES) + if(errNum == EACCES) { kDebug(KIO_SMB) << "SMBSlave::rename KIO::ERR_ACCESS_DENIED"; error(KIO::ERR_ACCESS_DENIED, src.prettyUrl()); Index: runtime/kioslave/smb/kio_smb_file.cpp =================================================================== --- runtime/kioslave/smb/kio_smb_file.cpp (revision 804348) +++ runtime/kioslave/smb/kio_smb_file.cpp (working copy) @@ -42,6 +42,7 @@ { char buf[MAX_XFER_BUF_SIZE]; int filefd = 0; + int errNum = 0; ssize_t bytesread = 0; // time_t curtime = 0; time_t lasttime = 0; @@ -66,9 +67,10 @@ // Stat url = kurl; - if(cache_stat(url,&st) == -1 ) + errNum = cache_stat(url,&st); + if( errNum != 0 ) { - if ( errno == EACCES ) + if ( errNum == EACCES ) error( KIO::ERR_ACCESS_DENIED, url.prettyUrl()); else error( KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); @@ -134,14 +136,14 @@ //=========================================================================== -void SMBSlave::open( const KUrl& kurl, QIODevice::OpenMode /*mode*/) +void SMBSlave::open( const KUrl& kurl, QIODevice::OpenMode mode) { - SMBUrl url; - + int errNum = 0; kDebug(KIO_SMB) << "SMBSlave::open on " << kurl; // check (correct) URL KUrl kvurl = checkURL(kurl); + // if URL is not valid we have to redirect to correct URL if (kvurl != kurl) { redirection(kvurl); @@ -149,102 +151,152 @@ return; } - if(!auth_initialize_smbc()) + if(!auth_initialize_smbc()) { + error( KIO::ERR_ACCESS_DENIED, kurl.prettyUrl()); return; + } + // Save the URL as a private member + // FIXME For some reason m_openUrl has be be declared in bottom private + // section of the class SMBSlave declaratiom instead of the top section + // or else this assignment fails + m_openUrl = kurl; + // Stat - url = kurl; - if(cache_stat(url,&st) == -1 ) + errNum = cache_stat(m_openUrl,&st); + if( errNum != 0 ) { - if ( errno == EACCES ) - error( KIO::ERR_ACCESS_DENIED, url.prettyUrl()); + if ( errNum == EACCES ) + error( KIO::ERR_ACCESS_DENIED, m_openUrl.prettyUrl()); else - error( KIO::ERR_DOES_NOT_EXIST, url.prettyUrl()); + error( KIO::ERR_DOES_NOT_EXIST, m_openUrl.prettyUrl()); return; } if ( S_ISDIR( st.st_mode ) ) { - error( KIO::ERR_IS_DIRECTORY, url.prettyUrl()); + error( KIO::ERR_IS_DIRECTORY, m_openUrl.prettyUrl()); return; } // Set the total size totalSize( st.st_size ); - // Open and read the file - openFd = smbc_open(url.toSmbcUrl(),O_RDONLY,0); - if(openFd < 0) + // Convert permissions + int flags = 0; + if (mode & QIODevice::ReadOnly) { + if (mode & QIODevice::WriteOnly) { + flags = O_RDWR | O_CREAT; + } else { + flags = O_RDONLY; + } + } else if (mode & QIODevice::WriteOnly) { + flags = O_WRONLY | O_CREAT; + } + + if (mode & QIODevice::Append) { + flags |= O_APPEND; + } else if (mode & QIODevice::Truncate) { + flags |= O_TRUNC; + } + + // Open the file + m_openFd = smbc_open(m_openUrl.toSmbcUrl(), flags, 0); + if(m_openFd < 0) { - error( KIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyUrl()); + error( KIO::ERR_CANNOT_OPEN_FOR_READING, m_openUrl.prettyUrl()); return; } + // Determine the mimetype of the file to be retrieved, and emit it. + // This is mandatory in all slaves (for KRun/BrowserRun to work). + // If we're not opening the file ReadOnly or ReadWrite, don't attempt to + // read the file and send the mimetype. + if (mode & QIODevice::ReadOnly){ + ssize_t bytesRequested = 1024; + ssize_t bytesRead = 0; + QVarLengthArray buffer(bytesRequested); + bytesRead = smbc_read(m_openFd, buffer.data(), bytesRequested); + if(bytesRead < 0) + { + error( KIO::ERR_COULD_NOT_READ, m_openUrl.prettyUrl()); + close(); + return; + } + else + { + QByteArray fileData = QByteArray::fromRawData(buffer.data(),bytesRead); + KMimeType::Ptr p_mimeType = KMimeType::findByNameAndContent(m_openUrl.fileName(), fileData); + mimeType(p_mimeType->name()); + + off_t res = smbc_lseek(m_openFd, 0, SEEK_SET); + if (res == (off_t)-1) { + error(KIO::ERR_COULD_NOT_SEEK, m_openUrl.path()); + close(); + return; + } + } + } + position( 0 ); emit opened(); - openUrl = url; - justOpened = true; } -void SMBSlave::read(KIO::filesize_t bytes) + +void SMBSlave::read( KIO::filesize_t bytesRequested ) { - kDebug( KIO_SMB ) << "open -- read"; - Q_ASSERT(openFd != -1); + Q_ASSERT(m_openFd != -1); - QVarLengthArray buffer(bytes); - ssize_t bytesread = 0; - // time_t curtime = 0; - time_t lasttime = 0; - time_t starttime = 0; + QVarLengthArray buffer(bytesRequested); + ssize_t bytesRead = 0; - lasttime = starttime = time(NULL); - bytesread = smbc_read(openFd, buffer.data(), bytes); - if(bytesread == 0) + bytesRead = smbc_read(m_openFd, buffer.data(), bytesRequested); + Q_ASSERT(bytesRead <= static_cast(bytesRequested)); + + if(bytesRead < 0) { - // All done reading - data(QByteArray()); - } - else if(bytesread < 0) - { - error( KIO::ERR_COULD_NOT_READ, openUrl.prettyUrl()); + kDebug(KIO_SMB) << "Could not read " << m_openUrl; + error( KIO::ERR_COULD_NOT_READ, m_openUrl.prettyUrl()); close(); return; } - else - { - QByteArray filedata = QByteArray::fromRawData(buffer.data(),bytesread); - if (justOpened) - { - KMimeType::Ptr p_mimeType = KMimeType::findByNameAndContent(openUrl.fileName(), filedata); - mimeType(p_mimeType->name()); - justOpened = false; - } - data( filedata ); - filedata.clear(); - } + + QByteArray fileData = QByteArray::fromRawData(buffer.data(), bytesRead); + data( fileData ); } -void SMBSlave::write(const QByteArray &data) + +void SMBSlave::write(const QByteArray &fileData) { - kDebug( KIO_SMB ) << "open -- write"; + Q_ASSERT(m_openFd != -1); - // not implemented - KIO::SlaveBase::write(data); + QByteArray buf(fileData); + + ssize_t size = smbc_write(m_openFd, buf.data(), buf.size()); + if (size < 0) + { + kDebug(KIO_SMB) << "Could not write to " << m_openUrl; + error( KIO::ERR_COULD_NOT_WRITE, m_openUrl.prettyUrl()); + close(); + return; + } + + written(size); } void SMBSlave::seek(KIO::filesize_t offset) { - kDebug( KIO_SMB ) << "open -- seek"; - int res = smbc_lseek(openFd, offset, SEEK_SET); - if (res != -1) { - position( offset ); + off_t res = smbc_lseek(m_openFd, static_cast(offset), SEEK_SET); + if (res == (off_t)-1) { + error(KIO::ERR_COULD_NOT_SEEK, m_openUrl.path()); + close(); } else { - error(KIO::ERR_COULD_NOT_SEEK, openUrl.path()); - close(); + kDebug( KIO_SMB ) << "res" << res; + position( res ); } } void SMBSlave::close() { - smbc_close(openFd); + smbc_close(m_openFd); finished(); } @@ -261,13 +313,15 @@ int filefd; bool exists; + int errNum = 0; + off_t retValLSeek = 0; mode_t mode; QByteArray filedata; kDebug(KIO_SMB) << "SMBSlave::put on " << kurl; - - exists = (cache_stat(m_current_url, &st) != -1 ); + errNum = cache_stat(m_current_url, &st); + exists = (errNum == 0); if ( exists && !(flags & KIO::Overwrite) && !(flags & KIO::Resume)) { if (S_ISDIR(st.st_mode)) @@ -295,7 +349,18 @@ // append if resuming kDebug(KIO_SMB) << "SMBSlave::put resume " << m_current_url.toSmbcUrl(); filefd = smbc_open(m_current_url.toSmbcUrl(), O_RDWR, 0 ); - smbc_lseek(filefd, 0, SEEK_END); + if (filefd < 0) { + errNum = errno; + } else { + errNum = 0; + } + + retValLSeek = smbc_lseek(filefd, 0, SEEK_END); + if (retValLSeek == (off_t)-1) { + errNum = errno; + } else { + errNum = 0; + } } else { @@ -310,11 +375,16 @@ kDebug(KIO_SMB) << "SMBSlave::put NO resume " << m_current_url.toSmbcUrl(); filefd = smbc_open(m_current_url.toSmbcUrl(), O_CREAT | O_TRUNC | O_WRONLY, mode); + if (filefd < 0) { + errNum = errno; + } else { + errNum = 0; + } } if ( filefd < 0 ) { - if ( errno == EACCES ) + if ( errNum == EACCES ) { kDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" access denied !!"; error( KIO::ERR_WRITE_ACCESS_DENIED, m_current_url.prettyUrl()); @@ -343,7 +413,7 @@ kDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl(); buf = filedata.data(); bufsize = filedata.size(); - int size = smbc_write(filefd, buf, bufsize); + ssize_t size = smbc_write(filefd, buf, bufsize); if ( size < 0) { kDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" could not write !!"; @@ -355,7 +425,7 @@ } kDebug(KIO_SMB) << "SMBSlave::put close " << m_current_url.toSmbcUrl(); - if(smbc_close(filefd)) + if(smbc_close(filefd) < 0) { kDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" could not write !!"; error( KIO::ERR_COULD_NOT_WRITE, m_current_url.prettyUrl()); Index: runtime/kioslave/smb/kio_smb.cpp =================================================================== --- runtime/kioslave/smb/kio_smb.cpp (revision 804348) +++ runtime/kioslave/smb/kio_smb.cpp (working copy) @@ -34,7 +34,7 @@ //=========================================================================== SMBSlave::SMBSlave(const QByteArray& pool, const QByteArray& app) - : SlaveBase( "smb", pool, app ), openFd(-1) + : SlaveBase( "smb", pool, app ), m_openFd(-1) { m_initialized_smbc = false; Index: runtime/kioslave/smb/kio_smb.h =================================================================== --- runtime/kioslave/smb/kio_smb.h (revision 804348) +++ runtime/kioslave/smb/kio_smb.h (working copy) @@ -127,6 +127,7 @@ * looks like gcc (C/C++) failure */ struct stat st; + protected: //--------------------------------------------- // Authentication functions (kio_smb_auth.cpp) @@ -214,7 +215,7 @@ */ KUrl checkURL(const KUrl& kurl) const; - void reportError(const SMBUrl &kurl); + void reportError(const SMBUrl &kurl, const int &errNum); public: @@ -254,8 +255,8 @@ virtual void get( const KUrl& kurl ); virtual void put( const KUrl& kurl, int permissions, KIO::JobFlags flags ); virtual void open( const KUrl& kurl, QIODevice::OpenMode mode ); - virtual void read( KIO::filesize_t size ); - virtual void write( const QByteArray &data ); + virtual void read( KIO::filesize_t bytesRequested ); + virtual void write( const QByteArray &fileData ); virtual void seek( KIO::filesize_t offset ); virtual void close(); @@ -272,10 +273,13 @@ private: QString mybuf, mystderr; - - int openFd; - bool justOpened; - SMBUrl openUrl; + /** + * Used in open(), read(), write(), and close() + * FIXME Placing these in the private section above causes m_openUrl = kurl + * to fail in SMBSlave::open. Need to find out why this is. + */ + int m_openFd; + SMBUrl m_openUrl; }; //========================================================================== --0-1798721820-1210124127=:87480--