00001
00002 #include <fcntl.h>
00003 #include <signal.h>
00004
00005 #include <iostream>
00006 #include <fstream>
00007 #include <string>
00008 #include <unistd.h>
00009 #include <cstdlib>
00010 #include <cstdio>
00011
00012 #include <QCoreApplication>
00013 #include <QString>
00014 #include <QDir>
00015
00016 #include "mythsocketmanager.h"
00017 #include "mythcontext.h"
00018 #include "exitcodes.h"
00019 #include "dbcheck.h"
00020 #include "mythdbcon.h"
00021 #include "mythlogging.h"
00022 #include "mythversion.h"
00023 #include "mythsystemevent.h"
00024 #include "commandlineparser.h"
00025
00026 #include "controlrequesthandler.h"
00027 #include "requesthandler/basehandler.h"
00028 #include "requesthandler/fileserverhandler.h"
00029 #include "requesthandler/messagehandler.h"
00030
00031 #define LOC QString("MythMediaServer: ")
00032 #define LOC_WARN QString("MythMediaServer, Warning: ")
00033 #define LOC_ERR QString("MythMediaServer, Error: ")
00034
00035 using namespace std;
00036
00037 QString pidfile;
00038 QString logfile = "";
00039
00040 static void cleanup(void)
00041 {
00042 delete gContext;
00043 gContext = NULL;
00044
00045 if (pidfile.size())
00046 {
00047 unlink(pidfile.toAscii().constData());
00048 pidfile.clear();
00049 }
00050 }
00051
00052 namespace
00053 {
00054 class CleanupGuard
00055 {
00056 public:
00057 typedef void (*CleanupFunc)();
00058
00059 public:
00060 CleanupGuard(CleanupFunc cleanFunction) :
00061 m_cleanFunction(cleanFunction) {}
00062
00063 ~CleanupGuard()
00064 {
00065 m_cleanFunction();
00066 }
00067
00068 private:
00069 CleanupFunc m_cleanFunction;
00070 };
00071 }
00072
00073 int main(int argc, char *argv[])
00074 {
00075 MythMediaServerCommandLineParser cmdline;
00076 if (!cmdline.Parse(argc, argv))
00077 {
00078 cmdline.PrintHelp();
00079 return GENERIC_EXIT_INVALID_CMDLINE;
00080 }
00081
00082 if (cmdline.toBool("showhelp"))
00083 {
00084 cmdline.PrintHelp();
00085 return GENERIC_EXIT_OK;
00086 }
00087
00088 if (cmdline.toBool("showversion"))
00089 {
00090 cmdline.PrintVersion();
00091 return GENERIC_EXIT_OK;
00092 }
00093
00094 QCoreApplication a(argc, argv);
00095 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHMEDIASERVER);
00096
00097 int retval = cmdline.Daemonize();
00098 if (retval != GENERIC_EXIT_OK)
00099 return retval;
00100
00101 bool daemonize = cmdline.toBool("daemon");
00102 QString mask("general");
00103 if ((retval = cmdline.ConfigureLogging(mask, daemonize)) != GENERIC_EXIT_OK)
00104 return retval;
00105
00106 CleanupGuard callCleanup(cleanup);
00107
00108 gContext = new MythContext(MYTH_BINARY_VERSION);
00109 if (!gContext->Init(false))
00110 {
00111 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to init MythContext, exiting.");
00112 return GENERIC_EXIT_NO_MYTHCONTEXT;
00113 }
00114
00115 if (!UpgradeTVDatabaseSchema(false))
00116 {
00117 LOG(VB_GENERAL, LOG_ERR, "Exiting due to schema mismatch.");
00118 return GENERIC_EXIT_DB_OUTOFDATE;
00119 }
00120
00121 cmdline.ApplySettingsOverride();
00122
00123 gCoreContext->SetBackend(true);
00124 if (!gCoreContext->ConnectToMasterServer())
00125 {
00126 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to connect to master server");
00127 return GENERIC_EXIT_CONNECT_ERROR;
00128 }
00129
00130 int port = gCoreContext->GetNumSetting("BackendServerPort", 6543);
00131 if (gCoreContext->GetSetting("BackendServerIP").isEmpty() &&
00132 gCoreContext->GetSetting("BackendServerIP6").isEmpty())
00133 {
00134 cerr << "No setting found for this machine's BackendServerIP.\n"
00135 << "Please run setup on this machine and modify the first page\n"
00136 << "of the general settings.\n";
00137 return GENERIC_EXIT_SETUP_ERROR;
00138 }
00139
00140 MythSocketManager *sockmanager = new MythSocketManager();
00141 if (!sockmanager->Listen(port))
00142 {
00143 LOG(VB_GENERAL, LOG_ERR,
00144 "Mediaserver exiting, failed to bind to listen port.");
00145 delete sockmanager;
00146 return GENERIC_EXIT_SOCKET_ERROR;
00147 }
00148
00149 sockmanager->RegisterHandler(new BaseRequestHandler());
00150 sockmanager->RegisterHandler(new FileServerHandler());
00151 sockmanager->RegisterHandler(new MessageHandler());
00152
00153 ControlRequestHandler *controlRequestHandler = new ControlRequestHandler();
00154 sockmanager->RegisterHandler(controlRequestHandler);
00155 controlRequestHandler->ConnectToMaster();
00156
00157 MythSystemEventHandler *sysEventHandler = new MythSystemEventHandler();
00158
00159 int exitCode = a.exec();
00160
00161 if (sysEventHandler)
00162 delete sysEventHandler;
00163
00164 return exitCode ? exitCode : GENERIC_EXIT_OK;
00165 }
00166
00167