00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
#include <qcstring.h>
00018
#include <qbitarray.h>
00019
#include <qfile.h>
00020
#include <qregexp.h>
00021
00022
#include <stdlib.h>
00023
#include <unistd.h>
00024
#include <sys/stat.h>
00025
00026
#include <kapp.h>
00027
#include <kdebug.h>
00028
#include <kinstance.h>
00029
#include <kglobal.h>
00030
#include <kurl.h>
00031
#include <kmimemagic.h>
00032
00033
#include "chm.h"
00034
00035
00036
using namespace KIO;
00037
00038
extern "C"
00039 {
00040 int kdemain(
int argc,
char **argv )
00041 {
00042
KInstance instance(
"kio_chm" );
00043
00044
kdDebug() <<
"*** Starting kio_chm " <<
endl;
00045
00046
if (argc != 4) {
00047
kdDebug() <<
"Usage: kio_chm protocol domain-socket1 domain-socket2" <<
endl;
00048 exit(-1);
00049 }
00050
00051
ChmProtocol slave(argv[2], argv[3]);
00052 slave.
dispatchLoop();
00053
00054
kdDebug() <<
"*** kio_chm Done" <<
endl;
00055
return 0;
00056 }
00057 }
00058
00059 ChmProtocol::ChmProtocol(
const QCString &pool_socket,
const QCString &app_socket)
00060 :
SlaveBase("kio_chm", pool_socket, app_socket)
00061 {
00062
kdDebug() <<
"ChmProtocol::ChmProtocol()" <<
endl;
00063 }
00064
00065
00066
00067 ChmProtocol::~ChmProtocol()
00068 {
00069
kdDebug() <<
"ChmProtocol::~ChmProtocol()" <<
endl;
00070 }
00071
00072
00073
00074 void ChmProtocol::get(
const KURL& url )
00075 {
00076
kdDebug() <<
"kio_chm::get(const KURL& url) " << url.
path() <<
endl;
00077
00078
QString path;
00079
if ( !
checkNewFile( url.
path(), path ) ) {
00080 error( KIO::ERR_DOES_NOT_EXIST, url.
prettyURL() );
00081
return;
00082 }
00083
00084
if (
m_dirMap.find(path) ==
m_dirMap.end()) {
00085 error( KIO::ERR_DOES_NOT_EXIST, url.
prettyURL() );
00086
return;
00087 }
00088
00089
QByteArray theData;
00090
00091
if (path ==
"/") {
00092
int offset =
m_dirMap[
"/@contents"].offset;
00093
int length = m_dirMap[
"/@contents"].length;
00094 theData.setRawData(&
m_contents[offset],
length);
00095
QString s(theData);
00096
QString output;
00097
00098
QRegExp object(
"<OBJECT type=\"text/sitemap\">(.*)</OBJECT>",
false);
00099 object.setMinimal(
true);
00100
00101
QRegExp nameParam(
"<param name=\"Name\" value=\"(.*)\">",
false);
00102 nameParam.setMinimal(
true);
00103
00104
QRegExp localParam(
"<param name=\"Local\" value=\"(.*)\">",
false);
00105 localParam.setMinimal(
true);
00106
00107
QRegExp mergeParam(
"<param name=\"Merge\" value=\"(.*)\">",
false);
00108 localParam.setMinimal(
true);
00109
00110
int old = 0, pos = 0;
00111
while ((pos = s.find(object, pos)) != -1) {
00112 output += s.mid(old, pos - old);
00113 pos += object.matchedLength();
00114 old = pos;
00115
QString obj = object.cap(1);
00116
QString name, local;
00117
if (obj.find(nameParam) != -1) {
00118 name = nameParam.cap(1);
00119
if (obj.find(localParam) != -1) {
00120 local = localParam.cap(1);
00121 output +=
"<a href=\"" + local +
"\">" + name +
"</a>";
00122 }
else {
00123 output += name;
00124 }
00125 }
00126
if (obj.find(mergeParam) != -1) {
00127
QString link = mergeParam.cap(1);
00128
QString href =
link.left(
link.find(
"::"));
00129
QString path =
m_chmFile.left(
m_chmFile.findRev(
"/") + 1);
00130 output +=
" (<a href=\"" + path + href +
"\">link</a>)";
00131 }
00132 }
00133 output += s.mid(old);
00134 theData.resetRawData(&
m_contents[offset],
length);
00135
00136
00137
00138
data(output.local8Bit());
00139 processedSize(output.length());
00140 }
else {
00141
int offset =
m_dirMap[path].offset;
00142
int length = m_dirMap[path].length;
00143 totalSize(
length);
00144 theData.setRawData(&
m_contents[offset],
length);
00145
00146
KMimeMagicResult * result =
KMimeMagic::self()->
findBufferFileType( theData, path );
00147
kdDebug() <<
"Emitting mimetype " << result->
mimeType() <<
endl;
00148 mimeType( result->
mimeType() );
00149
data(theData);
00150 theData.resetRawData(&
m_contents[offset],
length);
00151 processedSize(
length);
00152 }
00153
00154
finished();
00155 }
00156
00157
00158 bool ChmProtocol::checkNewFile(
QString fullPath,
QString& path )
00159 {
00160
00161
00162 fullPath = fullPath.replace(
QRegExp(
"::"),
"");
00163
00164
00165
if ( !
m_chmFile.isEmpty() && fullPath.startsWith(
m_chmFile) )
00166 {
00167 path = fullPath.mid(
m_chmFile.length()).lower();
00168
return true;
00169 }
00170
00171
kdDebug() <<
"Need to open a new file" <<
endl;
00172
00173
m_chmFile =
"";
00174
00175
00176
int pos = 0;
00177
QString chmFile;
00178 path =
"";
00179
00180
int len = fullPath.length();
00181
if (
len != 0 && fullPath[
len - 1 ] !=
'/' )
00182 fullPath +=
'/';
00183
00184
00185
while ( (pos=fullPath.find(
'/', pos+1 )) != -1 )
00186 {
00187
QString tryPath = fullPath.left( pos );
00188
00189
struct stat statbuf;
00190
if ( ::stat( QFile::encodeName(tryPath), &statbuf ) == 0 && !S_ISDIR(statbuf.st_mode) )
00191 {
00192 chmFile = tryPath;
00193 path = fullPath.mid( pos ).lower();
00194
kdDebug() <<
"fullPath=" << fullPath <<
" path=" << path <<
endl;
00195
len = path.length();
00196
if (
len > 2 )
00197 {
00198
if ( path[
len - 1 ] ==
'/' )
00199 path.truncate(
len - 1 );
00200 }
00201
else
00202 {
00203 path = QString::fromLatin1(
"/");
00204 }
00205
kdDebug() <<
"Found. chmFile=" << chmFile <<
" path=" << path <<
endl;
00206
break;
00207 }
00208 }
00209
if ( chmFile.isEmpty() )
00210 {
00211
kdDebug() <<
"ChmProtocol::checkNewFile: not found" <<
endl;
00212
return false;
00213 }
00214
00215
m_chmFile = chmFile;
00216
00217
00218
00219
return m_chm.
read(chmFile,
m_dirMap,
m_contents);
00220 }