⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cc

📁 类似GetRight的下载工具
💻 CC
📖 第 1 页 / 共 3 页
字号:
#include "file.h"#include <config.h>#include <kio_manager.h>#include <kio_rename_dlg.h>#include <kio_skip_dlg.h>#include <stdio.h>#include <signal.h>#include <errno.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#ifdef HAVE_SYS_TIME_H#include <sys/time.h>#endif#include <dirent.h>#include <time.h>#include <unistd.h>#include <string.h>#include <pwd.h>#include <grp.h>#include <assert.h>#include <iostream>#include <k2url.h>string testLogFile( const char *_filename );int check( Connection *_con );void sig_handler( int );void sig_handler2( int );int main( int argc, char **argv ){  signal(SIGCHLD,sig_handler);  signal(SIGSEGV,sig_handler2);  ProtocolManager manager;    debug( "kio_file : Starting");  Connection parent( 0, 1 );    FileProtocol file( &parent );  file.dispatchLoop();  debug( "kio_file : Done" );}void sig_handler2( int ){  debug( "kio_file : ###############SEG FILE#############" );  exit(1);}void sig_handler( int ){  int pid;  int status;      while( 1 )  {    pid = waitpid( -1, &status, WNOHANG );    if ( pid <= 0 )    {      // Reinstall signal handler, since Linux resets to default after      // the signal occured ( BSD handles it different, but it should do      // no harm ).      signal( SIGCHLD, sig_handler );      return;    }  }}FileProtocol::FileProtocol( Connection *_conn ) : IOProtocol( _conn ){  m_cmd = CMD_NONE;  m_bIgnoreJobErrors = false;}void FileProtocol::slotMkdir( const char *_url, int _mode ){  string url = _url;    K2URL usrc( _url );  if ( usrc.isMalformed() )  {    error( ERR_MALFORMED_URL, url.c_str() );    m_cmd = CMD_NONE;    return;  }  if ( !usrc.isLocalFile() )  {    error( ERR_INTERNAL, "kio_file got non local name in mkdir command" );    m_cmd = CMD_NONE;    return;  }  struct stat buff;  if ( stat( usrc.path(), &buff ) == -1 )  {    if ( ::mkdir( usrc.path(), S_IRWXU ) != 0 )    {      if ( errno == EACCES )      {  	error( ERR_ACCESS_DENIED, url.c_str() );	m_cmd = CMD_NONE;	return;      }      else      {  	error( ERR_COULD_NOT_MKDIR, url.c_str() );	m_cmd = CMD_NONE;	return;      }    }    else    {      if ( _mode != -1 )	if ( chmod( usrc.path(), _mode ) == -1 )	{	  error( ERR_CANNOT_CHMOD, url.c_str() );	  m_cmd = CMD_NONE;	  return;	}      finished();      return;    }  }  if ( S_ISDIR( buff.st_mode ) )  {    error( ERR_DOES_ALREADY_EXIST, url.c_str() );    m_cmd = CMD_NONE;    return;  }      error( ERR_COULD_NOT_MKDIR, url.c_str() );  m_cmd = CMD_NONE;  return;}void FileProtocol::slotCopy( list<string>& _source, const char *_dest ){  doCopy( _source, _dest, false );}void FileProtocol::slotCopy( const char* _source, const char *_dest ){  list<string> lst;  lst.push_back( _source );    doCopy( lst, _dest, true );}void FileProtocol::slotMove( list<string>& _source, const char *_dest ){  doCopy( _source, _dest, false, true );}void FileProtocol::slotMove( const char* _source, const char *_dest ){  list<string> lst;  lst.push_back( _source );    doCopy( lst, _dest, true, true );}void FileProtocol::doCopy( list<string>& _source, const char *_dest, bool _rename, bool _move ) {  if ( _rename )    assert( _source.size() == 1 );    debug( "kio_file : Making copy to %s", _dest );    // Check wether the URLs are wellformed  list<string>::iterator soit = _source.begin();  for( ; soit != _source.end(); ++soit )  {        debug( "kio_file : Checking %s", soit->c_str() );    K2URL usrc( *soit );    if ( usrc.isMalformed() )    {      error( ERR_MALFORMED_URL, soit->c_str() );      m_cmd = CMD_NONE;      return;    }    if ( !usrc.isLocalFile() )    {      error( ERR_INTERNAL, "kio_file got non local file as source in copy command" );      m_cmd = CMD_NONE;      return;    }  }  debug( "kio_file : All URLs ok %s", _dest );  // Make a copy of the parameter. if we do IPC calls from here, then we overwrite  // our argument. This is tricky! ( but saves memory and speeds things up )  string dest = _dest;    // Check wellformedness of the destination  K2URL udest( dest );  if ( udest.isMalformed() )  {    error( ERR_MALFORMED_URL, dest.c_str() );    m_cmd = CMD_NONE;    return;  }  debug( "kio_file : Dest ok %s", dest.c_str() );  // Extract destinations right most protocol  list<K2URL> lst;  if ( !K2URL::split( dest.c_str(), lst )  )  {    error( ERR_MALFORMED_URL, dest.c_str() );    m_cmd = CMD_NONE;    return;  }  // Find IO server for destination  string exec = ProtocolManager::self()->find( lst.back().protocol() );  if ( exec.empty() )  {    error( ERR_UNSUPPORTED_PROTOCOL, lst.back().protocol() );    m_cmd = CMD_NONE;    return;  }  // Is the right most protocol a filesystem protocol ?  if ( ProtocolManager::self()->outputType( lst.back().protocol() ) != ProtocolManager::T_FILESYSTEM )  {    error( ERR_PROTOCOL_IS_NOT_A_FILESYSTEM, lst.back().protocol() );    m_cmd = CMD_NONE;    return;  }        debug( "kio_file : IO server ok %s", dest.c_str() );  // Get a list of all source files and directories  list<Copy> files;  list<CopyDir> dirs;  int size = 0;  debug( "kio_file : Iterating" );  soit = _source.begin();  debug( "kio_file : Looping" );  for( ; soit != _source.end(); ++soit )  {        debug( "kio_file : Executing %s", soit->c_str() );    K2URL usrc( *soit );    debug( "kio_file : Parsed URL" );    // Did an error occur ?    int s;    if ( ( s = listRecursive( usrc.path(), files, dirs, _rename ) ) == -1 )    {      // Error message is already sent      m_cmd = CMD_NONE;      return;    }    // Sum up the total amount of bytes we have to copy    size += s;  }  debug( "kio_file : Recursive 1 %s", dest.c_str() );  // Check wether we do not copy a directory in itself or one of its subdirectories  struct stat buff2;  if ( udest.isLocalFile() && stat( udest.path(), &buff2 ) == 0 )  {    bool b_error = false;    for( soit = _source.begin(); soit != _source.end(); ++soit )    {          K2URL usrc( *soit );        struct stat buff1;      // Can we stat both the source, too ? ( Should always be the case )      if ( stat( usrc.path(), &buff1 ) == 0 )      {	bool b_error = false;	// Are source and dest equal ? => error	if ( buff1.st_ino == buff2.st_ino )	  b_error = true;      }    }      if ( !b_error )    {      // Iterate over all subdirectories      list<CopyDir>::iterator it = dirs.begin();      for( ; it != dirs.end() && !b_error; it++ )	if ( buff2.st_ino == it->m_ino )	  b_error = true;    }    // Do we have a cyclic copy now ? => error    if ( b_error )    {      error( ERR_CYCLIC_COPY, soit->c_str() );      m_cmd = CMD_NONE;      return;    }  }  debug( "kio_file : Recursive ok %s", dest.c_str() );  m_cmd = CMD_GET;    // Start a server for the destination protocol  Slave slave( exec.c_str() );  if ( slave.pid() == -1 )  {    error( ERR_CANNOT_LAUNCH_PROCESS, exec.c_str() );    m_cmd = CMD_NONE;    return;  }    // Put a protocol on top of the job  FileIOJob job( &slave, this );  debug( "kio_file : Job started ok %s", dest.c_str() );  // Tell our client what we 'r' gonna do  totalSize( size );  totalFiles( files.size() );  totalDirs( dirs.size() );    int processed_files = 0;  int processed_dirs = 0;  int processed_size = 0;    // Replace the relative destinations with absolut destinations  // by prepending the destinations path  string tmp1 = lst.back().path( 1 );  // Strip '/'  string tmp1_stripped = lst.back().path( -1 );  list<CopyDir>::iterator dit = dirs.begin();  for( ; dit != dirs.end(); dit++ )  {    string tmp2 = dit->m_strRelDest;    if ( _rename )      dit->m_strRelDest = tmp1_stripped;    else      dit->m_strRelDest = tmp1;    dit->m_strRelDest += tmp2;  }  list<Copy>::iterator fit = files.begin();  for( ; fit != files.end(); fit++ )  {    string tmp2 = fit->m_strRelDest;    if ( _rename ) // !!! && fit->m_strRelDest == "" )      fit->m_strRelDest = tmp1_stripped;    else      fit->m_strRelDest = tmp1;    fit->m_strRelDest += tmp2;  }    debug( "kio_file : Destinations ok %s", dest.c_str() );  /*****   * Make directories   *****/    m_bIgnoreJobErrors = true;  bool overwrite_all = false;  bool auto_skip = false;  list<string> skip_list;  list<string> overwrite_list;  // Create all directories  dit = dirs.begin();  for( ; dit != dirs.end(); dit++ )  {     // Repeat until we got no error    do    {      job.clearError();      list<K2URL> l( lst );      l.back().setPath( dit->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 subdirectory of *sit ?	if ( strncmp( sit->c_str(), d.c_str(), sit->size() ) == 0 )	  skip = true;            if ( skip )	continue;      // Is this URL on the overwrite list ?      bool overwrite = false;      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;            if ( overwrite )	continue;            // Tell what we are doing      makingDir( d.c_str() );            // debug( "kio_file : Making remote dir %s", d );      // Create the directory      job.mkdir( d.c_str(), dit->m_mode );      while( !job.hasFinished() )	job.dispatch();      // Did we have an error ?      if ( job.hasError() )      {	// Can we prompt the user and ask for a solution ?	if ( /* m_bGUI && */ job.errorId() == ERR_DOES_ALREADY_EXIST )	{    	  string old_path = l.back().path( 1 );	  string old_url = l.back().url( 1 );	  // Should we skip automatically ?	  if ( auto_skip )	  {	    job.clearError();	    // We dont want to copy files in this directory, so we put it on the skip list.	    skip_list.push_back( old_url );	    continue;	  }	  else if ( overwrite_all )	  {    	    job.clearError();	    continue;	  }	  string n;	  /* RenameDlg_Mode m = (RenameDlg_Mode)( M_SINGLE | M_OVERWRITE );	  if ( dirs.size() > 1 )	    m = (RenameDlg_Mode)(M_MULTI | M_SKIP | M_OVERWRITE ); */	  RenameDlg_Mode m = (RenameDlg_Mode)( M_MULTI | M_SKIP | M_OVERWRITE );	  string tmp2 = l.back().url();	  RenameDlg_Result r = open_RenameDlg( dit->m_strAbsSource.c_str(), tmp2.c_str(), m, n );	  if ( r == R_CANCEL ) 	  {	    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 );	    // The new path with trailing '/'	    string tmp3 = u.path( 1 );	    renamed( tmp3.c_str() );	    ///////	    // Replace old path with tmp3 	    ///////	    list<CopyDir>::iterator dit2 = dit;	    // Change the current one and strip the trailing '/'	    dit2->m_strRelDest = u.path( -1 );	    // Change the name of all subdirectories	    dit2++;	    for( ; dit2 != dirs.end(); dit2++ )	      if ( strncmp( dit2->m_strRelDest.c_str(), old_path.c_str(), old_path.size() ) == 0 )		dit2->m_strRelDest.replace( 0, old_path.size(), tmp3 );	    // Change all filenames	    list<Copy>::iterator fit2 = files.begin();	    for( ; fit2 != files.end(); fit2++ )	      if ( strncmp( fit2->m_strRelDest.c_str(), old_path.c_str(), old_path.size() ) == 0 )		fit2->m_strRelDest.replace( 0, old_path.size(), tmp3 );	    // Dont clear error => we will repeat the current command	  }	  else if ( r == R_SKIP )	  {	    // Skip all files and directories that start with 'old_url'	    skip_list.push_back( old_url );	    // Clear the error => The current command is not repeated => skipped	    job.clearError();	  }	  else if ( r == R_AUTO_SKIP )	  {	    // Skip all files and directories that start with 'old_url'	    skip_list.push_back( old_url );	    // Clear the error => The current command is not repeated => skipped	    job.clearError();	    auto_skip = true;	  }	  else if ( r == R_OVERWRITE )	  {	    // Dont bother for subdirectories	    overwrite_list.push_back( old_url );	    // Clear the error => The current command is not repeated => we will	    // overwrite every file in this directory or any of its subdirectories	    job.clearError();	  }	  else if ( r == R_OVERWRITE_ALL )	  {	    job.clearError();	    overwrite_all = true;	  }	  else	    assert( 0 );	}	// No need to ask the user, so raise an error	else	{    	  error( job.errorId(), job.errorText() );	  m_cmd = CMD_NONE;	  return;	}      }    }    while( job.hasError() );          processedDirs( ++processed_dirs );  }  debug( "kio_file : Created directories %s", dest.c_str() );    /*****   * 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;    // Repeat until we got no error    do {       job.clearError();      list<K2URL> l( lst );      l.back().setPath( fit->m_strRelDest.c_str() );          // debug( "kio_file : ########### 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 ?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -