From patchwork Mon Feb 20 17:36:27 2006 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: syrius.ml@no-log.org X-Patchwork-Id: 12212 Received: from [82.246.72.218] (helo=f.smtp.localhost) by www.linuxtv.org with esmtp (Exim 4.50) id 1FBExe-00014w-VO for vdr@linuxtv.org; Mon, 20 Feb 2006 18:36:35 +0100 Received: by f.smtp.localhost (Postfix, from userid 1000) id 8C4B64CA; Mon, 20 Feb 2006 18:36:27 +0100 (CET) From: syrius.ml@no-log.org To: vdr@linuxtv.org Message-ID: <87fymec553.87ek1yc553@87d5hic553.message.id> Date: Mon, 20 Feb 2006 18:36:27 +0100 User-Agent: Gnus/5.110004 (No Gnus v0.4) Emacs/21.4 (gnu/linux) MIME-Version: 1.0 Subject: [vdr] network patch for xine 0.7.7 X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: VDR Mailing List List-Id: VDR Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Feb 2006 17:36:35 -0000 Status: O X-Status: X-Keywords: X-UID: 8022 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 #include +#include +#include +#include + #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 diff -Nru xine-0.7.7.orig/xine.c xine-0.7.7/xine.c --- xine-0.7.7.orig/xine.c 2006-01-15 00:47:12.000000000 +0100 +++ xine-0.7.7/xine.c 2006-02-20 17:36:48.000000000 +0100 @@ -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) diff -Nru xine-0.7.7.orig/xineLib.c xine-0.7.7/xineLib.c --- xine-0.7.7.orig/xineLib.c 2006-02-12 22:36:48.000000000 +0100 +++ xine-0.7.7/xineLib.c 2006-02-20 18:06:02.000000000 +0100 @@ -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); diff -Nru xine-0.7.7.orig/xineLib.h xine-0.7.7/xineLib.h --- xine-0.7.7.orig/xineLib.h 2006-02-03 22:16:46.000000000 +0100 +++ xine-0.7.7/xineLib.h 2006-02-20 17:36:48.000000000 +0100 @@ -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;