]> git.vomp.tv Git - jsonserver.git/blob - jsonserver.c
Make SSL cert filename part of config. Fix a shutdown segfault
[jsonserver.git] / jsonserver.c
1 /*
2  * jsonserver.c: A plugin for the Video Disk Recorder
3  *
4  * See the README file for copyright information and how to reach the author.
5  *
6  */
7
8 #include <vdr/plugin.h>
9 #include <stdio.h>
10
11 #include "mongoose.h"
12 #include "handler.h"
13 #include "log.h"
14 #include "config.h"
15
16 static const char *VERSION        = "0.0.1";
17 static const char *DESCRIPTION    = "JSON data server plugin for VDR";
18 static const char *MAINMENUENTRY  = "Jsonserver";
19
20 class cPluginJsonserver : public cPlugin {
21 private:
22   // Add any member variables or functions you may need here.
23   struct mg_context *mg;
24   Log* log;
25   Config* config;
26   char* cfgDocRoot;
27   char* cfgPort;
28   char* cfgSSLFilename;
29   bool mgRunning;
30 public:
31   cPluginJsonserver(void);
32   virtual ~cPluginJsonserver();
33   virtual const char *Version(void) { return VERSION; }
34   virtual const char *Description(void) { return DESCRIPTION; }
35   virtual const char *CommandLineHelp(void);
36   virtual bool ProcessArgs(int argc, char *argv[]);
37   virtual bool Initialize(void);
38   virtual bool Start(void);
39   virtual void Stop(void);
40   virtual void Housekeeping(void);
41   virtual void MainThreadHook(void);
42   virtual cString Active(void);
43   virtual time_t WakeupTime(void);
44   virtual const char *MainMenuEntry(void) { return MAINMENUENTRY; }
45   virtual cOsdObject *MainMenuAction(void);
46   virtual cMenuSetupPage *SetupMenu(void);
47   virtual bool SetupParse(const char *Name, const char *Value);
48   virtual bool Service(const char *Id, void *Data = NULL);
49   virtual const char **SVDRPHelpPages(void);
50   virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
51   };
52
53 cPluginJsonserver::cPluginJsonserver(void)
54 {
55   // Initialize any member variables here.
56   // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
57   // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
58
59   config = NULL;
60   log = NULL;
61   cfgDocRoot = NULL;
62   cfgPort = NULL;
63   cfgSSLFilename = NULL;
64   mgRunning = false;
65 }
66
67 cPluginJsonserver::~cPluginJsonserver()
68 {
69   // Clean up after yourself!
70   if (log) delete log;
71   log = NULL;
72
73   if (config) delete config;
74   config = NULL;
75 }
76
77 const char *cPluginJsonserver::CommandLineHelp(void)
78 {
79   // Return a string that describes all known command line options.
80   return NULL;
81 }
82
83 bool cPluginJsonserver::ProcessArgs(int argc, char *argv[])
84 {
85   // Implement command line argument processing here if applicable.
86   return true;
87 }
88
89 bool cPluginJsonserver::Initialize(void)
90 {
91   // Initialize any background activities the plugin shall perform.
92   return true;
93 }
94
95 bool cPluginJsonserver::Start(void)
96 {
97   // Start any background activities the plugin shall perform.
98   const char* configDir = cPlugin::ConfigDirectory("jsonserver");
99   if (!configDir)
100   {
101     dsyslog("jsonserver: Error: Could not get config dir from VDR");
102     return false;
103   }
104   char* configFile;
105   if (asprintf(&configFile, "%s/jsonserver.conf", configDir) == -1)
106   {
107     dsyslog("jsonserver: Error: asprintf");
108     return false;
109   }
110   
111   dsyslog("%s", configFile);
112   
113   log = new Log();
114   
115   config = new Config();
116   if (config->init(configFile))
117   {
118     dsyslog("jsonserver: Config file found");
119     free(configFile);
120   }
121   else
122   {
123     dsyslog("jsonserver: Error: Config file not found");
124     free(configFile);
125     delete config;
126     config = NULL;
127     return false;
128   }
129
130   char* cfgLogFilename = config->getValueString("General", "Log file");
131   if (cfgLogFilename)
132   {
133     log->init(Log::DEBUG, cfgLogFilename);
134     delete[] cfgLogFilename;
135     log->log("Main", Log::INFO, "Logging started");
136   }
137   else
138   {
139     dsyslog("jsonserver: Logging disabled");
140   }
141   
142   cfgDocRoot = config->getValueString("General", "JS App Dir");
143   if (!cfgDocRoot)
144   {
145     log->log("Main", Log::CRIT, "Config General/JS App Dir not found");
146     dsyslog("jsonserver: Error: Could not load JS App Dir from plugin config file");
147     delete log;
148     delete config;
149     log = NULL;
150     config = NULL;
151     return false;
152   }
153
154   cfgPort = config->getValueString("General", "Port number");
155   if (!cfgPort)
156   {
157     cfgPort = new char[5];
158     strcpy(cfgPort, "8005");
159   }
160
161   char* cfgSSLFilename = config->getValueString("General", "SSL PEM File");
162   if (!cfgSSLFilename)
163   {
164     log->log("Main", Log::ALERT, "Config General / SSL PEM File not found - can't run!");
165     dsyslog("jsonserver: ERROR: Config: SSL PEM not found");
166     delete log;
167     delete config;
168     log = NULL;
169     config = NULL;
170     return false;
171   }
172   
173   // Make Mongoose options
174   const char *options[] =
175   {
176     "document_root", cfgDocRoot,
177 //    "listening_ports", cfgPort,
178     "num_threads", "5",
179
180     "listening_ports", "8005s",
181     "ssl_certificate", cfgSSLFilename,
182
183 //    "auth_domain", "VDRWeb",
184
185     NULL
186   };
187
188   // Prepare callbacks structure. We have only one callback, the rest are NULL.
189   struct mg_callbacks callbacks;
190   memset(&callbacks, 0, sizeof(callbacks));
191   callbacks.begin_request = jsonserver_request_handler;
192   
193   mg = mg_start(&callbacks, NULL, options);
194   log->log("JSONServer", Log::INFO, "Mongoose started");
195   mgRunning = true;
196   return true;
197 }
198
199 void cPluginJsonserver::Stop(void)
200 {
201   // Stop any background activities the plugin is performing.
202   if (mgRunning) mg_stop(mg);
203   mgRunning = false;
204   if (cfgDocRoot) delete[] cfgDocRoot; cfgDocRoot = NULL;
205   if (cfgPort) delete[] cfgPort; cfgPort = NULL;
206   if (cfgSSLFilename) delete[] cfgSSLFilename; cfgSSLFilename = NULL;
207 }
208
209 void cPluginJsonserver::Housekeeping(void)
210 {
211   // Perform any cleanup or other regular tasks.
212 }
213
214 void cPluginJsonserver::MainThreadHook(void)
215 {
216   // Perform actions in the context of the main program thread.
217   // WARNING: Use with great care - see PLUGINS.html!
218 }
219
220 cString cPluginJsonserver::Active(void)
221 {
222   // Return a message string if shutdown should be postponed
223   return NULL;
224 }
225
226 time_t cPluginJsonserver::WakeupTime(void)
227 {
228   // Return custom wakeup time for shutdown script
229   return 0;
230 }
231
232 cOsdObject *cPluginJsonserver::MainMenuAction(void)
233 {
234   // Perform the action when selected from the main VDR menu.
235   return NULL;
236 }
237
238 cMenuSetupPage *cPluginJsonserver::SetupMenu(void)
239 {
240   // Return a setup menu in case the plugin supports one.
241   return NULL;
242 }
243
244 bool cPluginJsonserver::SetupParse(const char *Name, const char *Value)
245 {
246   // Parse your own setup parameters and store their values.
247   return false;
248 }
249
250 bool cPluginJsonserver::Service(const char *Id, void *Data)
251 {
252   // Handle custom service requests from other plugins
253   return false;
254 }
255
256 const char **cPluginJsonserver::SVDRPHelpPages(void)
257 {
258   // Return help text for SVDRP commands this plugin implements
259   return NULL;
260 }
261
262 cString cPluginJsonserver::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
263 {
264   // Process SVDRP commands this plugin implements
265   return NULL;
266 }
267
268 VDRPLUGINCREATOR(cPluginJsonserver); // Don't touch this!