MythTV  master
mythtv/programs/mythmediaserver/main.cpp
Go to the documentation of this file.
1 #include <csignal>
2 #include <cstdio>
3 #include <cstdlib>
4 #include <fcntl.h>
5 #include <fstream>
6 #include <iostream>
7 #include <string>
8 #include <unistd.h>
9 
10 #include <QCoreApplication>
11 #include <QString>
12 #include <QDir>
13 
14 #include "mythconfig.h"
15 #include "mythsocketmanager.h"
16 #include "mythcontext.h"
17 #include "exitcodes.h"
18 #include "dbcheck.h"
19 #include "mythdbcon.h"
20 #include "loggingserver.h"
21 #include "mythlogging.h"
22 #include "mythversion.h"
23 #include "mythsystemevent.h"
24 #include "commandlineparser.h"
25 #include "signalhandling.h"
26 #include "cleanupguard.h"
27 
28 #include "controlrequesthandler.h"
32 #if CONFIG_SYSTEMD_NOTIFY
33 #include <systemd/sd-daemon.h>
34 #define ms_sd_notify(x) \
35  (void)sd_notify(0, x);
36 #else
37 #define ms_sd_notify(x)
38 #endif
39 
40 #define LOC QString("MythMediaServer: ")
41 #define LOC_WARN QString("MythMediaServer, Warning: ")
42 #define LOC_ERR QString("MythMediaServer, Error: ")
43 
44 using namespace std;
45 
46 QString pidfile;
47 QString logfile = "";
48 
49 static void cleanup(void)
50 {
51  delete gContext;
52  gContext = nullptr;
53 
54  if (pidfile.size())
55  {
56  unlink(pidfile.toLatin1().constData());
57  pidfile.clear();
58  }
59 
61 }
62 
63 int main(int argc, char *argv[])
64 {
66  if (!cmdline.Parse(argc, argv))
67  {
70  }
71 
72  if (cmdline.toBool("showhelp"))
73  {
75  return GENERIC_EXIT_OK;
76  }
77 
78  if (cmdline.toBool("showversion"))
79  {
81  return GENERIC_EXIT_OK;
82  }
83 
84  QCoreApplication a(argc, argv);
85  QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHMEDIASERVER);
86 
87  int retval = cmdline.Daemonize();
88  if (retval != GENERIC_EXIT_OK)
89  return retval;
90 
91  bool daemonize = cmdline.toBool("daemon");
92  QString mask("general");
93  if ((retval = cmdline.ConfigureLogging(mask, daemonize)) != GENERIC_EXIT_OK)
94  return retval;
95 
96  CleanupGuard callCleanup(cleanup);
97 
98 #ifndef _WIN32
99  QList<int> signallist;
100  signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
101  << SIGILL;
102 #if ! CONFIG_DARWIN
103  signallist << SIGRTMIN;
104 #endif
105  SignalHandler::Init(signallist);
106  SignalHandler::SetHandler(SIGHUP, logSigHup);
107 #endif
108 
109  ms_sd_notify("STATUS=Connecting to database.");
111  if (!gContext->Init(false))
112  {
113  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to init MythContext, exiting.");
115  }
116 
117  if (!UpgradeTVDatabaseSchema(false, false, true))
118  {
119  LOG(VB_GENERAL, LOG_ERR, "Exiting due to schema mismatch.");
121  }
122 
124 
125  gCoreContext->SetAsBackend(true); // blocks the event connection
126  ms_sd_notify("STATUS=Connecting to master server.");
128  {
129  LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect to master server");
131  }
132 
133  int port = gCoreContext->GetBackendServerPort();
134  if (gCoreContext->GetBackendServerIP().isEmpty())
135  {
136  cerr << "No setting found for this machine's BackendServerIP.\n"
137  << "Please run setup on this machine and modify the first page\n"
138  << "of the general settings.\n";
140  }
141 
142  ms_sd_notify("STATUS=Creating socket manager");
143  auto *sockmanager = new MythSocketManager();
144  if (!sockmanager->Listen(port))
145  {
146  LOG(VB_GENERAL, LOG_ERR,
147  "Mediaserver exiting, failed to bind to listen port.");
148  delete sockmanager;
150  }
151 
152  sockmanager->RegisterHandler(new BaseRequestHandler());
153  sockmanager->RegisterHandler(new FileServerHandler());
154  sockmanager->RegisterHandler(new MessageHandler());
155 
156  auto *controlRequestHandler = new ControlRequestHandler();
157  sockmanager->RegisterHandler(controlRequestHandler);
158  controlRequestHandler->ConnectToMaster();
159 
161 
162  // Provide systemd ready notification (for type=notify units)
163  ms_sd_notify("STATUS=");
164  ms_sd_notify("READY=1");
165 
166  int exitCode = QCoreApplication::exec();
167 
168  ms_sd_notify("STOPPING=1\nSTATUS=Exiting");
169  delete sysEventHandler;
170 
171  return exitCode ? exitCode : GENERIC_EXIT_OK;
172 }
173 
174 /* vim: set expandtab tabstop=4 shiftwidth=4: */
int Daemonize(void)
Fork application into background, and detatch from terminal.
Startup context for MythTV.
Definition: mythcontext.h:42
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
#define GENERIC_EXIT_CONNECT_ERROR
Can't connect to master backend.
Definition: exitcodes.h:20
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
static void cleanup(void)
static void PrintVersion(void)
Print application version information.
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
void PrintHelp(void) const
Print command line option help.
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
MythSystemEventHandler * sysEventHandler
static void Init(QList< int > &signallist, QObject *parent=nullptr)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:62
int GetBackendServerPort(void)
Returns the locally defined backend control port.
void ApplySettingsOverride(void)
Apply all overrides to the global context.
void SetAsBackend(bool backend)
int main(int argc, char *argv[])
#define MYTH_APPNAME_MYTHMEDIASERVER
#define GENERIC_EXIT_SOCKET_ERROR
Socket error.
Definition: exitcodes.h:18
static void Done(void)
static void SetHandler(int signum, SigHandlerFunc handler)
MythCommFlagCommandLineParser cmdline
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
#define SIGHUP
Definition: compat.h:213
#define GENERIC_EXIT_SETUP_ERROR
Incorrectly setup system.
Definition: exitcodes.h:21
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:16
bool Init(const bool gui=true, const bool promptForBackend=false, const bool disableAutoDiscovery=false, const bool ignoreDB=false)
Handles incoming MythSystemEvent messages.
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:13
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:15
int ConfigureLogging(const QString &mask="general", unsigned int progress=0)
Read in logging options and initialize the logging interface.
#define GENERIC_EXIT_DB_OUTOFDATE
Database needs upgrade.
Definition: exitcodes.h:16