MythTV master
mythbackend.cpp
Go to the documentation of this file.
1#include "libmythbase/mythconfig.h"
2#if CONFIG_SYSTEMD_NOTIFY
3 #include <systemd/sd-daemon.h>
4#endif
5
6#include <csignal> // for signal
7#include <cstdlib>
8#include <thread>
9
10#include <QtGlobal>
11#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
12#include <QtSystemDetection>
13#endif
14#ifndef Q_OS_WINDOWS
15#include <QCoreApplication>
16#else
17#include <QApplication>
18#endif
19
20#include <QDir>
21#include <QFile>
22#include <QFileInfo>
23#include <QMap>
24#ifdef Q_OS_DARWIN
25#include <QProcessEnvironment>
26#endif
27
28#include <unistd.h>
29
30// MythTV
31#include "libmyth/mythcontext.h"
32#include "libmythbase/compat.h"
37#include "libmythbase/mythdb.h"
42#include "libmythbase/mythversion.h"
44#include "libmythtv/dbcheck.h"
45#include "libmythtv/jobqueue.h"
49#include "libmythtv/tv_rec.h"
50
51// MythBackend
52#include "autoexpire.h"
53#include "backendcontext.h"
54#include "mainserver.h"
55#include "mediaserver.h"
58#include "scheduler.h"
59
60#include "servicesv2/v2myth.h"
61
62#define LOC QString("MythBackend: ")
63#define LOC_WARN QString("MythBackend, Warning: ")
64#define LOC_ERR QString("MythBackend, Error: ")
65
66#ifdef Q_OS_MACOS
67// 10.6 uses some file handles for its new Grand Central Dispatch thingy
68static constexpr long UNUSED_FILENO { 6 };
69#else
70static constexpr long UNUSED_FILENO { 3 };
71#endif
72
73int main(int argc, char **argv)
74{
76 if (!cmdline.Parse(argc, argv))
77 {
80 }
81
82 if (cmdline.toBool("showhelp"))
83 {
85 return GENERIC_EXIT_OK;
86 }
87
88 if (cmdline.toBool("showversion"))
89 {
91 return GENERIC_EXIT_OK;
92 }
93
94#ifndef Q_OS_WINDOWS
95#if HAVE_CLOSE_RANGE
96 close_range(UNUSED_FILENO, sysconf(_SC_OPEN_MAX) - 1, 0);
97#else
98 for (long i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
99 close(i);
100#endif
101 QCoreApplication a(argc, argv);
102#else
103 // MINGW application needs a window to receive messages
104 // such as socket notifications :[
105 QApplication a(argc, argv);
106#endif
107 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHBACKEND);
108
109#ifdef Q_OS_DARWIN
110 QString path = QCoreApplication::applicationDirPath();
111 setenv("PYTHONPATH",
112 QString("%1/../Resources/lib/%2:/../Resources/lib/%2/site-packages:/../Resources/lib/%2/lib-dynload:%3")
113 .arg(path)
114 .arg(QFileInfo(PYTHON_EXE).fileName())
115 .arg(QProcessEnvironment::systemEnvironment().value("PYTHONPATH"))
116 .toUtf8().constData(), 1);
117#endif
118
119 int retval = cmdline.Daemonize();
120 if (retval != GENERIC_EXIT_OK)
121 return retval;
122
123 bool daemonize = cmdline.toBool("daemon");
124 QString mask("general");
125 retval = cmdline.ConfigureLogging(mask, daemonize);
126 if (retval != GENERIC_EXIT_OK)
127 return retval;
128
129 if (daemonize)
130 // Don't listen to console input if daemonized
131 close(0);
132
133#if CONFIG_SYSTEMD_NOTIFY
134 (void)sd_notify(0, "STATUS=Connecting to database.");
135#endif
136
137 /*
138 InitializeMythDirs() is called by MythContext(), but we need to call it
139 first so XmlConfiguration() can find the configuration file.
140 */
142 // If setup has not been done (ie. the config.xml does not exist),
143 // set the ignoreDB flag, which will cause only the web-app to
144 // start, so that setup can be done.
145 bool ignoreDB = !(XmlConfiguration().FileExists());
146 if (ignoreDB)
148
149 // Init Parameters:
150 // bool Init(bool gui = true,
151 // bool promptForBackend = false,
152 // bool disableAutoDiscovery = false,
153 // bool ignoreDB = false);
154 MythContext context {MYTH_BINARY_VERSION};
155 if (!context.Init(false,false,false,ignoreDB))
156 {
157 LOG(VB_GENERAL, LOG_CRIT, "Failed to init MythContext.");
159 }
160 context.setCleanup(cleanup);
161
162 MythTranslation::load("mythfrontend");
163
164 setHttpProxy();
165
167
168 if (cmdline.toBool("setverbose") || cmdline.toBool("printsched") ||
169 cmdline.toBool("testsched") ||
170 cmdline.toBool("printexpire") || cmdline.toBool("setloglevel"))
171 {
173 return handle_command(cmdline);
174 }
175
177 retval = run_backend(cmdline);
178 // Retcode 258 is a special value to signal to mythbackend to restart
179 // This is used by the V2Myth/Shutdown?Restart=true API call
180 // Retcode 259 is a special value to signal to mythbackend to restart
181 // in webonly mode
182 if (retval == 258 || retval == 259)
183 {
184 char ** newargv = new char * [argc + 2];
185 std::string webonly = "--webonly";
186 newargv[0] = argv[0];
187 int newargc = 1;
188 for (int ix = 1 ; ix < argc ; ++ix)
189 {
190 if (webonly != argv[ix])
191 newargv[newargc++] = argv[ix];
192 }
193 if (retval == 259)
194 newargv[newargc++] = webonly.data();
195 newargv[newargc] = nullptr;
196 LOG(VB_GENERAL, LOG_INFO,
197 QString("Restarting mythbackend"));
198 std::this_thread::sleep_for(50ms);
199 int rc = execvp(newargv[0], newargv);
200 LOG(VB_GENERAL, LOG_ERR,
201 QString("execvp failed prog %1 rc=%2 errno=%3").arg(argv[0]).arg(rc).arg(errno));
202 delete[] newargv;
203 }
204 return retval;
205}
206
207/* vim: set expandtab tabstop=4 shiftwidth=4: */
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
void ApplySettingsOverride(void)
Apply all overrides to the global context.
int Daemonize(void) const
Fork application into background, and detatch from terminal.
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
static void PrintVersion(void)
Print application version information.
void PrintHelp(void) const
Print command line option help.
Startup context for MythTV.
Definition: mythcontext.h:20
void SetAsBackend(bool backend)
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
static WebOnlyStartup s_WebOnlyStartup
Definition: v2myth.h:68
@ kWebOnlyDBSetup
Definition: v2myth.h:62
#define close
Definition: compat.h:28
#define setenv(x, y, z)
Definition: compat.h:62
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:16
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
static constexpr const char * MYTH_APPNAME_MYTHBACKEND
Definition: mythappname.h:4
int main(int argc, char **argv)
Definition: mythbackend.cpp:73
static constexpr long UNUSED_FILENO
Definition: mythbackend.cpp:68
int handle_command(const MythBackendCommandLineParser &cmdline)
int run_backend(MythBackendCommandLineParser &cmdline)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void InitializeMythDirs(void)
Definition: mythdirs.cpp:35
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
void setHttpProxy(void)
Get network proxy settings from OS, and use for [Q]Http[Comms].
MythCommFlagCommandLineParser cmdline
static QString cleanup(const QString &str)