📄 main.cc
字号:
assert( 0 ); } // No need to ask the user, so raise an error else { ftp.ftpDisconnect(); error( job.errorId(), job.errorText() ); m_cmd = CMD_NONE; return; } } } while( job.hasError() ); processedDirs( ++processed_dirs ); } debug( "kio_ftp : Created directories %s", dest.c_str() ); /***** * Server check - supports resuming ? *****/ if ( !ftp.ftpResume( 0 ) ) m_bCanResume = false; /***** * Copy files *****/ time_t t_start = time( 0L ); time_t t_last = t_start; fit = files.begin(); for( ; fit != files.end(); fit++ ) { bool overwrite = false; bool skip_copying = false; bool resume = false; unsigned long offset = 0; // Repeat until we got no error do { job.clearError(); list<K2URL> l( lst ); l.back().setPath( fit->m_strRelDest.c_str() ); // debug( "kio_ftp : ########### SET Path to '%s'", fit->m_strRelDest.c_str() ); string d; list<K2URL>::iterator it = l.begin(); for( ; it != l.end(); it++ ) d += it->url(); // Is this URL on the skip list ? bool skip = false; list<string>::iterator sit = skip_list.begin(); for( ; sit != skip_list.end() && !skip; sit++ ) // Is 'd' a file in directory '*sit' or one of its subdirectories ? if ( strncmp( sit->c_str(), d.c_str(), sit->size() ) == 0 ) skip = true; if ( skip ) continue; // emit sigCanResume( m_bCanResume ) canResume( m_bCanResume ); string realpath = "ftp:"; realpath += fit->m_strAbsSource; copyingFile( realpath.c_str(), d.c_str() ); // debug( "kio_ftp : Writing to %s", d ); // Is this URL on the overwrite list ? list<string>::iterator oit = overwrite_list.begin(); for( ; oit != overwrite_list.end() && !overwrite; oit++ ) if ( strncmp( oit->c_str(), d.c_str(), oit->size() ) == 0 ) overwrite = true; // implicitly set permissions rw-r--r-- for anonymous ftp int md = -1; // but when it's not anonymous ftp, set permissions as in original source if ( b_user ) md = fit->m_access; job.put( d.c_str(), md, overwrite_all || overwrite, resume_all || resume, fit->m_size ); while( !job.isReady() && !job.hasFinished() ) job.dispatch(); // Did we have an error ? if ( job.hasError() ) { int currentError = job.errorId(); debug("################# COULD NOT PUT %d",currentError); // if ( /* m_bGUI && */ job.errorId() == ERR_WRITE_ACCESS_DENIED ) if ( /* m_bGUI && */ currentError != ERR_DOES_ALREADY_EXIST && currentError != ERR_DOES_ALREADY_EXIST_FULL ) { // Should we skip automatically ? if ( auto_skip ) { job.clearError(); skip_copying = true; continue; } string tmp2 = l.back().url(); SkipDlg_Result r; r = open_SkipDlg( tmp2.c_str(), ( files.size() > 1 ) ); if ( r == S_CANCEL ) { ftp.ftpDisconnect(); error( ERR_USER_CANCELED, "" ); m_cmd = CMD_NONE; return; } else if ( r == S_SKIP ) { // Clear the error => The current command is not repeated => skipped job.clearError(); skip_copying = true; continue; } else if ( r == S_AUTO_SKIP ) { // Clear the error => The current command is not repeated => skipped job.clearError(); skip_copying = true; continue; } else assert( 0 ); } // Can we prompt the user and ask for a solution ? else if ( /* m_bGUI && */ currentError == ERR_DOES_ALREADY_EXIST || currentError == ERR_DOES_ALREADY_EXIST_FULL ) { // Should we skip automatically ? if ( auto_skip ) { job.clearError(); continue; } RenameDlg_Result r; string n; if ( ProtocolManager::self()->getAutoResume() && m_bCanResume && currentError != ERR_DOES_ALREADY_EXIST_FULL ) { r = R_RESUME_ALL; } else { RenameDlg_Mode m; // ask for resume only if transfer can be resumed and if it is not // already fully downloaded if ( files.size() > 1 ){ if ( m_bCanResume && currentError != ERR_DOES_ALREADY_EXIST_FULL ) m = (RenameDlg_Mode)(M_MULTI | M_SKIP | M_OVERWRITE | M_RESUME); else m = (RenameDlg_Mode)(M_MULTI | M_SKIP | M_OVERWRITE); } else { if ( m_bCanResume && currentError != ERR_DOES_ALREADY_EXIST_FULL ) m = (RenameDlg_Mode)( M_SINGLE | M_OVERWRITE | M_RESUME); else m = (RenameDlg_Mode)( M_SINGLE | M_OVERWRITE); } string tmp2 = l.back().url(); r = open_RenameDlg( fit->m_strAbsSource.c_str(), tmp2.c_str(), m, n ); } if ( r == R_CANCEL ) { ftp.ftpDisconnect(); error( ERR_USER_CANCELED, "" ); m_cmd = CMD_NONE; return; } else if ( r == R_RENAME ) { K2URL u( n.c_str() ); // The Dialog should have checked this. if ( u.isMalformed() ) assert( 0 ); // Change the destination name of the current file fit->m_strRelDest = u.path( -1 ); // Dont clear error => we will repeat the current command } else if ( r == R_SKIP ) { // Clear the error => The current command is not repeated => skipped job.clearError(); } else if ( r == R_AUTO_SKIP ) { // Clear the error => The current command is not repeated => skipped job.clearError(); auto_skip = true; } else if ( r == R_OVERWRITE ) { overwrite = true; // Dont clear error => we will repeat the current command } else if ( r == R_OVERWRITE_ALL ) { overwrite_all = true; // Dont clear error => we will repeat the current command } else if ( r == R_RESUME ) { resume = true; offset = getOffset( l.back().url() ); // Dont clear error => we will repeat the current command } else if ( r == R_RESUME_ALL ) { resume_all = true; offset = getOffset( l.back().url() ); // Dont clear error => we will repeat the current command } else assert( 0 ); } // No need to ask the user, so raise an error else { ftp.ftpDisconnect(); error( currentError, job.errorText() ); m_cmd = CMD_NONE; return; } } } while( job.hasError() ); if ( skip_copying ) continue; // add the offset to processed size if ( offset > 0 ) { processed_size += offset; debug( "kio_ftp : Offset = %ld", offset ); } K2URL tmpurl( "ftp:/" ); tmpurl.setPath( fit->m_strAbsSource.c_str() ); debug( "kio_ftp : Opening %s", fit->m_strAbsSource.c_str() ); if ( !ftp.ftpOpen( tmpurl, Ftp::READ, offset ) ) { ftp.ftpDisconnect(); error( ftp.error(), ftp.errorText() ); m_cmd = CMD_NONE; return; } // we want to know the processed size even before we read something // especially in case we overwrite file => this cleans size to zero processedSize( processed_size ); char buffer[ 4096 ]; int n; do { setup_alarm( ProtocolManager::self()->getReadTimeout() ); // start timeout n = ftp.read( buffer, 2048 ); // !!! slow down loop for local testing// for ( int tmpi = 0; tmpi < 800000; tmpi++ ) ; job.data( buffer, n ); processed_size += n; time_t t = time( 0L ); if ( t - t_last >= 1 ) { processedSize( processed_size ); speed( processed_size / ( t - t_start ) ); t_last = t; } // Check parent while ( check( connection() ) ) dispatch(); // Check for error messages from slave while ( check( &slave ) ) job.dispatch(); // An error ? if ( job.hasFinished() ) { ftp.ftpClose(); ftp.ftpDisconnect(); finished(); m_cmd = CMD_NONE; return; } } while ( n > 0 ); job.dataEnd(); ftp.ftpClose(); while( !job.hasFinished() ) job.dispatch(); time_t t = time( 0L ); processedSize( processed_size ); if ( t - t_start >= 1 ) { speed( processed_size / ( t - t_start ) ); t_last = t; } processedFiles( ++processed_files ); } debug( "kio_ftp : Copied files %s", dest.c_str() ); // slotDel() handles disconnecting by itself if ( _move ) { slotDel( _source ); } else ftp.ftpDisconnect(); finished(); m_cmd = CMD_NONE;}void FtpProtocol::slotGetSize( const char* _url ) { m_cmd = CMD_GET_SIZE; // Check wether URL is wellformed K2URL usrc( _url ); if ( usrc.isMalformed() ) { error( ERR_MALFORMED_URL, _url ); m_cmd = CMD_NONE; return; } if ( strcmp( usrc.protocol(), "ftp" ) != 0L ) { error( ERR_INTERNAL, "kio_ftp got non ftp file as source in copy command" ); m_cmd = CMD_NONE; return; } debug( "kio_ftp : URL is ok " ); if ( !ftp.ftpConnect( usrc ) ) { error( ftp.error(), ftp.errorText() ); m_cmd = CMD_NONE; return; } // Get a list of all source files and directories list<Copy> files; list<CopyDir> dirs; debug( "kio_ftp : Executing %s", _url ); // Did an error occur ? int s; if ( ( s = listRecursive( usrc.path(), files, dirs, false ) ) == -1 ) { ftp.ftpDisconnect(); // Error message is already sent m_cmd = CMD_NONE; return; } // Tell our client what we 'r' gonna do totalSize( s ); ftp.ftpDisconnect(); finished(); m_cmd = CMD_NONE;}void FtpProtocol::slotPut( const char *_url, int _mode, bool _overwrite, bool _resume, int _size ){ string url_orig = _url; string url_part = url_orig + ".part"; K2URL udest_orig( url_orig ); K2URL udest_part( url_part ); bool m_bMarkPartial = ProtocolManager::self()->getMarkPartial(); if ( udest_orig.isMalformed() ) { error( ERR_MALFORMED_URL, url_orig.c_str() ); m_cmd = CMD_NONE; finished(); return; } if ( strcmp( udest_orig.protocol(), "ftp" ) != 0L ) { error(ERR_INTERNAL,"kio_ftp got non ftp file as as destination in put command" ); m_cmd = CMD_NONE; finished(); return; } // Connect to the ftp server, only if we are not connected // this prevents connecting twice in recursive copying ( mkdir connects first time ) if ( !ftp.isConnected() ) if ( !ftp.ftpConnect( udest_orig ) ) { error( ftp.error(), ftp.errorText() ); m_cmd = CMD_NONE; finished(); return; } m_cmd = CMD_PUT; // Find out, whether we are logged anonymously or not // Authorization has been already checked with ftp.ftpConnect( usrc ) bool b_user = false; if ( udest_orig.hasUser() ) b_user = true; FtpEntry* e; if ( ( e = ftp.ftpStat( udest_orig ) ) ) { // if original file exists, but we are using mark partial -> rename it to XXX.part if ( m_bMarkPartial ) ftp.ftpRename( udest_orig.path(), udest_part.path() ); if ( !_overwrite && !_resume ) { if ( e->size == _size ) error( ERR_DOES_ALREADY_EXIST_FULL, udest_orig.path() ); else error( ERR_DOES_ALREADY_EXIST, udest_orig.path() ); ftp.ftpDisconnect(); m_cmd = CMD_NONE; finished(); return; } } else if ( ( e = ftp.ftpStat( udest_part ) ) ) { // if file with extension .part exists but we are not using mark partial // -> rename XXX.part to original name if ( ! m_bMarkPartial ) ftp.ftpRename( udest_part.path(), udest_orig.path() ); if ( !_overwrite && !_resume ) { if ( e->size == _size ) error( ERR_DOES_ALREADY_EXIST_FULL, udest_orig.path() ); else error( ERR_DOES_ALREADY_EXIST, udest_orig.path() ); ftp.ftpDisconnect(); m_cmd = CMD_NONE; finished(); return; } } K2URL udest; // if we are using marking of partial downloads -> add .part extension if ( m_bMarkPartial ) { debug( "kio_ftp : Adding .part extension to %s", udest_orig.path() ); udest = udest_part; } else udest = udest_orig; /* if ( access( udest.path(), W_OK ) == -1 ) { debug("Write Access denied for '%s' %d",udest.path(), errno ); error( ERR_WRITE_ACCESS_DENIED, url.c_str() ); m_cmd = CMD_NONE; finished(); return; } */ unsigned long offset = 0; // set the mode according to offset if ( _resume ) { offset = e->size; debug( "kio_ftp : Offset = %ld", offset ); } if ( !ftp.ftpOpen( udest, Ftp::WRITE, offset ) ) { debug( "kio_ftp : ####################### COULD NOT WRITE %s", udest.path() ); ftp.ftpDisconnect(); error( ftp.error(), ftp.errorText() ); m_cmd = CMD_NONE; finished(); return; } // We are ready for receiving data ready(); // Loop until we got 'dataEnd' while ( m_cmd == CMD_PUT && dispatch() ); ftp.ftpClose(); if ( (e = ftp.ftpStat( udest )) ) { if ( e->size == _size ) { // after full download rename the file back to original name if ( m_bMarkPartial ) { cerr << "kio_ftp renaming\n"; if ( !ftp.ftpRename( udest.path(), udest_orig.path() ) ) { error( ERR_CANNOT_RENAME, udest_orig.path() ); ftp.ftpDisconnect(); m_cmd = CMD_NONE; finished(); return; } } // do chmod only after full download if ( _mode != -1 ) { cerr << "kio_ftp chmoding\n"; // set the desired attributes for dir !!! how ? if ( !ftp.ftpChmod( udest_orig.path(), _mode ) ) { error( ERR_CANNOT_CHMOD, udest_orig.path() ); ftp.ftpDisconnect(); m_cmd = CMD_NONE; finished(); return; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -