1/*
2 * This file is part of the KDE libraries
3 * Copyright (c) 1999-2000 Waldo Bastian <bastian@kde.org>
4 * (c) 1999 Mario Weilguni <mweilguni@sime.com>
5 * (c) 2001 Lubos Lunak <l.lunak@kde.org>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License version 2 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#include <kdebug.h>
23#include <config.h>
24
25#include <stdlib.h>
26#include <stdio.h>
27#include <errno.h>
28#include <locale.h>
29
30#include <QtCore/QString>
31#include <QtCore/QLibrary>
32#include <QtCore/QFile>
33
34#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
35#define USE_KPROCESS_FOR_KIOSLAVES
36#endif
37
38#ifdef USE_KPROCESS_FOR_KIOSLAVES
39#include <QtCore/QDir>
40#include <QtCore/QProcess>
41#include <QtCore/QStringList>
42#ifdef Q_WS_WIN
43#include <windows.h>
44#include <process.h>
45#endif
46#include "kstandarddirs.h"
47#endif
48
49#ifndef Q_WS_WIN
50/* These are to link libkio even if 'smart' linker is used */
51#include <kio/authinfo.h>
52extern "C" KIO::AuthInfo* _kioslave_init_kio() { return new KIO::AuthInfo(); }
53#endif
54
55int main(int argc, char **argv)
56{
57 if (argc < 5)
58 {
59 fprintf(stderr, "Usage: kioslave <slave-lib> <protocol> <klauncher-socket> <app-socket>\n\nThis program is part of KDE.\n");
60 exit(1);
61 }
62#ifndef _WIN32_WCE
63 setlocale(LC_ALL, "");
64#endif
65 QString libpath = QFile::decodeName(argv[1]);
66
67 if (libpath.isEmpty())
68 {
69 fprintf(stderr, "library path is empty.\n");
70 exit(1);
71 }
72
73 QLibrary lib(libpath);
74#ifdef USE_KPROCESS_FOR_KIOSLAVES
75 qDebug("trying to load '%s'", qPrintable(libpath));
76#endif
77 if ( !lib.load() || !lib.isLoaded() )
78 {
79#ifdef USE_KPROCESS_FOR_KIOSLAVES
80 libpath = KStandardDirs::installPath("module") + QFileInfo(libpath).fileName();
81 lib.setFileName( libpath );
82 if(!lib.load() || !lib.isLoaded())
83 {
84 QByteArray kdedirs = qgetenv("KDEDIRS");
85 if (!kdedirs.size()) {
86 qDebug("not able to find '%s' because KDEDIRS environment variable is not set.\n"
87 "Set KDEDIRS to the KDE installation root dir and restart klauncher to fix this problem.",
88 qPrintable(libpath));
89 exit(1);
90 }
91 QString paths = QString::fromLocal8Bit(kdedirs);
92 QStringList pathlist = paths.split(';');
93 Q_FOREACH(const QString &path, pathlist) {
94 QString slave_path = path + QLatin1String("/lib/kde4/") + QFileInfo(libpath).fileName();
95 qDebug("trying to load '%s'",slave_path.toLatin1().data());
96 lib.setFileName(slave_path);
97 if (lib.load() && lib.isLoaded() )
98 break;
99 }
100 if (!lib.isLoaded())
101 {
102 qWarning("could not open %s: %s", libpath.data(), qPrintable (lib.errorString()) );
103 exit(1);
104 }
105 }
106#else
107 fprintf(stderr, "could not open %s: %s", qPrintable(libpath),
108 qPrintable (lib.errorString()) );
109 exit(1);
110#endif
111 }
112
113 void* sym = lib.resolve("kdemain");
114 if (!sym )
115 {
116 fprintf(stderr, "Could not find kdemain: %s\n", qPrintable(lib.errorString() ));
117 exit(1);
118 }
119
120#ifdef Q_WS_WIN
121 // enter debugger in case debugging is actived
122 QString slaveDebugWait( QString::fromLocal8Bit( qgetenv("KDE_SLAVE_DEBUG_WAIT") ) );
123 if (slaveDebugWait == QLatin1String("all") || slaveDebugWait == argv[2])
124 {
125# ifdef Q_CC_MSVC
126 // msvc debugger or windbg supports jit debugging, the latter requires setting up windbg jit with windbg -i
127 DebugBreak();
128# else
129 // gdb does not support win32 jit debug support, so implement it by ourself
130 WCHAR buf[1024];
131 GetModuleFileName(NULL,buf, 1024);
132 QStringList params;
133 params << QString::fromUtf16((const unsigned short*)buf);
134 params << QString::number(GetCurrentProcessId());
135 QProcess::startDetached("gdb",params);
136 Sleep(1000);
137# endif
138 }
139# if defined(Q_CC_MSVC) && !defined(_WIN32_WCE)
140 else {
141 QString slaveDebugPopup( QString::fromLocal8Bit( qgetenv("KDE_SLAVE_DEBUG_POPUP") ) );
142 if (slaveDebugPopup == QLatin1String("all") || slaveDebugPopup == argv[2]) {
143 // A workaround for OSes where DebugBreak() does not work in administrative mode (actually Vista with msvc 2k5)
144 // - display a native message box so developer can attach the debugger to the KIO slave process and click OK.
145 MessageBoxA(NULL,
146 QString("Please attach the debugger to process #%1 (%2)").arg(getpid()).arg(argv[0]).toLatin1(),
147 QString("\"%1\" KIO Slave Debugging").arg(argv[2]).toLatin1(), MB_OK|MB_ICONINFORMATION|MB_TASKMODAL);
148 }
149 }
150# endif
151#endif // Q_WS_WIN
152
153 int (*func)(int, char *[]) = (int (*)(int, char *[])) sym;
154
155 exit( func(argc-1, argv+1)); /* Launch! */
156}
157