mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
SVDRP now also works with clients that don't do line buffering
This commit is contained in:
parent
28130daef7
commit
ab626eecd3
3
HISTORY
3
HISTORY
@ -447,3 +447,6 @@ Video Disk Recorder Revision History
|
|||||||
- Fixed a segfault that sometimes happened when killing VDR.
|
- Fixed a segfault that sometimes happened when killing VDR.
|
||||||
- VDR now returns an exit status of '2' in case of an error at startup, instead
|
- VDR now returns an exit status of '2' in case of an error at startup, instead
|
||||||
of terminating with 'abort()' (which caused a core dump).
|
of terminating with 'abort()' (which caused a core dump).
|
||||||
|
- SVDRP now also works with clients that don't do line buffering (like the
|
||||||
|
Windows 'telnet').
|
||||||
|
|
||||||
|
64
svdrp.c
64
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 1.15 2001/03/02 22:59:37 kls Exp $
|
* $Id: svdrp.c 1.16 2001/04/01 14:09:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -113,7 +113,6 @@ int cSocket::Accept(void)
|
|||||||
|
|
||||||
// --- cSVDRP ----------------------------------------------------------------
|
// --- cSVDRP ----------------------------------------------------------------
|
||||||
|
|
||||||
#define MAXCMDBUFFER 10000
|
|
||||||
#define MAXHELPTOPIC 10
|
#define MAXHELPTOPIC 10
|
||||||
|
|
||||||
const char *HelpPages[] = {
|
const char *HelpPages[] = {
|
||||||
@ -234,6 +233,7 @@ const char *GetHelpPage(const char *Cmd)
|
|||||||
cSVDRP::cSVDRP(int Port)
|
cSVDRP::cSVDRP(int Port)
|
||||||
:socket(Port)
|
:socket(Port)
|
||||||
{
|
{
|
||||||
|
numChars = 0;
|
||||||
message = NULL;
|
message = NULL;
|
||||||
lastActivity = 0;
|
lastActivity = 0;
|
||||||
isyslog(LOG_INFO, "SVDRP listening on port %d", Port);
|
isyslog(LOG_INFO, "SVDRP listening on port %d", Port);
|
||||||
@ -842,7 +842,8 @@ void cSVDRP::Execute(char *Cmd)
|
|||||||
char *s = Cmd;
|
char *s = Cmd;
|
||||||
while (*s && !isspace(*s))
|
while (*s && !isspace(*s))
|
||||||
s++;
|
s++;
|
||||||
*s++ = 0;
|
if (*s)
|
||||||
|
*s++ = 0;
|
||||||
if (CMD("CHAN")) CmdCHAN(s);
|
if (CMD("CHAN")) CmdCHAN(s);
|
||||||
else if (CMD("DELC")) CmdDELC(s);
|
else if (CMD("DELC")) CmdDELC(s);
|
||||||
else if (CMD("DELT")) CmdDELT(s);
|
else if (CMD("DELT")) CmdDELT(s);
|
||||||
@ -864,8 +865,7 @@ void cSVDRP::Execute(char *Cmd)
|
|||||||
else if (CMD("OVLP")) CmdOVLP(s);
|
else if (CMD("OVLP")) CmdOVLP(s);
|
||||||
else if (CMD("OVLO")) CmdOVLO(s);
|
else if (CMD("OVLO")) CmdOVLO(s);
|
||||||
else if (CMD("UPDT")) CmdUPDT(s);
|
else if (CMD("UPDT")) CmdUPDT(s);
|
||||||
else if (CMD("QUIT")
|
else if (CMD("QUIT")) Close();
|
||||||
|| CMD("\x04")) Close();
|
|
||||||
else Reply(500, "Command unrecognized: \"%s\"", Cmd);
|
else Reply(500, "Command unrecognized: \"%s\"", Cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,29 +875,55 @@ void cSVDRP::Process(void)
|
|||||||
bool SendGreeting = NewConnection;
|
bool SendGreeting = NewConnection;
|
||||||
|
|
||||||
if (file.IsOpen() || file.Open(socket.Accept())) {
|
if (file.IsOpen() || file.Open(socket.Accept())) {
|
||||||
char buffer[MAXCMDBUFFER];
|
|
||||||
if (SendGreeting) {
|
if (SendGreeting) {
|
||||||
//TODO how can we get the *full* hostname?
|
//TODO how can we get the *full* hostname?
|
||||||
|
char buffer[MAXCMDBUFFER];
|
||||||
gethostname(buffer, sizeof(buffer));
|
gethostname(buffer, sizeof(buffer));
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, ctime(&now));
|
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, ctime(&now));
|
||||||
}
|
}
|
||||||
if (NewConnection)
|
if (NewConnection)
|
||||||
lastActivity = time(NULL);
|
lastActivity = time(NULL);
|
||||||
int rbytes = file.ReadString(buffer, sizeof(buffer) - 1);
|
if (file.Ready(false)) {
|
||||||
if (rbytes > 0) {
|
unsigned char c;
|
||||||
//XXX overflow check???
|
int r = read(file, &c, 1);
|
||||||
// strip trailing whitespace:
|
if (r > 0) {
|
||||||
while (rbytes > 0 && strchr(" \t\r\n", buffer[rbytes - 1]))
|
if (c == '\n' || c == 0x00) {
|
||||||
buffer[--rbytes] = 0;
|
// strip trailing whitespace:
|
||||||
// make sure the string is terminated:
|
while (numChars > 0 && strchr(" \t\r\n", cmdLine[numChars - 1]))
|
||||||
buffer[rbytes] = 0;
|
cmdLine[--numChars] = 0;
|
||||||
// showtime!
|
// make sure the string is terminated:
|
||||||
Execute(buffer);
|
cmdLine[numChars] = 0;
|
||||||
lastActivity = time(NULL);
|
// showtime!
|
||||||
|
Execute(cmdLine);
|
||||||
|
numChars = 0;
|
||||||
|
}
|
||||||
|
else if (c == 0x04 && numChars == 0) {
|
||||||
|
// end of file (only at beginning of line)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
else if (c == 0x08 || c == 0x7F) {
|
||||||
|
// backspace or delete (last character)
|
||||||
|
if (numChars > 0)
|
||||||
|
numChars--;
|
||||||
|
}
|
||||||
|
else if (c <= 0x03 || c == 0x0D || 0xF0 <= c) {
|
||||||
|
// ignore control characters
|
||||||
|
}
|
||||||
|
else if (numChars < sizeof(cmdLine) - 1) {
|
||||||
|
cmdLine[numChars++] = c;
|
||||||
|
cmdLine[numChars] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Reply(501, "Command line too long");
|
||||||
|
esyslog(LOG_ERR, "SVDRP: command line too long: '%s'", cmdLine);
|
||||||
|
numChars = 0;
|
||||||
|
}
|
||||||
|
lastActivity = time(NULL);
|
||||||
|
}
|
||||||
|
else if (r < 0)
|
||||||
|
Close();
|
||||||
}
|
}
|
||||||
else if (rbytes < 0)
|
|
||||||
Close();
|
|
||||||
else if (Setup.SVDRPTimeout && time(NULL) - lastActivity > Setup.SVDRPTimeout) {
|
else if (Setup.SVDRPTimeout && time(NULL) - lastActivity > Setup.SVDRPTimeout) {
|
||||||
isyslog(LOG_INFO, "timeout on SVDRP connection");
|
isyslog(LOG_INFO, "timeout on SVDRP connection");
|
||||||
Close(true);
|
Close(true);
|
||||||
|
6
svdrp.h
6
svdrp.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.h 1.7 2001/02/18 13:36:47 kls Exp $
|
* $Id: svdrp.h 1.8 2001/04/01 14:10:33 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SVDRP_H
|
#ifndef __SVDRP_H
|
||||||
@ -26,11 +26,15 @@ public:
|
|||||||
int Accept(void);
|
int Accept(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAXCMDBUFFER 1024
|
||||||
|
|
||||||
class cSVDRP {
|
class cSVDRP {
|
||||||
private:
|
private:
|
||||||
cSocket socket;
|
cSocket socket;
|
||||||
cFile file;
|
cFile file;
|
||||||
CRect ovlClipRects[MAXCLIPRECTS];
|
CRect ovlClipRects[MAXCLIPRECTS];
|
||||||
|
uint numChars;
|
||||||
|
char cmdLine[MAXCMDBUFFER];
|
||||||
char *message;
|
char *message;
|
||||||
time_t lastActivity;
|
time_t lastActivity;
|
||||||
void Close(bool Timeout = false);
|
void Close(bool Timeout = false);
|
||||||
|
23
tools.c
23
tools.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 1.31 2001/03/03 13:25:00 kls Exp $
|
* $Id: tools.c 1.32 2001/04/01 14:13:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -369,27 +369,6 @@ void cFile::Close(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int cFile::ReadString(char *Buffer, int Size)
|
|
||||||
{
|
|
||||||
int rbytes = 0;
|
|
||||||
bool wait = true;
|
|
||||||
|
|
||||||
while (Ready(wait)) {
|
|
||||||
int n = read(f, Buffer + rbytes, 1);
|
|
||||||
if (n == 0)
|
|
||||||
break; // EOF
|
|
||||||
if (n < 0) {
|
|
||||||
LOG_ERROR;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
rbytes += n;
|
|
||||||
if (rbytes == Size || Buffer[rbytes - 1] == '\n')
|
|
||||||
break;
|
|
||||||
wait = false;
|
|
||||||
}
|
|
||||||
return rbytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cFile::Ready(bool Wait)
|
bool cFile::Ready(bool Wait)
|
||||||
{
|
{
|
||||||
return f >= 0 && AnyFileReady(f, Wait ? 1000 : 0);
|
return f >= 0 && AnyFileReady(f, Wait ? 1000 : 0);
|
||||||
|
3
tools.h
3
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.24 2001/02/11 13:39:40 kls Exp $
|
* $Id: tools.h 1.25 2001/04/01 14:13:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -64,7 +64,6 @@ public:
|
|||||||
bool Open(int FileDes);
|
bool Open(int FileDes);
|
||||||
void Close(void);
|
void Close(void);
|
||||||
bool IsOpen(void) { return f >= 0; }
|
bool IsOpen(void) { return f >= 0; }
|
||||||
int ReadString(char *Buffer, int Size);
|
|
||||||
bool Ready(bool Wait = true);
|
bool Ready(bool Wait = true);
|
||||||
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
|
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
|
||||||
static bool FileReady(int FileDes, int TimeoutMs = 1000);
|
static bool FileReady(int FileDes, int TimeoutMs = 1000);
|
||||||
|
Loading…
Reference in New Issue
Block a user