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