network patch for xine 0.7.7
Commit Message
vdr-xine+network.diff on top of vdr-xine-0.7.7
xine-lib+network.diff on top of cvs xine-lib+vdr-xine-0.7.7/patch/xine-lib
diff -Nru xine-lib/src/vdr/input_vdr.c xine-lib+net/src/vdr/input_vdr.c
--- xine-lib/src/vdr/input_vdr.c 2005-09-14 23:04:14.000000000 +0200
+++ xine-lib+net/src/vdr/input_vdr.c 2005-08-16 12:03:03.000000000 +0200
@@ -34,6 +34,10 @@
#include <errno.h>
#include <pthread.h>
+#include <sys/socket.h>
+#include <resolv.h>
+#include <netdb.h>
+
#define LOG_MODULE "input_vdr"
#define LOG_VERBOSE
/*
@@ -51,8 +55,6 @@
#define VDR_MAX_NUM_WINDOWS 16
#define VDR_ABS_FIFO_DIR "/tmp/vdr-xine"
-
-
#define BUF_SIZE 1024
#define LOG_OSD(x)
@@ -1455,108 +1457,203 @@
return INPUT_OPTIONAL_UNSUPPORTED;
}
-static int vdr_plugin_open(input_plugin_t *this_gen)
+static int vdr_plugin_open_socket(vdr_input_plugin_t *this, struct hostent *host, unsigned short port)
+{
+ int fd;
+ struct sockaddr_in sain;
+ struct in_addr iaddr;
+
+ if ((fd = socket(PF_INET,SOCK_STREAM,0)) == -1) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _("vdr: failed to create socket for port %d (%s)\n"),
+ port,strerror(errno));
+ return -1;
+ }
+
+ iaddr.s_addr = * ((unsigned int *) host->h_addr_list[0]);
+
+ sain.sin_port = htons(port);
+ sain.sin_family = AF_INET;
+ sain.sin_addr = iaddr;
+
+ if (connect(fd,(struct sockaddr*) &sain, sizeof(sain)) < 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _("vdr: failed to connect to port %d (%s)\n"),port,
+ strerror(errno));
+ return -1;
+ }
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "vdr: socket opening successful, fd = %d\n",fd);
+ return fd;
+}
+
+static int vdr_plugin_open_sockets(vdr_input_plugin_t *this)
+{
+// struct hostent *host = gethostbyname(VDR_SERVER_ADDRESS);
+ struct hostent *host = gethostbyname(&this->mrl[12]);
+
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,"vdr: connecting to vdr.\n");
+ if (host == NULL) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _("vdr: failed to resolve hostname '%s' (%s)\n"),
+ &this->mrl[12],
+ strerror(errno));
+ return 0;
+ }
+
+ if ((this->fh = vdr_plugin_open_socket(this,host,18701)) == -1)
+ return 0;
+
+ fcntl(this->fh, F_SETFL, ~O_NONBLOCK & fcntl(this->fh, F_GETFL, 0));
+
+ if ((this->fh_control = vdr_plugin_open_socket(this,host,18702)) == -1)
+ return 0;
+
+ if ((this->fh_result = vdr_plugin_open_socket(this,host,18703)) == -1)
+ return 0;
+
+ if ((this->fh_event = vdr_plugin_open_socket(this,host,18704)) == -1)
+ return 0;
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "vdr: connecting to all sockets was successful.\n");
+ return 1;
+}
+
+static int vdr_plugin_open_vdr(input_plugin_t *this_gen)
{
vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen;
- lprintf("trying to open '%s'...\n", this->mrl);
+ char *filename;
- if (this->fh == -1)
- {
- char *filename;
- int err = 0;
+ filename = (char *)&this->mrl[ 4 ];
+ this->fh = open(filename, O_RDONLY | O_NONBLOCK);
- filename = (char *)&this->mrl[ 4 ];
- this->fh = open(filename, O_RDONLY | O_NONBLOCK);
+ lprintf("filename '%s'\n", filename);
- lprintf("filename '%s'\n", filename);
+ if (this->fh == -1)
+ {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _(LOG_MODULE ": failed to open '%s' (%s)\n"),
+ filename,
+ strerror(errno));
+
+ return 0;
+ }
- if (this->fh == -1)
+ {
+ struct pollfd poll_fh = { this->fh, POLLIN, 0 };
+
+ int r = poll(&poll_fh, 1, 300);
+ if (1 != r)
{
xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
_(LOG_MODULE ": failed to open '%s' (%s)\n"),
filename,
- strerror(errno));
-
- return 0;
- }
-
- {
- struct pollfd poll_fh = { this->fh, POLLIN, 0 };
-
- int r = poll(&poll_fh, 1, 300);
- if (1 != r)
- {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _(LOG_MODULE ": failed to open '%s' (%s)\n"),
- filename,
- _("timeout expired during setup phase"));
+ _("timeout expired during setup phase"));
- return 0;
- }
+ return 0;
}
+ }
- fcntl(this->fh, F_SETFL, ~O_NONBLOCK & fcntl(this->fh, F_GETFL, 0));
+ fcntl(this->fh, F_SETFL, ~O_NONBLOCK & fcntl(this->fh, F_GETFL, 0));
- {
- char *filename_control = 0;
- asprintf(&filename_control, "%s.control", filename);
-
- this->fh_control = open(filename_control, O_RDONLY);
-
- if (this->fh_control == -1) {
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _(LOG_MODULE ": failed to open '%s' (%s)\n"),
- filename_control,
- strerror(errno));
+ {
+ char *filename_control = 0;
+ asprintf(&filename_control, "%s.control", filename);
- free(filename_control);
- return 0;
- }
+ this->fh_control = open(filename_control, O_RDONLY);
- free(filename_control);
+ if (this->fh_control == -1) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _(LOG_MODULE ": failed to open '%s' (%s)\n"),
+ filename_control,
+ strerror(errno));
+ free(filename_control);
+ return 0;
}
+ free(filename_control);
+ }
- {
- char *filename_result = 0;
- asprintf(&filename_result, "%s.result", filename);
+ {
+ char *filename_result = 0;
+ asprintf(&filename_result, "%s.result", filename);
- this->fh_result = open(filename_result, O_WRONLY);
+ this->fh_result = open(filename_result, O_WRONLY);
- if (this->fh_result == -1) {
- perror("failed");
+ if (this->fh_result == -1) {
+ perror("failed");
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _(LOG_MODULE ": failed to open '%s' (%s)\n"),
- filename_result,
- strerror(errno));
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _(LOG_MODULE ": failed to open '%s' (%s)\n"),
+ filename_result,
+ strerror(errno));
- free(filename_result);
- return 0;
- }
-
free(filename_result);
+ return 0;
}
- {
- char *filename_event = 0;
- asprintf(&filename_event, "%s.event", filename);
+ free(filename_result);
+ }
- this->fh_event = open(filename_event, O_WRONLY);
+ {
+ char *filename_event = 0;
+ asprintf(&filename_event, "%s.event", filename);
- if (this->fh_event == -1) {
- perror("failed");
+ this->fh_event = open(filename_event, O_WRONLY);
- xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
- _(LOG_MODULE ": failed to open '%s' (%s)\n"),
- filename_event,
- strerror(errno));
-
- free(filename_event);
- return 0;
- }
+ if (this->fh_event == -1) {
+ perror("failed");
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ _(LOG_MODULE ": failed to open '%s' (%s)\n"),
+ filename_event,
+ strerror(errno));
+
free(filename_event);
+ return 0;
+ }
+
+ free(filename_event);
+ }
+
+ return 1;
+}
+
+static int vdr_plugin_open_vdr_socket(input_plugin_t *this_gen)
+{
+ vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen;
+
+ lprintf("input_vdr: connecting to vdr-xine-server...\n");
+
+ if (!vdr_plugin_open_sockets(this))
+ return 0;
+
+ return 1;
+}
+
+static int vdr_plugin_open(input_plugin_t *this_gen)
+{
+ vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen;
+
+ lprintf("trying to open '%s'...\n", this->mrl);
+
+ if (this->fh == -1)
+ {
+ int err = 0;
+
+ if (!strncasecmp(&this->mrl[0], "vdr:/", 5))
+ {
+ if (!vdr_plugin_open_vdr(this_gen))
+ return 0;
+ }
+ else
+ {
+ if (!strncasecmp(&this->mrl[0], "vdr-socket:/", 12))
+ {
+ if (!vdr_plugin_open_vdr_socket(this_gen))
+ return 0;
+ }
}
this->rpc_thread_shutdown = 0;
@@ -1571,7 +1668,6 @@
}
}
-
/*
* mrl accepted and opened successfully at this point
*
@@ -1703,14 +1799,21 @@
vdr_input_plugin_t *this;
char *mrl = strdup(data);
- if (!strncasecmp(mrl, "vdr:/", 5))
+ if (!strncasecmp(mrl, "vdr-socket:/", 12))
{
- lprintf("filename '%s'\n", (char *)&mrl[ 4 ]);
+ lprintf("host '%s'\n", (char *)&mrl[ 12 ]);
}
else
{
- free(mrl);
- return NULL;
+ if (!strncasecmp(mrl, "vdr:/", 5))
+ {
+ lprintf("filename '%s'\n", (char *)&mrl[ 4 ]);
+ }
+ else
+ {
+ free(mrl);
+ return NULL;
+ }
}
/*
note: vdr-xine+network.diff also contains a change to choose the ip to bind
to with -i
--
@@ -33,7 +33,7 @@
public:
PluginXine::cXineLib *m_xineLib;
- int m_instanceNo;
+ in_addr_t m_bindIp;
cPluginXine(void);
virtual ~cPluginXine();
@@ -56,7 +56,7 @@
, m_remote(0)
, m_remoteOn(false)
, m_xineLib(0)
- , m_instanceNo(-1)
+ , m_bindIp(0)
{
// Initialize any member variables here.
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
@@ -73,7 +73,7 @@
//Return a string that describes all known command line options.
//" - -- x \n"
return
- " -i N instance number to append to FIFO directory\n"
+ " -i ip ip address to bind to\n"
" -q turn off debug messages on console\n"
" -r turn on remote (pressing keys in xine controls VDR)\n"
" -s switch to curses skin, while xine is disconnected\n"
@@ -93,11 +93,9 @@
{
case 'i':
{
- const int no = ::atoi(::optarg);
- if (no < 0)
+ m_bindIp = inet_addr(::optarg);
+ if (m_bindIp == INADDR_NONE)
return false;
-
- m_instanceNo = no;
}
break;
@@ -203,9 +201,9 @@
namespace PluginXine
{
- int GetInstanceNo(cPlugin *const plugin)
+ int GetBindIp(cPlugin *const plugin)
{
- return ((cPluginXine *)plugin)->m_instanceNo;
+ return ((cPluginXine *)plugin)->m_bindIp;
}
cXineLib *&GetXineLib(cPlugin *const plugin)
@@ -1847,7 +1847,7 @@
#endif
- extern int GetInstanceNo(cPlugin *const plugin);
+ extern int GetBindIp(cPlugin *const plugin);
extern cXineLib *&GetXineLib(cPlugin *const plugin);
cXineLib::cXineLib(cPlugin *const plugin, const cXineSettings &settings, cMutex &osdMutex, cXineRemote *const remote)
@@ -1855,6 +1855,10 @@
, m_plugin(plugin)
, m_settings(settings)
, m_osdFlushRequired(false)
+ , fd_fifo0_serv(-1)
+ , fd_result_serv(-1)
+ , fd_control_serv(-1)
+ , fd_remote_serv(-1)
, fd_fifo0(-1)
, fd_result(-1)
, fd_control(-1)
@@ -1873,14 +1877,9 @@
{
m_fifoDir = FIFO_DIR;
- if (GetInstanceNo(plugin) >= 0)
- {
- char s[ 20 ];
- ::sprintf(s, "%d", GetInstanceNo(plugin));
-
- m_fifoDir += s;
- }
-
+ m_bindIp = GetBindIp(plugin);
+ m_fifoDir += itoa(m_bindIp);
+
m_fifoNameControl = m_fifoDir + "/stream.control";
m_fifoNameResult = m_fifoDir + "/stream.result";
m_fifoNameRemote = m_fifoDir + "/stream.event";
@@ -1962,9 +1961,37 @@
m_eventSink = eventSink;
}
+ int cXineLib::CreateServerSocket(unsigned short port)
+ {
+ int fd;
+ int onoff = 1;
+ struct sockaddr_in sain;
+
+ if ((fd = ::socket(PF_INET,SOCK_STREAM,0)) < 0) {
+ perror("socket failed.");
+ return -1;
+ }
+
+ sain.sin_addr.s_addr = m_bindIp;
+ sain.sin_port = htons(port);
+
+ ::setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&onoff, sizeof(int) );
+
+ if (::bind(fd,(struct sockaddr*)&sain, sizeof(sain)) != 0) {
+ perror("bind failed.");
+ return -1;
+ }
+
+ if (::listen(fd,1) != 0) {
+ printf("listen failed.");
+ return -1;
+ }
+ return fd;
+ }
+
bool cXineLib::Open()
{
- ::unlink(m_fifoNameExtControl.c_str());
+/* ::unlink(m_fifoNameExtControl.c_str());
::unlink(m_fifoNameExtResult.c_str());
::unlink(m_fifoNameControl.c_str());
::unlink(m_fifoNameResult.c_str());
@@ -2003,6 +2030,26 @@
#undef MkFifo
::umask(origUmask);
+*/
+/*
+{ .path = FIFO_STREAM, .mode = 0644, .port = 18701 },
+{ .path = FIFO_STREAM_CONTROL, .mode = 0644, .port = 18702 },
+{ .path = FIFO_STREAM_RESULT, .mode = 0666, .port = 18703 },
+{ .path = FIFO_STREAM_EVENT, .mode = 0666, .port = 18704 },
+
+*/
+ /* sockets - create the server sockets */
+ if ((fd_fifo0_serv = CreateServerSocket(18701)) == -1)
+ return false;
+
+ if ((fd_control_serv = CreateServerSocket(18702)) == -1)
+ return false;
+
+ if ((fd_result_serv = CreateServerSocket(18703)) == -1)
+ return false;
+
+ if ((fd_remote_serv = CreateServerSocket(18704)) == -1)
+ return false;
if (!Start())
return false;
@@ -2028,13 +2075,18 @@
disconnect();
}
- ::unlink(m_fifoNameExtControl.c_str());
+/* ::unlink(m_fifoNameExtControl.c_str());
::unlink(m_fifoNameExtResult.c_str());
::unlink(m_fifoNameControl.c_str());
::unlink(m_fifoNameResult.c_str());
::unlink(m_fifoNameRemote.c_str());
::unlink(m_fifoNameStream.c_str());
- ::rmdir(m_fifoDir.c_str());
+ ::rmdir(m_fifoDir.c_str()); */
+
+ ::close(fd_remote_serv);
+ ::close(fd_result_serv);
+ ::close(fd_control_serv);
+ ::close(fd_fifo0_serv);
}
void cXineLib::internalPaused(const bool paused)
@@ -2286,6 +2338,28 @@
// fprintf(stderr, "Action done\n");
}
+int cXineLib::SocketAcceptHelper(int fd)
+{
+ // use cPoller for checking server socket for incoming requests
+ cPoller poller(fd,0); /* POLLIN */
+ struct sockaddr sain;
+ socklen_t len = sizeof(sain);
+ int client;
+
+// ::fprintf(stderr,"vdr-xine: polling for connection on %d...\n",fd);
+ if (!poller.Poll(100))
+ return -1;
+
+// ::fprintf(stderr,"vdr-xine: incoming requests on %d\n",fd);
+ if ((client = ::accept(fd,(struct sockaddr *) &sain,&len)) == -1) {
+ ::fprintf(stderr,"vdr-xine: fifo0 failed to accept...\n");
+ return -1;
+ }
+// ::fprintf(stderr,"vdr-xine: successful request on %d (client: %d)\n",fd,client);
+ return client;
+}
+
+
bool cXineLib::checkXineVersion()
{
int32_t version = 0;
@@ -2306,7 +2380,8 @@
// if (-1 == fd_fifo0)
// {
- fd_fifo0 = ::open(m_fifoNameStream.c_str(), O_WRONLY | O_NONBLOCK);
+/*
+ fd_fifo0 = ::open(m_fifoNameStream.c_str(), O_WRONLY | O_NONBLOCK);
if (-1 == fd_fifo0)
return false;
@@ -2321,6 +2396,23 @@
::fcntl(fd_fifo0 , F_SETFL, ~O_NONBLOCK & ::fcntl(fd_fifo0 , F_GETFL, 0));
::fcntl(fd_remote, F_SETFL, ~O_NONBLOCK & ::fcntl(fd_remote, F_GETFL, 0));
+*/
+ /* sockets */
+
+ if (fd_fifo0_serv == -1)
+ return false;
+
+ if ((fd_fifo0 = SocketAcceptHelper(fd_fifo0_serv)) == -1)
+ return false;
+
+ if ((fd_control = SocketAcceptHelper(fd_control_serv)) == -1)
+ return false;
+
+ if ((fd_result = SocketAcceptHelper(fd_result_serv)) == -1)
+ return false;
+
+ if ((fd_remote = SocketAcceptHelper(fd_remote_serv)) == -1)
+ return false;
internalPaused(false);
@@ -88,6 +88,7 @@
string m_fifoNameStream;
string m_fifoNameExtControl;
string m_fifoNameExtResult;
+ in_addr_t m_bindIp;
private:
cPlugin *const m_plugin;
@@ -137,7 +138,13 @@
}
private:
+ /* sockets */
+ int CreateServerSocket(unsigned short port);
+ int SocketAcceptHelper(int fd);
+ int fd_fifo0_serv, fd_result_serv, fd_control_serv, fd_remote_serv;
int fd_fifo0, fd_result, fd_control, fd_remote;
+
+
cMutex m_ioMutex, m_dataMutex, m_disconnectMutex;
cMutex &m_osdMutex;