You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
321 lines
8.2 KiB
321 lines
8.2 KiB
/***************************************************************************
|
|
* Copyright (C) 2004-2007 by Georgy Yunaev, gyunaev@ulduzsoft.com *
|
|
* Please do not use email address above for bug reports; see *
|
|
* the README file *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program 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 General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
|
***************************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <kapplication.h>
|
|
#include <kdebug.h>
|
|
#include <kinstance.h>
|
|
#include <kurl.h>
|
|
#include <kmimemagic.h>
|
|
|
|
#include <tqfile.h>
|
|
#include <tqbitarray.h>
|
|
#include <tqvaluevector.h>
|
|
|
|
#include "msits.h"
|
|
#include "libchmurlfactory.h"
|
|
|
|
using namespace KIO;
|
|
|
|
extern "C"
|
|
{
|
|
int kdemain( int argc, char **argv )
|
|
{
|
|
kdDebug() << "*** kio_msits Init" << endl;
|
|
|
|
KInstance instance( "kio_msits" );
|
|
|
|
if ( argc != 4 )
|
|
{
|
|
kdDebug() << "Usage: kio_msits protocol domain-socket1 domain-socket2" << endl;
|
|
exit (-1);
|
|
}
|
|
|
|
ProtocolMSITS slave ( argv[2], argv[3] );
|
|
slave.dispatchLoop();
|
|
|
|
kdDebug() << "*** kio_msits Done" << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
ProtocolMSITS::ProtocolMSITS (const TQCString &pool_socket, const TQCString &app_socket)
|
|
: SlaveBase ("kio_msits", pool_socket, app_socket)
|
|
{
|
|
m_chmFile = 0;
|
|
}
|
|
|
|
ProtocolMSITS::~ProtocolMSITS()
|
|
{
|
|
if ( !m_chmFile )
|
|
return;
|
|
|
|
chm_close (m_chmFile);
|
|
m_chmFile = 0;
|
|
}
|
|
|
|
// A simple stat() wrapper
|
|
static bool isDirectory ( const TQString & filename )
|
|
{
|
|
return filename[filename.length() - 1] == '/';
|
|
}
|
|
|
|
|
|
void ProtocolMSITS::get( const KURL& url )
|
|
{
|
|
TQString htmdata, fileName;
|
|
chmUnitInfo ui;
|
|
TQByteArray buf;
|
|
|
|
kdDebug() << "kio_msits::get() " << url.path() << endl;
|
|
|
|
if ( !parseLoadAndLookup ( url, fileName ) )
|
|
return; // error() has been called by parseLoadAndLookup
|
|
|
|
kdDebug() << "kio_msits::get: parseLoadAndLookup returned " << fileName << endl;
|
|
|
|
if ( LCHMUrlFactory::handleFileType( url.path(), htmdata ) )
|
|
{
|
|
buf = htmdata.utf8();
|
|
kdDebug() << "Using special handling for image pages: " << htmdata << endl;
|
|
}
|
|
else
|
|
{
|
|
if ( isDirectory (fileName) )
|
|
{
|
|
error( KIO::ERR_IS_DIRECTORY, url.prettyURL() );
|
|
return;
|
|
}
|
|
|
|
if ( !ResolveObject ( fileName, &ui) )
|
|
{
|
|
kdDebug() << "kio_msits::get: could not resolve filename " << fileName << endl;
|
|
error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
|
|
return;
|
|
}
|
|
|
|
buf.resize( ui.length );
|
|
|
|
if ( RetrieveObject (&ui, (unsigned char*) buf.data(), 0, ui.length) == 0 )
|
|
{
|
|
kdDebug() << "kio_msits::get: could not retrieve filename " << fileName << endl;
|
|
error( KIO::ERR_NO_CONTENT, url.prettyURL() );
|
|
return;
|
|
}
|
|
}
|
|
|
|
totalSize( buf.size() );
|
|
KMimeMagicResult * result = KMimeMagic::self()->findBufferFileType( buf, fileName );
|
|
kdDebug() << "Emitting mimetype " << result->mimeType() << endl;
|
|
|
|
mimeType( result->mimeType() );
|
|
data( buf );
|
|
processedSize( buf.size() );
|
|
|
|
finished();
|
|
}
|
|
|
|
|
|
bool ProtocolMSITS::parseLoadAndLookup ( const KURL& url, TQString& abspath )
|
|
{
|
|
kdDebug() << "ProtocolMSITS::parseLoadAndLookup (const KURL&) " << url.path() << endl;
|
|
|
|
int pos = url.path().find ("::");
|
|
|
|
if ( pos == -1 )
|
|
{
|
|
error( KIO::ERR_MALFORMED_URL, url.prettyURL() );
|
|
return false;
|
|
}
|
|
|
|
TQString filename = url.path().left (pos);
|
|
abspath = url.path().mid (pos + 2); // skip ::
|
|
|
|
// Some buggy apps add ms-its:/ to the path as well
|
|
if ( abspath.startsWith( "ms-its:" ) )
|
|
abspath = abspath.mid( 7 );
|
|
|
|
kdDebug() << "ProtocolMSITS::parseLoadAndLookup: filename " << filename << ", path " << abspath << endl;
|
|
|
|
if ( filename.isEmpty() )
|
|
{
|
|
error( KIO::ERR_MALFORMED_URL, url.prettyURL() );
|
|
return false;
|
|
}
|
|
|
|
// If the file has been already loaded, nothing to do.
|
|
if ( m_chmFile && filename == m_openedFile )
|
|
return true;
|
|
|
|
kdDebug() << "Opening a new CHM file " << filename << endl;
|
|
|
|
// First try to open a temporary file
|
|
chmFile * tmpchm;
|
|
|
|
if ( (tmpchm = chm_open ( TQFile::encodeName (filename))) == 0 )
|
|
{
|
|
error( KIO::ERR_COULD_NOT_READ, url.prettyURL() );
|
|
return false;
|
|
}
|
|
|
|
// Replace an existing file by a new one
|
|
if ( m_chmFile )
|
|
chm_close (m_chmFile);
|
|
|
|
m_chmFile = tmpchm;
|
|
m_openedFile = filename;
|
|
|
|
kdDebug() << "A CHM file " << filename << " has beed opened successfully" << endl;
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Shamelessly stolen from a KDE KIO tutorial
|
|
*/
|
|
static void app_entry(UDSEntry& e, unsigned int uds, const TQString& str)
|
|
{
|
|
UDSAtom a;
|
|
a.m_uds = uds;
|
|
a.m_str = str;
|
|
e.append(a);
|
|
}
|
|
|
|
// appends an int with the UDS-ID uds
|
|
static void app_entry(UDSEntry& e, unsigned int uds, long l)
|
|
{
|
|
UDSAtom a;
|
|
a.m_uds = uds;
|
|
a.m_long = l;
|
|
e.append(a);
|
|
}
|
|
|
|
// internal function
|
|
// fills a directory item with its name and size
|
|
static void app_dir(UDSEntry& e, const TQString & name)
|
|
{
|
|
e.clear();
|
|
app_entry(e, KIO::UDS_NAME, name);
|
|
app_entry(e, KIO::UDS_FILE_TYPE, S_IFDIR);
|
|
app_entry(e, KIO::UDS_SIZE, 1);
|
|
}
|
|
|
|
// internal function
|
|
// fills a file item with its name and size
|
|
static void app_file(UDSEntry& e, const TQString & name, size_t size)
|
|
{
|
|
e.clear();
|
|
app_entry(e, KIO::UDS_NAME, name);
|
|
app_entry(e, KIO::UDS_FILE_TYPE, S_IFREG);
|
|
app_entry(e, KIO::UDS_SIZE, size);
|
|
}
|
|
|
|
void ProtocolMSITS::stat (const KURL & url)
|
|
{
|
|
TQString fileName;
|
|
chmUnitInfo ui;
|
|
|
|
kdDebug() << "kio_msits::stat (const KURL& url) " << url.path() << endl;
|
|
|
|
if ( !parseLoadAndLookup ( url, fileName ) )
|
|
return; // error() has been called by parseLoadAndLookup
|
|
|
|
if ( !ResolveObject ( fileName, &ui ) )
|
|
{
|
|
error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL() );
|
|
return;
|
|
}
|
|
|
|
kdDebug() << "kio_msits::stat: adding an entry for " << fileName << endl;
|
|
UDSEntry entry;
|
|
|
|
if ( isDirectory ( fileName ) )
|
|
app_dir(entry, fileName);
|
|
else
|
|
app_file(entry, fileName, ui.length);
|
|
|
|
statEntry (entry);
|
|
|
|
finished();
|
|
}
|
|
|
|
|
|
// A local CHMLIB enumerator
|
|
static int chmlib_enumerator (struct chmFile *, struct chmUnitInfo *ui, void *context)
|
|
{
|
|
((TQValueVector<TQString> *) context)->push_back (TQString::fromLocal8Bit (ui->path));
|
|
return CHM_ENUMERATOR_CONTINUE;
|
|
}
|
|
|
|
|
|
void ProtocolMSITS::listDir (const KURL & url)
|
|
{
|
|
TQString filepath;
|
|
|
|
kdDebug() << "kio_msits::listDir (const KURL& url) " << url.path() << endl;
|
|
|
|
if ( !parseLoadAndLookup ( url, filepath ) )
|
|
return; // error() has been called by parseLoadAndLookup
|
|
|
|
filepath += "/";
|
|
|
|
if ( !isDirectory (filepath) )
|
|
{
|
|
error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path());
|
|
return;
|
|
}
|
|
|
|
kdDebug() << "kio_msits::listDir: enumerating directory " << filepath << endl;
|
|
|
|
TQValueVector<TQString> listing;
|
|
|
|
if ( chm_enumerate_dir ( m_chmFile,
|
|
filepath.local8Bit(),
|
|
CHM_ENUMERATE_NORMAL | CHM_ENUMERATE_FILES | CHM_ENUMERATE_DIRS,
|
|
chmlib_enumerator,
|
|
&listing ) != 1 )
|
|
{
|
|
error(KIO::ERR_CANNOT_ENTER_DIRECTORY, url.path());
|
|
return;
|
|
}
|
|
|
|
UDSEntry entry;
|
|
unsigned int striplength = filepath.length();
|
|
|
|
for ( unsigned int i = 0; i < listing.size(); i++ )
|
|
{
|
|
// Strip the direcroty name
|
|
TQString ename = listing[i].mid (striplength);
|
|
|
|
if ( isDirectory ( ename ) )
|
|
app_dir(entry, ename);
|
|
else
|
|
app_file(entry, ename, 0);
|
|
|
|
listEntry(entry, false);
|
|
}
|
|
|
|
listEntry(entry, true);
|
|
finished();
|
|
}
|