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
9#include <QtGlobal>
10#ifndef _WIN32
11#include <QCoreApplication>
12#else
13#include <QApplication>
14#endif
15
16#include <QDir>
17#include <QFile>
18#include <QFileInfo>
19#include <QMap>
20#ifdef Q_OS_DARWIN
21#include <QProcessEnvironment>
22#endif
23
24#include <unistd.h>
25
26// MythTV
27#include "libmyth/mythcontext.h"
28#include "libmythbase/compat.h"
33#include "libmythbase/mythdb.h"
38#include "libmythbase/mythversion.h"
42#include "libmythtv/dbcheck.h"
43#include "libmythtv/jobqueue.h"
47#include "libmythtv/tv_rec.h"
48
49// MythBackend
50#include "autoexpire.h"
51#include "backendcontext.h"
52#include "mainserver.h"
53#include "mediaserver.h"
56#include "scheduler.h"
57
58#include "servicesv2/v2myth.h"
59
60#define LOC QString("MythBackend: ")
61#define LOC_WARN QString("MythBackend, Warning: ")
62#define LOC_ERR QString("MythBackend, Error: ")
63
64#ifdef Q_OS_MACOS
65// 10.6 uses some file handles for its new Grand Central Dispatch thingy
66static constexpr long UNUSED_FILENO { 6 };
67#else
68static constexpr long UNUSED_FILENO { 3 };
69#endif
70
71int main(int argc, char **argv)
72{
74 if (!cmdline.Parse(argc, argv))
75 {
78 }
79
80 if (cmdline.toBool("showhelp"))
81 {
83 return GENERIC_EXIT_OK;
84 }
85
86 if (cmdline.toBool("showversion"))
87 {
89 return GENERIC_EXIT_OK;
90 }
91
92#ifndef _WIN32
93#if HAVE_CLOSE_RANGE
94 close_range(UNUSED_FILENO, sysconf(_SC_OPEN_MAX) - 1, 0);
95#else
96 for (long i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
97 close(i);
98#endif
99 QCoreApplication a(argc, argv);
100#else
101 // MINGW application needs a window to receive messages
102 // such as socket notifications :[
103 QApplication a(argc, argv);
104#endif
105 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHBACKEND);
106
107#ifdef Q_OS_DARWIN
108 QString path = QCoreApplication::applicationDirPath();
109 setenv("PYTHONPATH",
110 QString("%1/../Resources/lib/%2:/../Resources/lib/%2/site-packages:/../Resources/lib/%2/lib-dynload:%3")
111 .arg(path)
112 .arg(QFileInfo(PYTHON_EXE).fileName())
113 .arg(QProcessEnvironment::systemEnvironment().value("PYTHONPATH"))
114 .toUtf8().constData(), 1);
115#endif
116
117 int retval = cmdline.Daemonize();
118 if (retval != GENERIC_EXIT_OK)
119 return retval;
120
121 bool daemonize = cmdline.toBool("daemon");
122 QString mask("general");
123 retval = cmdline.ConfigureLogging(mask, daemonize);
124 if (retval != GENERIC_EXIT_OK)
125 return retval;
126
127 if (daemonize)
128 // Don't listen to console input if daemonized
129 close(0);
130
131#if CONFIG_SYSTEMD_NOTIFY
132 (void)sd_notify(0, "STATUS=Connecting to database.");
133#endif
134
135 /*
136 InitializeMythDirs() is called by MythContext(), but we need to call it
137 first so XmlConfiguration() can find the configuration file.
138 */
140 // If setup has not been done (ie. the config.xml does not exist),
141 // set the ignoreDB flag, which will cause only the web-app to
142 // start, so that setup can be done.
143 bool ignoreDB = !(XmlConfiguration().FileExists());
144 if (ignoreDB)
146
147 // Init Parameters:
148 // bool Init(bool gui = true,
149 // bool promptForBackend = false,
150 // bool disableAutoDiscovery = false,
151 // bool ignoreDB = false);
152 MythContext context {MYTH_BINARY_VERSION};
153 if (!context.Init(false,false,false,ignoreDB))
154 {
155 LOG(VB_GENERAL, LOG_CRIT, "Failed to init MythContext.");
157 }
158 context.setCleanup(cleanup);
159
160 MythTranslation::load("mythfrontend");
161
162 setHttpProxy();
163
165
166 if (cmdline.toBool("setverbose") || cmdline.toBool("printsched") ||
167 cmdline.toBool("testsched") ||
168 cmdline.toBool("printexpire") || cmdline.toBool("setloglevel"))
169 {
171 return handle_command(cmdline);
172 }
173
175 retval = run_backend(cmdline);
176 // Retcode 258 is a special value to signal to mythbackend to restart
177 // This is used by the V2Myth/Shutdown?Restart=true API call
178 // Retcode 259 is a special value to signal to mythbackend to restart
179 // in webonly mode
180 if (retval == 258 || retval == 259)
181 {
182 char ** newargv = new char * [argc + 2];
183 std::string webonly = "--webonly";
184 newargv[0] = argv[0];
185 int newargc = 1;
186 for (int ix = 1 ; ix < argc ; ++ix)
187 {
188 if (webonly != argv[ix])
189 newargv[newargc++] = argv[ix];
190 }
191 if (retval == 259)
192 newargv[newargc++] = webonly.data();
193 newargv[newargc] = nullptr;
194 LOG(VB_GENERAL, LOG_INFO,
195 QString("Restarting mythbackend"));
196 usleep(50000);
197 int rc = execvp(newargv[0], newargv);
198 LOG(VB_GENERAL, LOG_ERR,
199 QString("execvp failed prog %1 rc=%2 errno=%3").arg(argv[0]).arg(rc).arg(errno));
200 delete[] newargv;
201 }
202 return retval;
203}
204
205/* 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:39
#define setenv(x, y, z)
Definition: compat.h:85
@ 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:71
static constexpr long UNUSED_FILENO
Definition: mythbackend.cpp:66
int handle_command(const MythBackendCommandLineParser &cmdline)
int run_backend(MythBackendCommandLineParser &cmdline)
MythCommFlagCommandLineParser cmdline
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void InitializeMythDirs(void)
Definition: mythdirs.cpp:32
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
void setHttpProxy(void)
Get network proxy settings from OS, and use for [Q]Http[Comms].
static QString cleanup(const QString &str)