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

📄 ftp.cc

📁 将konqueror浏览器移植到ARM9 2410中
💻 CC
📖 第 1 页 / 共 4 页
字号:
                    if ( p_access[0] == 'l' )                    {                      tmp = p_name;                      int i = tmp.findRev( QString::fromLatin1(" -> ") );                      if ( i != -1 ) {                        de.link = p_name + i + 4;                        tmp.truncate( i );                        p_name = tmp.ascii();                      }                      else                        de.link = QString::null;                    }                    else                      de.link = QString::null;                                          if (strchr(p_name, '/'))                       return 0L; // Don't trick us!                                        de.access = 0;                    de.type = S_IFREG;                    switch ( p_access[0] ) {                        case 'd':                            de.type = S_IFDIR;                            break;                        case 's':                            de.type = S_IFSOCK;                            break;                        case 'b':                            de.type = S_IFBLK;                            break;                        case 'c':                            de.type = S_IFCHR;                            break;                        case 'l':                            de.type = S_IFREG;                            // we don't set S_IFLNK here.  de.link says it.                            break;                        default:                            break;                    }                    if ( p_access[1] == 'r' )                      de.access |= S_IRUSR;                    if ( p_access[2] == 'w' )                      de.access |= S_IWUSR;                    if ( p_access[3] == 'x' )                      de.access |= S_IXUSR;                    if ( p_access[4] == 'r' )                      de.access |= S_IRGRP;                    if ( p_access[5] == 'w' )                      de.access |= S_IWGRP;                    if ( p_access[6] == 'x' )                      de.access |= S_IXGRP;                    if ( p_access[7] == 'r' )                      de.access |= S_IROTH;                    if ( p_access[8] == 'w' )                      de.access |= S_IWOTH;                    if ( p_access[9] == 'x' )                      de.access |= S_IXOTH;                    // maybe fromLocal8Bit would be better in some cases,                    // but what proves that the ftp server is in the same encoding                    // than the user ??                    de.owner    = QString::fromLatin1(p_owner);                    de.group    = QString::fromLatin1(p_group);                    de.size     = atoi(p_size);                    QCString tmp( p_name );                    // Some sites put more than one space between the date and the name                    // e.g. ftp://ftp.uni-marburg.de/mirror/                    de.name     = QString::fromLatin1(tmp.stripWhiteSpace());                    // Parsing the date is somewhat tricky                    // Examples : "Oct  6 22:49", "May 13  1999"                    // First get current time - we need the current month and year                    time_t currentTime = time( 0L );                    struct tm * tmptr = gmtime( &currentTime );                    int currentMonth = tmptr->tm_mon;                    //kdDebug(7102) << "Current time :" << asctime( tmptr ) << endl;                    // Reset time fields                    tmptr->tm_sec = 0;                    tmptr->tm_min = 0;                    tmptr->tm_hour = 0;                    // Get day number (always second field)                    tmptr->tm_mday = atoi( p_date_2 );                    // Get month from first field                    // NOTE : no, we don't want to use KLocale here                    // It seems all FTP servers use the English way		    //kdDebug() << "Looking for month " << p_date_1 << endl;                    static const char * s_months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",                                                       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };                    for ( int c = 0 ; c < 12 ; c ++ )                      if ( !strcmp( p_date_1, s_months[c]) )                      {			//kdDebug() << "Found month " << c << " for " << p_date_1 << endl;                        tmptr->tm_mon = c;                        break;                      }                    // Parse third field                    if ( strlen( p_date_3 ) == 4 ) // 4 digits, looks like a year                      tmptr->tm_year = atoi( p_date_3 ) - 1900;                    else                    {                      // otherwise, the year is implicit                      // according to man ls, this happens when it is between than 6 months                      // old and 1 hour in the future.                      // So the year is : current year if tm_mon <= currentMonth+1                      // otherwise current year minus one                      // (The +1 is a security for the "+1 hour" at the end of the month issue)                      if ( tmptr->tm_mon > currentMonth + 1 )                        tmptr->tm_year--;                      // and p_date_3 contains probably a time                      char * semicolon;                      if ( ( semicolon = (char*)strchr( p_date_3, ':' ) ) )                      {                        *semicolon = '\0';                        tmptr->tm_min = atoi( semicolon + 1 );                        tmptr->tm_hour = atoi( p_date_3 );                      }                      else                        kdWarning(7102) << "Can't parse third field " << p_date_3 << endl;                    }                    //kdDebug(7102) << asctime( tmptr ) << endl;                    de.date = mktime( tmptr );                    return( &de );                  }          }  return 0L;}bool Ftp::ftpCloseDir(){  if( dirfile )  {    kdDebug(7102) << "... closing" << endl;    if ( ! ftpCloseCommand() )      return false;    fclose( dirfile );    dirfile = 0L;  } else    kdDebug(7102) << "ftpCloseDir but no dirfile ??" << endl;  return true;}//////////// get, put ////////void Ftp::get( const KURL & url ){  kdDebug(7102) << "Ftp::get " << url.url() << endl;  if (!m_bLoggedOn)  {      openConnection();      if (!m_bLoggedOn)      {        kdDebug(7102) << "Login failure, aborting" << endl;        return;      }  }  // try to find the size of the file (and check that it exists at the same time)  // 550 is "File does not exist"/"not a plain file"  if ( !ftpSize( url.path(), 'I' ) && strncmp( rspbuf, "550", 3) == 0 )  {      // Not a file, or doesn't exist. We need to find out.      QCString tmp = "cwd ";      tmp += url.path().latin1();      if ( ftpSendCmd( tmp, '2' ) )      {          // Ok it's a dir in fact          kdDebug(7102) << "Ftp::get: it is a directory in fact" << endl;          error( ERR_IS_DIRECTORY, url.path() );      }      else      {          kdDebug(7102) << "Ftp::get: doesn't exist" << endl;          error( ERR_DOES_NOT_EXIST, url.path() );      }      return;  }  unsigned long offset = 0;  QString resumeOffset = metaData(QString::fromLatin1("resume"));  if ( !resumeOffset.isEmpty() )  {      offset = resumeOffset.toInt();      kdDebug(7102) << "Ftp::get got offset from medata : " << offset << endl;  }  if ( !ftpOpenCommand( "retr", url.path(), 'I', ERR_CANNOT_OPEN_FOR_READING, offset ) ) {    kdWarning(7102) << "Can't open for reading" << endl;    return;  }  // Read the size from the response string  if ( strlen( rspbuf ) > 4 && m_size == 0 ) {    const char * p = strrchr( rspbuf, '(' );    if ( p != 0L ) m_size = atol( p + 1 );  }  size_t bytesLeft = m_size - offset;  kdDebug(7102) << "Ftp::get starting with offset=" << offset << endl;  int processed_size = offset;  time_t t_start = time( 0L );  time_t t_last = t_start;  char buffer[ 2048 ];  QByteArray array;  QByteArray mimetypeBuffer;  bool mimetypeEmitted = false;  while( bytesLeft > 0 )  {    int n = ftpRead( buffer, 2048 );    bytesLeft -= n;    // Buffer the first 1024 bytes for mimetype determination    if ( !mimetypeEmitted )    {      int oldSize = mimetypeBuffer.size();      mimetypeBuffer.resize(oldSize + n);      memcpy(mimetypeBuffer.data()+oldSize, buffer, n);      // Found enough data - or we're arriving to the end of the file -> emit mimetype      if (mimetypeBuffer.size() >= 1024 || bytesLeft <= 0)      {        KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( mimetypeBuffer, url.fileName() );        kdDebug(7102) << "Emitting mimetype " << result->mimeType() << endl;        mimeType( result->mimeType() );        mimetypeEmitted = true;        data( mimetypeBuffer );        mimetypeBuffer.resize(0);        // Emit total size AFTER mimetype        totalSize( m_size );      }    }    else if ( n > 0 )    {      array.setRawData(buffer, n);      data( array );      array.resetRawData(buffer, n);    }    else // unexpected eof. Happens when the daemon gets killed.    {      error( ERR_COULD_NOT_READ, url.path() );      return;    }    processed_size += n;    time_t t = time( 0L );    if ( t - t_last >= 1 ) {      processedSize( processed_size );      speed( ( processed_size - offset ) / ( t - t_start ) );      t_last = t;    }  }  kdDebug(7102) << "Get: done, sending empty QByteArray" << endl;  data( QByteArray() );  kdDebug(7102) << "Get: calling ftpCloseCommand()" << endl;  (void) ftpCloseCommand();  // proceed even on error  processedSize( m_size );  time_t t = time( 0L );  if ( t - t_start >= 1 )    speed( ( processed_size - offset ) / ( t - t_start ) );  kdDebug(7102) << "Get: emitting finished()" << endl;  finished();}/*void Ftp::mimetype( const KURL& url ){  if (!m_bLoggedOn)  {      openConnection();      if (!m_bLoggedOn)      {        kdDebug(7102) << "Login failure, aborting" << endl;        return;      }  }  if ( !ftpOpenCommand( "retr", url.path(), 'I', ERR_CANNOT_OPEN_FOR_READING, 0 ) ) {    kdWarning(7102) << "Can't open for reading" << endl;    return;  }  char buffer[ 2048 ];  QByteArray array;  // Get one chunk of data only and send it, KIO::Job will determine the  // mimetype from it using KMimeMagic  int n = ftpRead( buffer, 2048 );  array.setRawData(buffer, n);  data( array );  array.resetRawData(buffer, n);  kdDebug(7102) << "aborting" << endl;  ftpAbortTransfer();  kdDebug(7102) << "finished" << endl;  finished();  kdDebug(7102) << "after finished" << endl;}void Ftp::ftpAbortTransfer(){  // RFC 959, page 34-35  // IAC (interpret as command) = 255 ; IP (interrupt process) = 254  // DM = 242 (data mark)   char msg[4];   // 1. User system inserts the Telnet "Interrupt Process" (IP) signal   //   in the Telnet stream.   msg[0] = (char) 255; //IAC   msg[1] = (char) 254; //IP   (void) send(sControl, msg, 2, 0);   // 2. User system sends the Telnet "Sync" signal.   msg[0] = (char) 255; //IAC   msg[1] = (char) 242; //DM   if (send(sControl, msg, 2, MSG_OOB) != 2)     ; // error...   // Send ABOR   kdDebug(7102) << "send ABOR" << endl;   QCString buf = "ABOR\r\n";   if ( KSocks::self()->write( sControl, buf.data(), buf.length() ) <= 0 )  {     error( ERR_COULD_NOT_WRITE, QString::null );     return;   }   //   kdDebug(7102) << "read resp" << endl;   if ( readresp() != '2' )   {     error( ERR_COULD_NOT_READ, QString::null );     return;   }  kdDebug(7102) << "close sockets" << endl;  closeSockets();}*/void Ftp::put( const KURL& dest_url, int permissions, bool overwrite, bool resume ){  QString dest_orig = dest_url.path();  if (!m_bLoggedOn)  {      openConnection();      if (!m_bLoggedOn)      {        kdDebug(7102) << "Login failure, aborting" << endl;        return;      }  }  kdDebug(7102) << "Put " << dest_orig << endl;  QString dest_part( dest_orig );  dest_part += QString::fromLatin1(".part");  bool bMarkPartial = config()->readBoolEntry("MarkPartial", true);  // Don't use mark partial over anonymous FTP.  // My incoming dir allows put but not rename...  if (m_user == FTP_LOGIN)      bMarkPartial = false;  if ( ftpSize( dest_orig, 'I' ) )  {    if ( m_size == 0 ) {  // delete files with zero size      QCString cmd = "DELE ";      cmd += dest_orig.ascii();      if ( !ftpSendCmd( cmd, '2' ) )      {        error( ERR_CANNOT_DELETE_PARTIAL, dest_orig );        return;      }    } else if ( !overwrite && !resume ) {      error( ERR_FILE_ALREADY_EXIST, dest_orig );      return;    } else if ( bMarkPartial ) { // when using mark partial, append .part extension      if ( !ftpRename( dest_orig, dest_part, true ) )      {        error( KIO::ERR_CANNOT_RENAME_PARTIAL, dest_orig );        return;      }    }    // Don't chmod an existing file    permissions = -1;  } else if ( ftpSize( dest_part, 'I' ) ) { // file with extension .part exists    if ( m_size == 0 ) {  // delete files with zero size      QCString cmd = "DELE ";      cmd += dest_part.ascii();      if ( !ftpSendCmd( cmd, '2' ) )      {        error( ERR_CANNOT_DELETE_PARTIAL, dest_orig );        return;      }    } else if ( !overwrite && !resume ) {      error( ERR_FILE_ALREADY_EXIST, dest_orig );      return;    } else if ( !bMarkPartial ) { // when using mark partial, remove .part extension      if ( !ftpRename( dest_part, dest_orig, true ) )      {        error( KIO::ERR_CANNOT_RENAME_PARTIAL, dest_orig );        return;      }    }  }  QString dest;  // if we are using marking of partial downloads -> add .part extension  if ( bMarkPartial ) {    kdDebug(7102) << "Adding .part extension to " << dest_orig << endl;    dest = dest_part;  } else    dest = dest_orig;  unsigned long offset = 0;  // set the mode according to offset  if ( resume ) {    offset = m_size;    kdDebug(7102) << "Offset = " << (unsigned int) offset << "d" << endl;  }  if (! ftpOpenCommand( "stor", dest, 'I', ERR_COULD_NOT_WRITE, offset ) )    return;  int result;  // Loop until we got 'dataEnd'  do  {    QByteArray buffer;    dataReq(); // Request for data    result = readData( buffer );    if (result > 0)    {      ftpWrite( buffer.data(), buffer.size() );    }  }  while ( result > 0 );  if (result != 0) // error  {    (void) ftpCloseCommand(); // don't care about errors    kdDebug(7102) << "Error during 'put'. Aborting." << endl;    if (bMarkPartial)    {      // Remove if smaller than minimum size      if ( ftpSize( dest, 'I' ) &&           ( m_size < (unsigned long) config()->readNumEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE) ) )      {        QCString cmd = "DELE ";        cmd += dest.ascii();        (void) ftpSendCmd( cmd, '\0' );      }    }    return;  }  if ( !ftpCloseCommand() )  {    error( KIO::ERR_COULD_NOT_WRITE, dest_orig);    return;  }  // after full download rename the file back to original name  if ( bMarkPartial )  {    kdDebug(7102) << "renaming dest (" << dest << ") back to dest_orig (" << dest_orig << ")" << endl;    if ( !ftpRename( dest, dest_orig, true ) )    {      error( KIO::ERR_CANNOT_RENAME_PARTIAL, dest_orig );      return;    }  }  // set final permissions  if ( permissions != -1 )  {    if ( m_user == FTP_LOGIN )      kdDebug(7102) << "Trying to chmod over anonymous FTP ???" << endl;    // chmod the file we just put, ignoring errors.    (void) ftpChmod( dest_orig, permissions );  }  // We have done our job => finish  finished();}/*  This is related to "canResume" ... not sure how  Old main.cc contained:  if ( !ftp.ftpResume( 0 ) )    m_bCanResume = false;bool Ftp::ftpResume( unsigned long offset ){  char buf[64];  sprintf(buf, "rest %ld", offset);  if ( !ftpSendCmd( buf, '3' ) ) {    error( ERR_CANNOT_RESUME, QString::null );    return false;  }  return true;}*//** Use the SIZE command to get the file size.    Warning : the size depends on the transfer mode, hence the second arg. */bool Ftp::ftpSize( const QString & path, char mode ){  QCString buf;  buf.sprintf("type %c", mode);  if ( !ftpSendCmd( buf, '2' ) ) {      return false;  }  buf="SIZE ";  buf+=path.ascii();  if (!ftpSendCmd(buf,'2')) {    m_size = 0;    return false;  }  m_size = atol(rspbuf+4); // skip leading "213 " (response code)  return true;}size_t Ftp::ftpRead(void *buffer, long len){  size_t n = KSocks::self()->read( sData, buffer, len );  return n;}size_t Ftp::ftpWrite(void *buffer, long len){  return( KSocks::self()->write( sData, buffer, len ) );}

⌨️ 快捷键说明

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