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

📄 kio_file.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
字号:
/*  This file is part of the KDE project    Copyright (C) 2000-2001 Simon Hausmann <hausmann@kde.org>    Copyright (C) 2001 Dirk Mueller <mueller@kde.org>    Copyright (C) 2002-2003 Paul Chitescu <paulc-devel@null.ro>    Copyright (C) 2003 Luciano Montanaro <mikelima@cirulla.net>    Copyright (C) 2005 Fastweb SpA    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public License    along with this library; see the file COPYING.LIB.  If not, write to    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,    Boston, MA 02110-1301, USA.*/#include <config.h>#include "kio_file.h"#include <qdir.h>#include <qfileinfo.h>#include <qtextstream.h>#include <qregexp.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <kglobal.h>#include <kconfig.h>#include <klocale.h>using namespace KIO;#define MAX_IPC_SIZE (1024*32)#define HDR_IPC_SIZE (1024)File::File( const QString &prot )    : SlaveBase( prot.local8Bit() ){}File::~File(){}void File::get( const KURL &url ){    QString path = url.path();#if defined(ENABLE_CGI)    bool mayExec = false;    bool asProxy = false;    {        KConfig *config = KGlobal::config();        KConfigGroupSaver saver( config, QString::fromLatin1( "Local Protocols" ) );	QString temp=config->readEntry( mProtocol, QString::null );	if ( temp.startsWith("*") )	{	    temp.remove( 0, 1 );	    mayExec = true;	}	else if ( temp.startsWith("!") )	{	    temp.remove( 0, 1 );	    mayExec = true;	    asProxy = true;	    path="";	}	if ( temp.startsWith("~") )	{	    temp.remove( 0, 1 );	    temp.prepend( QDir::homeDirPath() );	}	path=temp+path;    }    if ( path.contains("/../") || path.endsWith("/..") )    {        error( KIO::ERR_MALFORMED_URL, path );        return;    }#endif    QFileInfo info( path );    if ( !info.exists() )    {        error( KIO::ERR_DOES_NOT_EXIST, path );        return;    }    if ( info.isFile() )    {        QFile file( path );	unsigned long bytes_read = 0;	bool can_exec = info.isExecutable() &&	     info.permission( QFileInfo::ExeUser | QFileInfo::ExeGroup | QFileInfo::ExeOther );#if defined(ENABLE_CGI)	QByteArray tryHeader;	if ( mayExec && can_exec )	{	    QString referrer = metaData( "referrer" );	    int pipefd[2];	    if ( ::pipe( pipefd ) )	    {		error( KIO::ERR_UNKNOWN, path );		return;	    }	    int pid = fork();	    if ( pid == -1 )	    {		error( KIO::ERR_CANNOT_LAUNCH_PROCESS, path );		return;	    }	    if ( pid == 0 )	    { // in child here		::close( pipefd [0] );		if ( ::dup2( pipefd[1], 1 ) == -1 )		    ::exit( errno );		int i;		for ( i=getdtablesize(); i >= 3 ; i-- )		    ::close( i );		::setenv( "GATEWAY_INTERFACE", "LOCAL-CGI/1.1", true );		::setenv( "SCRIPT_NAME", url.path().latin1(), true );		::setenv( "SCRIPT_FILENAME", path.latin1(), true );		::setenv( "REQUEST_METHOD", "GET", true );		::setenv( "REQUEST_URL", url.url().latin1(), true );		::setenv( "REQUEST_URI", url.encodedPathAndQuery().latin1(), true );		if ( url.hasHost() )		    ::setenv( "SERVER_NAME", url.host().latin1(), true );		if ( url.port() )		    ::setenv( "SERVER_PORT", QString::number( url.port() ).latin1(), true );		if ( !url.query().isEmpty() )		    ::setenv( "QUERY_STRING", url.query().mid( 1 ).latin1(), true );		if ( url.hasUser() )		    ::setenv( "PROTOCOL_USER_NAME", url.user().latin1(), true );		if ( url.hasPass() )		    ::setenv( "PROTOCOL_USER_PASS", url.pass().latin1(), true );		if ( !referrer.isEmpty() )		    ::setenv( "PROTOCOL_REFERER", referrer.latin1(), true );		::setenv( "PROTOCOL_NAME", mProtocol.data(), true );		QDir::setCurrent( info.dirPath( true ) );		execl( path.latin1(), path.latin1(), 0 );		::exit( errno );	    }	    ::close( pipefd[1] );	    if ( !file.open( IO_ReadOnly, pipefd[0] ) )	    {		::close( pipefd[0] );        	error( KIO::ERR_CANNOT_OPEN_FOR_READING, path );		return;	    }	    // Expect header lines, prepare to put back non-header data	    tryHeader.resize( HDR_IPC_SIZE );	    int n = 0;	    bool eatNewline = false;	    for ( ; ; )	    {		// QFile from pipe is very broken... we read each char		//  we also can't rely on atEnd() and readch()		QString h;		for ( n = 0; n < HDR_IPC_SIZE; )		{		    char c;		    if ( file.readBlock( &c, 1 ) != 1 )			break;		    tryHeader[n++] = c;		    if ( c == '\n' )			break;		    if ( c != '\r' )			h.append( c );		}		if ( h.isEmpty() )		{		    if ( eatNewline )			n = 0;		    break;		}		eatNewline = true;		// HACK: KIO::ERR_COULD_NOT_LOGIN displays the message verbatim		//       Use BELL ( \a, \007, ^G ) characters to insert newline		if ( h.lower().startsWith( "error:" ) )		    error( KIO::ERR_COULD_NOT_LOGIN, h.mid( 6 ).stripWhiteSpace()					.replace( QRegExp( "\a" ), "\n" ) );		else if ( h.lower().startsWith( "content-type:" ) )		    mimeType( h.mid( 13 ).stripWhiteSpace() );		else if ( h.lower().startsWith( "content-length:" ) )		    totalSize( h.mid( 15 ).stripWhiteSpace().toUInt() );		else if ( h.lower().startsWith( "location:" ) )		    redirection( KURL( url, h.mid( 9 ).stripWhiteSpace() ) );		else if ( h.lower().startsWith( "processed-size:" ) )		    processedSize( h.mid( 15 ).stripWhiteSpace().toUInt() );		else if ( h.lower().startsWith( "info-message:" ) )		    infoMessage( h.mid( 13 ).stripWhiteSpace() );		else		    break; // will put back the n bytes read	    }	    tryHeader.resize( n );	}	else#endif	{	    if ( !file.open( IO_ReadOnly ) )	    {        	error( KIO::ERR_CANNOT_OPEN_FOR_READING, path );        	return;	    }	    totalSize( info.size() );	    if ( can_exec )		mimeType( "application/x-executable" );        }	for ( ; ; )        {            QByteArray buffer( MAX_IPC_SIZE );	    int n = 0;#if defined(ENABLE_CGI)	    if ( !tryHeader.isEmpty() )	    {		// We have some data, put it back only once		n = tryHeader.size();		memcpy( buffer.data(), tryHeader.data(), n );		tryHeader.resize( 0 );	    }#endif	    n += file.readBlock( buffer.data()+n, buffer.size()-n );	    if ( n == 0 )		break;            if ( n == -1 )            {                error( KIO::ERR_COULD_NOT_READ, path );                return;            }            buffer.truncate( n );	    bytes_read += n;	    processedSize( bytes_read );            data( buffer );        }        data( QByteArray() ); // signal end of data    }    else if ( info.isDir()#if defined(ENABLE_CGI)	      && !asProxy#endif			   )    {	int sort_mode = QDir::IgnoreCase | QDir::DirsFirst;#ifdef SORT_DIRLIST	QString q = url.query();	if ( q.contains( "=D" ) )	    sort_mode |= QDir::Reversed;	if ( q.startsWith( "?U" ) )	{	    sort_mode |= QDir::Unsorted;	    sort_mode &= ~QDir::DirsFirst;	}	else if ( q.startsWith( "?N=" ) )	    sort_mode |= QDir::Name;	else if ( q.startsWith( "?M=" ) )	{	    sort_mode |= QDir::Time;	    // Qt ascending/descending sorting for time and size is buggy	    sort_mode ^= QDir::Reversed;	}	else if ( q.startsWith( "?S=" ) )	{	    sort_mode |= QDir::Size;	    sort_mode ^= QDir::Reversed;	}	else#endif	    sort_mode |= QDir::Name;	mimeType( "inode/directory" );        QDir dir( info.absFilePath(), QString::null, sort_mode );        const QFileInfoList *entries = dir.entryInfoList();		if ( entries )	{  	    totalSize( entries->count() );	    // the header	    QByteArray header_buffer;	    QTextStream header_stream( header_buffer, IO_WriteOnly );	    header_stream << QString::fromLatin1( "<html><body><pre>" );#ifdef SORT_DIRLIST	    header_stream << i18n( "<b>Sort:</b> "		"<a href=\"?U\">Unsorted</a> "		"<a href=\"?N=A\">+Name</a> "		"<a href=\"?N=D\">-Name</a> "		"<a href=\"?S=A\">+Size</a> "		"<a href=\"?S=D\">-Size</a> "		"<a href=\"?M=A\">+Date</a> "		"<a href=\"?M=D\">-Date</a>" );	    header_stream << QString::fromLatin1( "\n<hr>\n" );#endif	    data( header_buffer );    	    QFileInfoListIterator it( *entries );	    for ( unsigned long c = 0; it.current(); ++it )	    {		if ( it.current()->fileName() == "." ) continue;		if ( it.current()->fileName() == ".." &&		    url.path() == "/" ) continue;		QString f_path( it.current()->absFilePath() );		QString f_name( it.current()->fileName() );		if ( it.current()->isDir() )		{		    f_name.prepend( "<b>" ).append( "</b>" );		    if ( f_path.right( 1 ) != "/" && !it.current()->isSymLink() )			f_path.append( "/" );#ifdef SORT_DIRLIST		    f_path.append( url.query() );#endif		}	    	QByteArray buffer;		QTextStream stream( buffer, IO_WriteOnly );	        stream << QString::fromLatin1( "<a href=\"file:%1\">%2</a>\n" )		    .arg( f_path )		    .arg( f_name );		processedSize( ++c );		data( buffer );	    }	    // the footer	    QByteArray footer_buffer;	    QTextStream footer_stream( header_buffer, IO_WriteOnly );	    footer_stream << QString::fromLatin1( "</pre></body></html>" );	    data( footer_buffer );	    data( QByteArray() );        }	    }    else    {        error( KIO::ERR_DOES_NOT_EXIST, path );        return;    }    finished();}bool File::implementsProto( const QString &prot ){    if ( prot == "file" ) return true;#if defined(ENABLE_CGI)    KConfig *config = KGlobal::config();    KConfigGroupSaver saver( config, QString::fromLatin1( "Local Protocols" ) );    return !config->readEntry( prot, QString::null ).isEmpty();#else    return false;#endif}

⌨️ 快捷键说明

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