diff options
Diffstat (limited to 'kioslave/info/info.cc')
-rw-r--r-- | kioslave/info/info.cc | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/kioslave/info/info.cc b/kioslave/info/info.cc new file mode 100644 index 000000000..6b829ec1c --- /dev/null +++ b/kioslave/info/info.cc @@ -0,0 +1,261 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include <qdir.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qregexp.h> + +#include <kdebug.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <klocale.h> + +#include "info.h" + +using namespace KIO; + +InfoProtocol::InfoProtocol( const QCString &pool, const QCString &app ) + : SlaveBase( "info", pool, app ) + , m_page( "" ) + , m_node( "" ) +{ + kdDebug( 7108 ) << "InfoProtocol::InfoProtocol" << endl; + + m_perl = KGlobal::dirs()->findExe( "perl" ); + m_infoScript = locate( "data", "kio_info/kde-info2html" ); + m_infoConf = locate("data", "kio_info/kde-info2html.conf"); + + if( m_perl.isNull() || m_infoScript.isNull() || m_infoConf.isNull() ) { + kdError( 7108 ) << "Critical error: Cannot locate files for HTML-conversion" << endl; + QString errorStr; + if ( m_perl.isNull() ) { + errorStr = "perl."; + } else { + QString missing =m_infoScript.isNull() ? "kio_info/kde-info2html" : "kio_info/kde-info2html.conf"; + errorStr = "kde-info2html" + i18n( "\nUnable to locate file %1 which is necessary to run this service. " + "Please check your software installation" ).arg( missing ); + } + error( KIO::ERR_CANNOT_LAUNCH_PROCESS, errorStr ); + exit(); + } + + kdDebug( 7108 ) << "InfoProtocol::InfoProtocol - done" << endl; +} + +InfoProtocol::~InfoProtocol() +{ + kdDebug( 7108 ) << "InfoProtocol::~InfoProtocol" << endl; + + kdDebug( 7108 ) << "InfoProtocol::~InfoProtocol - done" << endl; +} + +void InfoProtocol::get( const KURL& url ) +{ + kdDebug( 7108 ) << "InfoProtocol::get" << endl; + kdDebug( 7108 ) << "URL: " << url.prettyURL() << " , Path :" << url.path() << endl; + + if (url.path()=="/") + { + KURL newUrl("info:/dir"); + redirection(newUrl); + finished(); + return; + }; + + // some people write info://autoconf instead of info:/autoconf + if (!url.host().isEmpty()) { + KURL newURl(url); + newURl.setPath(url.host()+url.path()); + newURl.setHost(QString::null); + redirection(newURl); + finished(); + return; + } + + if ( url.path().right(1) == "/" ) + { + // Trailing / are not supported, so we need to remove them. + KURL newUrl( url ); + QString newPath( url.path() ); + newPath.truncate( newPath.length()-1 ); + newUrl.setPath( newPath ); + redirection( newUrl ); + finished(); + return; + } + + mimeType("text/html"); + // extract the path and node from url + decodeURL( url ); + + QString path = KGlobal::iconLoader()->iconPath("up", KIcon::Toolbar, true); + int revindex = path.findRev('/'); + path = path.left(revindex); + + QString cmd = KProcess::quote(m_perl); + cmd += " "; + cmd += KProcess::quote(m_infoScript); + cmd += " "; + cmd += KProcess::quote(m_infoConf); + cmd += " "; + cmd += KProcess::quote(path); + cmd += " "; + cmd += KProcess::quote(m_page); + cmd += " "; + cmd += KProcess::quote(m_node); + + kdDebug( 7108 ) << "cmd: " << cmd << endl; + + FILE *file = popen( QFile::encodeName(cmd), "r" ); + if ( !file ) { + kdDebug( 7108 ) << "InfoProtocol::get popen failed" << endl; + error( ERR_CANNOT_LAUNCH_PROCESS, cmd ); + return; + } + + char buffer[ 4096 ]; + QByteArray array; + + bool empty = true; + while ( !feof( file ) ) + { + int n = fread( buffer, 1, sizeof( buffer ), file ); + if ( !n && feof( file ) && empty ) { + error( ERR_CANNOT_LAUNCH_PROCESS, cmd ); + return; + } + if ( n < 0 ) + { + // ERROR + kdDebug( 7108 ) << "InfoProtocol::get ERROR!" << endl; + pclose( file ); + return; + } + + empty = false; + array.setRawData( buffer, n ); + data( array ); + array.resetRawData( buffer, n ); + } + + pclose( file ); + + finished(); + + kdDebug( 7108 ) << "InfoProtocol::get - done" << endl; +} + +void InfoProtocol::mimetype( const KURL& /* url */ ) +{ + kdDebug( 7108 ) << "InfoProtocol::mimetype" << endl; + + // to get rid of those "Open with" dialogs... + mimeType( "text/html" ); + + // finish action + finished(); + + kdDebug( 7108 ) << "InfoProtocol::mimetype - done" << endl; +} + +void InfoProtocol::decodeURL( const KURL &url ) +{ + kdDebug( 7108 ) << "InfoProtocol::decodeURL" << endl; + + /* Notes: + * + * I cleaned up the URL decoding and chose not to support URLs in the + * form "info:/usr/local/share/info/libc.info.gz" or similar which the + * older code attempted (and failed, maybe it had worked once) to do. + * + * The reason is that an obvious use such as viewing a info file off your + * infopath would work for the first page, but then all the links would be + * wrong. Of course, one could change kde-info2html to make it work, but I don't + * think it worthy, others are free to disagree and write the necessary code ;) + * + * luis pedro + */ + + if ( url == KURL( "info:/browse_by_file?special=yes" ) ) { + m_page = "#special#"; + m_node = "browse_by_file"; + kdDebug( 7108 ) << "InfoProtocol::decodeURL - special - browse by file" << endl; + return; + } + + decodePath( url.path() ); + + kdDebug( 7108 ) << "InfoProtocol::decodeURL - done" << endl; +} + +void InfoProtocol::decodePath( QString path ) +{ + kdDebug( 7108 ) << "InfoProtocol::decodePath(-" <<path<<"-)"<< endl; + + m_page = "dir"; //default + m_node = ""; + + // remove leading slash + if ('/' == path[0]) { + path = path.mid( 1 ); + } + //kdDebug( 7108 ) << "Path: " << path << endl; + + int slashPos = path.find( "/" ); + + if( slashPos < 0 ) + { + m_page = path; + m_node = "Top"; + return; + } + + m_page = path.left( slashPos ); + + // remove leading+trailing whitespace + m_node = path.right( path.length() - slashPos - 1).stripWhiteSpace (); + + kdDebug( 7108 ) << "InfoProtocol::decodePath - done" << endl; +} + +// A minimalistic stat with only the file type +// This seems to be enough for konqueror +void InfoProtocol::stat( const KURL & ) +{ + UDSEntry uds_entry; + UDSAtom uds_atom; + + // Regular file with rwx permission for all + uds_atom.m_uds = KIO::UDS_FILE_TYPE; + uds_atom.m_long = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO; + + uds_entry.append( uds_atom ); + + statEntry( uds_entry ); + + finished(); +} + +extern "C" { int KDE_EXPORT kdemain( int argc, char **argv ); } + +int kdemain( int argc, char **argv ) +{ + KInstance instance( "kio_info" ); + + kdDebug() << "kio_info starting " << getpid() << endl; + + if (argc != 4) + { + fprintf(stderr, "Usage: kio_info protocol domain-socket1 domain-socket2\n"); + exit(-1); + } + + InfoProtocol slave( argv[2], argv[3] ); + slave.dispatchLoop(); + + return 0; +} |