1 /*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org>
4 SPDX-FileCopyrightText: 2002-2003 Waldo Bastian <bastian@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7 */
8
9 #include <kbuildsycoca_p.h>
10
11 #include "../../kservice_version.h"
12
13 #include <KAboutData>
14 #include <KLocalizedString>
15
16 #include <QCommandLineOption>
17 #include <QCommandLineParser>
18 #include <QCoreApplication>
19 #include <QDateTime>
20 #include <QDebug>
21 #include <QDir>
22 #include <QFile>
23 #include <QFileInfo>
24 #include <QStandardPaths>
25
26 #include <qplatformdefs.h> // for unlink
27 #ifdef Q_OS_WIN
28 #include <qt_windows.h>
29 #endif
30
crashHandler(int)31 static void crashHandler(int)
32 {
33 // If we crash while reading sycoca, we delete the database
34 // in an attempt to recover.
35 if (KBuildSycoca::sycocaPath()) {
36 unlink(KBuildSycoca::sycocaPath());
37 }
38 }
39
40 #if defined(Q_OS_WIN)
41 // glue function for calling the unix signal handler from the windows unhandled exception filter
42 // Inspired from KCrash, but heavily simplified
win32UnhandledExceptionFilter(_EXCEPTION_POINTERS *)43 LONG WINAPI win32UnhandledExceptionFilter(_EXCEPTION_POINTERS *)
44 {
45 crashHandler(0);
46 return EXCEPTION_EXECUTE_HANDLER; // allow windows to do the default action (terminate)
47 }
48 #endif
49
setCrashHandler()50 void setCrashHandler()
51 {
52 #if defined(Q_OS_WIN)
53 SetUnhandledExceptionFilter(win32UnhandledExceptionFilter);
54 #elif !defined(Q_OS_ANDROID)
55 sigset_t mask;
56 sigemptyset(&mask);
57
58 #ifdef SIGSEGV
59 signal(SIGSEGV, crashHandler);
60 sigaddset(&mask, SIGSEGV);
61 #endif
62 #ifdef SIGBUS
63 signal(SIGBUS, crashHandler);
64 sigaddset(&mask, SIGBUS);
65 #endif
66 #ifdef SIGFPE
67 signal(SIGFPE, crashHandler);
68 sigaddset(&mask, SIGFPE);
69 #endif
70 #ifdef SIGILL
71 signal(SIGILL, crashHandler);
72 sigaddset(&mask, SIGILL);
73 #endif
74 #ifdef SIGABRT
75 signal(SIGABRT, crashHandler);
76 sigaddset(&mask, SIGABRT);
77 #endif
78
79 sigprocmask(SIG_UNBLOCK, &mask, nullptr);
80 #endif
81 }
82
main(int argc,char ** argv)83 int main(int argc, char **argv)
84 {
85 QCoreApplication app(argc, argv);
86
87 KLocalizedString::setApplicationDomain("kservice5");
88
89 KAboutData about(QStringLiteral(KBUILDSYCOCA_EXENAME),
90 i18nc("application name", "KBuildSycoca"),
91 QStringLiteral(KSERVICE_VERSION_STRING),
92 i18nc("application description", "Rebuilds the system configuration cache."),
93 KAboutLicense::GPL,
94 i18nc("@info:credit", "Copyright 1999-2014 KDE Developers"));
95 about.addAuthor(i18nc("@info:credit", "David Faure"), i18nc("@info:credit", "Author"), QStringLiteral("faure@kde.org"));
96 about.addAuthor(i18nc("@info:credit", "Waldo Bastian"), i18nc("@info:credit", "Author"), QStringLiteral("bastian@kde.org"));
97 KAboutData::setApplicationData(about);
98
99 QCommandLineParser parser;
100 about.setupCommandLine(&parser);
101 parser.addOption(
102 QCommandLineOption(QStringLiteral("nosignal"),
103 i18nc("@info:shell command-line option", "Do not signal applications to update (deprecated, no longer having any effect)")));
104 parser.addOption(
105 QCommandLineOption(QStringLiteral("noincremental"), i18nc("@info:shell command-line option", "Disable incremental update, re-read everything")));
106 parser.addOption(QCommandLineOption(QStringLiteral("checkstamps"),
107 i18nc("@info:shell command-line option", "Check file timestamps (deprecated, no longer having any effect)")));
108 parser.addOption(QCommandLineOption(QStringLiteral("nocheckfiles"),
109 i18nc("@info:shell command-line option", "Disable checking files (deprecated, no longer having any effect)")));
110 parser.addOption(QCommandLineOption(QStringLiteral("menutest"), i18nc("@info:shell command-line option", "Perform menu generation test run only")));
111 parser.addOption(
112 QCommandLineOption(QStringLiteral("track"), i18nc("@info:shell command-line option", "Track menu id for debug purposes"), QStringLiteral("menu-id")));
113 parser.addOption(
114 QCommandLineOption(QStringLiteral("testmode"), i18nc("@info:shell command-line option", "Switch QStandardPaths to test mode, for unit tests only")));
115 parser.process(app);
116 about.processCommandLine(&parser);
117
118 const bool bMenuTest = parser.isSet(QStringLiteral("menutest"));
119
120 if (parser.isSet(QStringLiteral("testmode"))) {
121 QStandardPaths::setTestModeEnabled(true);
122 }
123
124 setCrashHandler();
125
126 fprintf(stderr, "%s running...\n", KBUILDSYCOCA_EXENAME);
127
128 const bool incremental = !parser.isSet(QStringLiteral("noincremental"));
129
130 KBuildSycoca sycoca; // Build data base
131 if (parser.isSet(QStringLiteral("track"))) {
132 sycoca.setTrackId(parser.value(QStringLiteral("track")));
133 }
134 sycoca.setMenuTest(bMenuTest);
135 if (!sycoca.recreate(incremental)) {
136 return -1;
137 }
138
139 return 0;
140 }
141