summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY4
-rw-r--r--svdrp.c74
-rw-r--r--svdrp.h17
3 files changed, 92 insertions, 3 deletions
diff --git a/HISTORY b/HISTORY
index 58ab9cc5..e1b93540 100644
--- a/HISTORY
+++ b/HISTORY
@@ -997,7 +997,7 @@ Video Disk Recorder Revision History
- If a recording has no episode title, the trailing '~' is no longer shown in
the progress display.
-2002-02-23: Version 1.0.0pre1
+2002-02-24: Version 1.0.0pre1
- Added scanning for EPG data for another 4 days on channels that support this
(thanks to Oleg Assovski).
@@ -1023,3 +1023,5 @@ Video Disk Recorder Revision History
- At startup the data written into 'epg.data' is now read into the EPG data
structures. In order for this to work, the 'E' record has been extended to
(optionally) contain the 'table ID' (see FORMATS for details).
+- The new SVDRP command PUTE can be used to put EPG data into the EPG list.
+ See FORMATS for details about the required data format.
diff --git a/svdrp.c b/svdrp.c
index da816b01..6fe69474 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 1.31 2002/02/23 13:55:57 kls Exp $
+ * $Id: svdrp.c 1.32 2002/02/24 11:05:38 kls Exp $
*/
#include "svdrp.h"
@@ -118,6 +118,52 @@ int cSocket::Accept(void)
return -1;
}
+// --- cPUTEhandler ----------------------------------------------------------
+
+cPUTEhandler::cPUTEhandler(void)
+{
+ if ((f = tmpfile()) != NULL) {
+ status = 354;
+ message = "Enter EPG data, end with \".\" on a line by itself";
+ }
+ else {
+ LOG_ERROR;
+ status = 554;
+ message = "Error while opening temporary file";
+ }
+}
+
+cPUTEhandler::~cPUTEhandler()
+{
+ if (f)
+ fclose(f);
+}
+
+bool cPUTEhandler::Process(const char *s)
+{
+ if (f) {
+ if (strcmp(s, ".") != 0) {
+ fputs(s, f);
+ fputc('\n', f);
+ return true;
+ }
+ else {
+ rewind(f);
+ if (cSchedules::Read(f)) {
+ status = 250;
+ message = "EPG data processed";
+ }
+ else {
+ status = 451;
+ message = "Error while processing EPG data";
+ }
+ fclose(f);
+ f = NULL;
+ }
+ }
+ return false;
+}
+
// --- cSVDRP ----------------------------------------------------------------
#define MAXHELPTOPIC 10
@@ -192,6 +238,11 @@ const char *HelpPages[] = {
" zero, this means that the timer is currently recording and has started\n"
" at the given time. The first value in the resulting line is the number\n"
" of the timer.",
+ "PUTE\n"
+ " Put data into the EPG list. The data entered has to strictly follow the\n"
+ " format defined in VDR/FORMATS for the 'epg.data' file. A '.' on a line\n"
+ " by itself terminates the input and starts processing of the data (all\n"
+ " entered data is buffered until the terminating '.' is seen).",
"UPDT <settings>\n"
" Updates a timer. Settings must be in the same format as returned\n"
" by the LSTT command. If a timer with the same channel, day, start\n"
@@ -209,6 +260,7 @@ const char *HelpPages[] = {
220 VDR service ready
221 VDR service closing transmission channel
250 Requested VDR action okay, completed
+ 354 Start sending EPG data
451 Requested action aborted: local error in processing
500 Syntax error, command unrecognized
501 Syntax error in parameters or arguments
@@ -252,6 +304,7 @@ const char *GetHelpPage(const char *Cmd)
cSVDRP::cSVDRP(int Port)
:socket(Port)
{
+ PUTEhandler = NULL;
numChars = 0;
message = NULL;
lastActivity = 0;
@@ -273,6 +326,7 @@ void cSVDRP::Close(bool Timeout)
Reply(221, "%s closing connection%s", buffer, Timeout ? " (timeout)" : "");
isyslog(LOG_INFO, "closing SVDRP connection"); //TODO store IP#???
file.Close();
+ DELETENULL(PUTEhandler);
}
}
@@ -827,6 +881,15 @@ void cSVDRP::CmdNEXT(const char *Option)
Reply(550, "No active timers");
}
+void cSVDRP::CmdPUTE(const char *Option)
+{
+ delete PUTEhandler;
+ PUTEhandler = new cPUTEhandler;
+ Reply(PUTEhandler->Status(), PUTEhandler->Message());
+ if (PUTEhandler->Status() != 354)
+ DELETENULL(PUTEhandler);
+}
+
void cSVDRP::CmdUPDT(const char *Option)
{
if (*Option) {
@@ -859,6 +922,14 @@ void cSVDRP::CmdUPDT(const char *Option)
void cSVDRP::Execute(char *Cmd)
{
+ // handle PUTE data:
+ if (PUTEhandler) {
+ if (!PUTEhandler->Process(Cmd)) {
+ Reply(PUTEhandler->Status(), PUTEhandler->Message());
+ DELETENULL(PUTEhandler);
+ }
+ return;
+ }
// skip leading whitespace:
Cmd = skipspace(Cmd);
// find the end of the command word:
@@ -888,6 +959,7 @@ void cSVDRP::Execute(char *Cmd)
else if (CMD("NEWT")) CmdNEWT(s);
else if (CMD("NEXT")) CmdNEXT(s);
else if (CMD("UPDT")) CmdUPDT(s);
+ else if (CMD("PUTE")) CmdPUTE(s);
else if (CMD("QUIT")) Close();
else Reply(500, "Command unrecognized: \"%s\"", Cmd);
}
diff --git a/svdrp.h b/svdrp.h
index e68a92e4..42e5b691 100644
--- a/svdrp.h
+++ b/svdrp.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: svdrp.h 1.13 2001/11/04 11:20:46 kls Exp $
+ * $Id: svdrp.h 1.14 2002/02/24 10:48:21 kls Exp $
*/
#ifndef __SVDRP_H
@@ -26,11 +26,25 @@ public:
int Accept(void);
};
+class cPUTEhandler {
+private:
+ FILE *f;
+ int status;
+ const char *message;
+public:
+ cPUTEhandler(void);
+ ~cPUTEhandler();
+ bool Process(const char *s);
+ int Status(void) { return status; }
+ const char *Message(void) { return message; }
+ };
+
class cSVDRP {
private:
cSocket socket;
cFile file;
cRecordings Recordings;
+ cPUTEhandler *PUTEhandler;
uint numChars;
char cmdLine[MAXPARSEBUFFER];
char *message;
@@ -57,6 +71,7 @@ private:
void CmdNEWC(const char *Option);
void CmdNEWT(const char *Option);
void CmdNEXT(const char *Option);
+ void CmdPUTE(const char *Option);
void CmdUPDT(const char *Option);
void Execute(char *Cmd);
public: