📄 file.cc
字号:
string filename = fit->m_strAbsSource; debug( "kio_file : Deleting file %s", filename.c_str() ); deletingFile( filename.c_str() ); if ( unlink( filename.c_str() ) == -1 ) { error( ERR_CANNOT_DELETE, filename.c_str() ); m_cmd = CMD_NONE; return; } } /***** * Delete empty directories *****/ list<CopyDir>::iterator dit = ds.begin(); for( ; dit != ds.end(); dit++ ) { string dirname = dit->m_strAbsSource; debug( "kio_file : Deleting directory %s", dirname.c_str() ); deletingFile( dirname.c_str() ); if ( rmdir( dirname.c_str() ) == -1 ) { error( ERR_COULD_NOT_RMDIR, dirname.c_str() ); m_cmd = CMD_NONE; return; } } finished(); m_cmd = CMD_NONE;}void FileProtocol::slotListDir( const char *_url ){ 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 file in list command" ); m_cmd = CMD_NONE; return; } struct stat buff; if ( stat( usrc.path(), &buff ) == -1 ) { error( ERR_DOES_NOT_EXIST, url.c_str() ); m_cmd = CMD_NONE; return; } if ( !S_ISDIR( buff.st_mode ) ) { error( ERR_IS_FILE, url.c_str() ); m_cmd = CMD_NONE; return; } m_cmd = CMD_LIST; DIR *dp = 0L; struct dirent *ep; string dir = usrc.path( 0 ); dp = opendir( dir.c_str() ); if ( dp == 0L ) { error( ERR_CANNOT_ENTER_DIRECTORY, url.c_str() ); m_cmd = CMD_NONE; return; } while ( ( ep = readdir( dp ) ) != 0L ) { if ( strcmp( ep->d_name, "." ) == 0 || strcmp( ep->d_name, ".." ) == 0 ) continue; // debug( "kio_file : Listing %s", ep->d_name ); UDSEntry entry; UDSAtom atom; atom.m_uds = UDS_NAME; atom.m_str = ep->d_name; entry.push_back( atom ); string tmp = usrc.path( 1 ); tmp += ep->d_name; string slink = ""; mode_t type; mode_t access; struct stat buff; struct stat lbuff; if ( stat( tmp.c_str(), &buff ) == -1 ) { // A link poiting to nowhere ? if ( lstat( tmp.c_str(), &lbuff ) == -1 ) { // Should never happen error( ERR_DOES_NOT_EXIST, tmp.c_str() ); m_cmd = CMD_NONE; return; } // It is a link pointing to nowhere type = S_IFMT - 1; access = S_IRWXU | S_IRWXG | S_IRWXO; } else { lstat( tmp.c_str(), &lbuff ); type = buff.st_mode; access = buff.st_mode; // Is it a link if ( S_ISLNK( lbuff.st_mode ) ) { // it is save to set this bit here since it belongs to access and has no meaning here type |= S_ISVTX; char buffer2[ 1000 ]; int n = readlink( tmp.c_str(), buffer2, 1000 ); if ( n != -1 ) { buffer2[ n ] = 0; slink = buffer2; } } else type &= S_IFMT; } struct passwd * user = getpwuid( buff.st_uid ); struct group * grp = getgrgid( buff.st_gid ); atom.m_uds = UDS_FILE_TYPE; atom.m_long = type; entry.push_back( atom ); atom.m_uds = UDS_SIZE; atom.m_long = buff.st_size; entry.push_back( atom ); atom.m_uds = UDS_MODIFICATION_TIME; atom.m_long = buff.st_mtime; entry.push_back( atom ); atom.m_uds = UDS_ACCESS; atom.m_long = access; entry.push_back( atom ); atom.m_uds = UDS_USER; atom.m_str = (( user != 0L ) ? user->pw_name : "???" ); entry.push_back( atom ); atom.m_uds = UDS_GROUP; atom.m_str = (( grp != 0L ) ? grp->gr_name : "???" ); entry.push_back( atom ); atom.m_uds = UDS_LINK_DEST; atom.m_str = slink; entry.push_back( atom ); atom.m_uds = UDS_ACCESS_TIME; atom.m_long = buff.st_atime; entry.push_back( atom ); atom.m_uds = UDS_CREATION_TIME; atom.m_long = buff.st_ctime; entry.push_back( atom ); listEntry( entry ); } closedir( dp ); m_cmd = CMD_NONE; finished();}void FileProtocol::slotTestDir( const char *_url ){ 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 file in testdir command" ); m_cmd = CMD_NONE; return; } struct stat buff; if ( stat( usrc.path(), &buff ) == -1 ) { error( ERR_DOES_NOT_EXIST, url.c_str() ); m_cmd = CMD_NONE; return; } if ( S_ISDIR( buff.st_mode ) ) isDirectory(); else isFile(); finished();}void FileProtocol::slotMount( bool _ro, const char *_fstype, const char* _dev, const char *_point ){ char buffer[ 1024 ]; int t = (int)time( 0L ); // Look in /etc/fstab ? if ( *_fstype == 0 || *_point == 0 ) sprintf( buffer, "mount %s 2>/tmp/mnt%i",_dev, t ); else if ( _ro ) sprintf( buffer, "mount -rt %s %s %s 2>/tmp/mnt%i",_fstype, _dev, _point, t ); else sprintf( buffer, "mount -t %s %s %s 2>/tmp/mnt%i",_fstype, _dev, _point, t ); system( buffer ); sprintf( buffer, "/tmp/mnt%i", t ); string err = testLogFile( buffer ); if ( err.empty() ) { finished(); return; } error( ERR_COULD_NOT_MOUNT, err.c_str() ); m_cmd = CMD_NONE; return;}void FileProtocol::slotUnmount( const char *_point ){ char buffer[ 1024 ]; int t = (int)time( 0L ); sprintf( buffer, "umount %s 2>/tmp/mnt%i",_point, t ); system( buffer ); sprintf( buffer, "/tmp/mnt%i", t ); string err = testLogFile( buffer ); if ( err.empty() ) { finished(); return; } error( ERR_COULD_NOT_MOUNT, err.c_str() ); m_cmd = CMD_NONE; return;}void FileProtocol::slotData( void *_p, int _len ){ switch( m_cmd ) { case CMD_PUT: fwrite( _p, 1, _len, m_fPut ); break; }}void FileProtocol::slotDataEnd(){ switch( m_cmd ) { case CMD_PUT: m_cmd = CMD_NONE; }}long FileProtocol::listRecursive( const char *_path, list<Copy>& _files, list<CopyDir>& _dirs, bool _rename ){ struct stat buff; // Check wether we have to copy the complete directory tree beginning by its root. int len = strlen( _path ); while( len >= 1 && _path[ len -1 ] == '/' ) len--; if ( len == 1 && _path[ 0 ] == '/' ) { if ( stat( "/", &buff ) == -1 ) { error( ERR_DOES_NOT_EXIST, "/" ); return -1; } CopyDir c; c.m_strAbsSource = _path; if ( _rename ) c.m_strRelDest = ""; else c.m_strRelDest = "Root"; c.m_ino = buff.st_ino; c.m_mode = buff.st_mode; _dirs.push_back( c ); return listRecursive2( "/", c.m_strRelDest.c_str(), _files, _dirs ); } string p; p.assign( _path, len ); debug( "kio_file : ########## RECURSIVE LISTING %s", p.c_str() ); if ( stat( p.c_str(), &buff ) == -1 ) { error( ERR_DOES_NOT_EXIST, p.c_str() ); return -1; } K2URL u( p.c_str() ); // Should be checked before, but who knows if ( u.isMalformed() ) assert( 0 ); // Is the source not a directory ? => so just copy it and we are done. if ( !S_ISDIR( buff.st_mode ) ) { string fname; if ( _rename ) fname = ""; else { fname = u.filename(); // Should be impossible, but who knows ... if ( fname.empty() ) assert( 0 ); } Copy c; c.m_strAbsSource = p; c.m_strRelDest = fname; c.m_mode = buff.st_mode; c.m_size = buff.st_size; _files.push_back( c ); return buff.st_size; } // The source is a directory. So we have to go into recursion here. string tmp1; if ( _rename ) tmp1 = u.path( 0 ); else { tmp1 = u.directory( true ); tmp1 += "/"; } string tmp2; if ( _rename ) tmp2 = ""; else tmp2 = u.filename(); CopyDir c; c.m_strAbsSource = p; c.m_strRelDest = tmp2; c.m_mode = buff.st_mode; c.m_ino = buff.st_ino; _dirs.push_back( c ); debug( "kio_file : ########### STARTING RECURSION with %s and %s",tmp1.c_str(), tmp2.c_str() ); return listRecursive2( tmp1.c_str(), tmp2.c_str(), _files, _dirs );}long FileProtocol::listRecursive2( const char *_abs_path, const char *_rel_path, list<Copy>& _files, list<CopyDir>& _dirs ){ long size = 0; string p = _abs_path; p += _rel_path; DIR *dp = 0L; struct dirent *ep; scanningDir( p.c_str() ); dp = opendir( p.c_str() ); if ( dp == 0L ) { error( ERR_CANNOT_ENTER_DIRECTORY, p.c_str() ); return -1; } while ( ( ep = readdir( dp ) ) != 0L ) { if ( strcmp( ep->d_name, "." ) == 0 || strcmp( ep->d_name, ".." ) == 0 ) continue; string p2 = p; p2 += "/"; p2 += ep->d_name; struct stat buff; if ( stat( p2.c_str(), &buff ) == -1 ) { // Should never happen error( ERR_DOES_NOT_EXIST, p.c_str() ); return -1; } string tmp = _rel_path;// if ( tmp != "" ) tmp += "/"; tmp += ep->d_name; if ( !S_ISDIR( buff.st_mode ) ) { Copy c; c.m_strAbsSource = p2; c.m_strRelDest = tmp; c.m_mode = buff.st_mode & ( S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO ); c.m_size = buff.st_size; _files.push_back( c ); size += buff.st_size; } else { // Did we scan this directory already ? // This may happen because a link goes backward in the directory tree list<CopyDir>::iterator it = _dirs.begin(); for( ; it != _dirs.end(); it++ ) if ( it->m_ino == buff.st_ino ) { error( ERR_CYCLIC_LINK, p2.c_str() ); return -1; } CopyDir c; c.m_strAbsSource = p2; c.m_strRelDest = tmp; c.m_mode = buff.st_mode; c.m_ino = buff.st_ino; _dirs.push_back( c ); long s; if ( ( s = listRecursive2( _abs_path, tmp.c_str(), _files, _dirs ) ) == -1 ) return -1; size += s; } } closedir( dp ); return size;}void FileProtocol::jobError( int _errid, const char *_txt ){ if ( !m_bIgnoreJobErrors ) error( _errid, _txt );}/************************************* * * FileIOJob * *************************************/FileIOJob::FileIOJob( Connection *_conn, FileProtocol *_File ) : IOJob( _conn ){ m_pFile = _File;} void FileIOJob::slotError( int _errid, const char *_txt ){ IOJob::slotError( _errid, _txt ); m_pFile->jobError( _errid, _txt );}/************************************* * * Utilities * *************************************/string testLogFile( const char *_filename ){ char buffer[ 1024 ]; struct stat buff; string result; stat( _filename, &buff ); int size = buff.st_size; if ( size == 0 ) { unlink( _filename ); return result; } FILE * f = fopen( _filename, "rb" ); if ( f == 0L ) { unlink( _filename ); result = "Could not read "; result += _filename; return result; } result = ""; char *p = ""; while ( p != 0L ) { p = fgets( buffer, 1023, f ); if ( p != 0L ) result += buffer; } fclose( f ); unlink( _filename ); return result;}int check( Connection *_con ){ int err; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; fd_set rfds; FD_ZERO( &rfds ); FD_SET( _con->inFD(), &rfds ); again: if ( ( err = select( _con->inFD(), &rfds, 0L, 0L, &tv ) ) == -1 && errno == EINTR ) goto again; // No error and something to read ? if ( err != -1 && err != 0 ) return 1; return 0;}void openFileManagerWindow( const char * ){ assert( 0 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -