mirror of
				https://github.com/rofafor/vdr-plugin-iptv.git
				synced 2023-10-10 11:37:03 +00:00 
			
		
		
		
	Added FreeBSD support (Thanks to Jürgen Lock).
This commit is contained in:
		
							
								
								
									
										4
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								HISTORY
									
									
									
									
									
								
							@@ -177,3 +177,7 @@ VDR Plugin 'iptv' Revision History
 | 
			
		||||
 | 
			
		||||
- Optimized reading from UDP sockets.
 | 
			
		||||
- Fixed ProvidesChannel method.
 | 
			
		||||
 | 
			
		||||
2012-07-10: Version 1.0.1
 | 
			
		||||
 | 
			
		||||
- Added FreeBSD support (Thanks to Jürgen Lock).
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Makefile
									
									
									
									
									
								
							@@ -5,9 +5,15 @@
 | 
			
		||||
# Debugging on/off 
 | 
			
		||||
#IPTV_DEBUG = 1
 | 
			
		||||
 | 
			
		||||
# Default shell for EXT protocol
 | 
			
		||||
#IPTV_EXTSHELL = /bin/bash
 | 
			
		||||
 | 
			
		||||
# Strip debug symbols?  Set eg. to /bin/true if not
 | 
			
		||||
STRIP = strip
 | 
			
		||||
 | 
			
		||||
# Install command
 | 
			
		||||
INSTALL = cp --remove-destination
 | 
			
		||||
 | 
			
		||||
# The official name of this plugin.
 | 
			
		||||
# This name will be used in the '-P...' option of VDR to load the plugin.
 | 
			
		||||
# By default the main source file also carries this name.
 | 
			
		||||
@@ -60,6 +66,10 @@ ifdef IPTV_DEBUG
 | 
			
		||||
DEFINES += -DDEBUG
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifdef IPTV_EXTSHELL
 | 
			
		||||
DEFINES += -DEXTSHELL='"$(IPTV_EXTSHELL)"'
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ($(strip $(GITTAG)),)
 | 
			
		||||
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
 | 
			
		||||
endif
 | 
			
		||||
@@ -123,7 +133,7 @@ libvdr-$(PLUGIN).so: $(OBJS)
 | 
			
		||||
ifndef IPTV_DEBUG
 | 
			
		||||
	@$(STRIP) $@
 | 
			
		||||
endif
 | 
			
		||||
	@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
 | 
			
		||||
	@$(INSTALL) $@ $(LIBDIR)/$@.$(APIVERSION)
 | 
			
		||||
 | 
			
		||||
dist: $(I18Npo) clean
 | 
			
		||||
	@-rm -rf $(TMPDIR)/$(ARCHIVE)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								common.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								common.h
									
									
									
									
									
								
							@@ -39,13 +39,14 @@
 | 
			
		||||
#define SECTION_FILTER_TABLE_SIZE       7
 | 
			
		||||
 | 
			
		||||
#define ERROR_IF_FUNC(exp, errstr, func, ret) \
 | 
			
		||||
  do {                                                            \
 | 
			
		||||
     if (exp) {                                                   \
 | 
			
		||||
        char tmp[64];                                             \
 | 
			
		||||
        error(errstr": %s", strerror_r(errno, tmp, sizeof(tmp))); \
 | 
			
		||||
        func;                                                     \
 | 
			
		||||
        ret;                                                      \
 | 
			
		||||
        }                                                         \
 | 
			
		||||
  do {                                        \
 | 
			
		||||
     if (exp) {                               \
 | 
			
		||||
        char tmp[64];                         \
 | 
			
		||||
        strerror_r(errno, tmp, sizeof(tmp));  \
 | 
			
		||||
        error(errstr": %s", tmp);             \
 | 
			
		||||
        func;                                 \
 | 
			
		||||
        ret;                                  \
 | 
			
		||||
        }                                     \
 | 
			
		||||
  } while (0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								iptv.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								iptv.c
									
									
									
									
									
								
							@@ -21,7 +21,7 @@
 | 
			
		||||
#define GITVERSION ""
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
       const char VERSION[]     = "1.0.0" GITVERSION;
 | 
			
		||||
       const char VERSION[]     = "1.0.1" GITVERSION;
 | 
			
		||||
static const char DESCRIPTION[] = trNOOP("Experience the IPTV");
 | 
			
		||||
 | 
			
		||||
class cPluginIptv : public cPlugin {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,10 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "protocolext.h"
 | 
			
		||||
 | 
			
		||||
#ifndef EXTSHELL
 | 
			
		||||
#define EXTSHELL "/bin/bash"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
cIptvProtocolExt::cIptvProtocolExt()
 | 
			
		||||
: pid(-1),
 | 
			
		||||
  scriptFile(""),
 | 
			
		||||
@@ -56,7 +60,9 @@ void cIptvProtocolExt::ExecuteScript(void)
 | 
			
		||||
     // Execute the external script
 | 
			
		||||
     cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, streamPort);
 | 
			
		||||
     debug("cIptvProtocolExt::ExecuteScript(child): %s\n", *cmd);
 | 
			
		||||
     if (execl("/bin/bash", "sh", "-c", *cmd, (char *)NULL) == -1) {
 | 
			
		||||
     // Create a new session for a process group
 | 
			
		||||
     ERROR_IF_RET(setsid() == -1, "setsid()", _exit(-1));
 | 
			
		||||
     if (execl(EXTSHELL, "sh", "-c", *cmd, (char *)NULL) == -1) {
 | 
			
		||||
        error("Script execution failed: %s", *cmd);
 | 
			
		||||
        _exit(-1);
 | 
			
		||||
        }
 | 
			
		||||
@@ -75,27 +81,36 @@ void cIptvProtocolExt::TerminateScript(void)
 | 
			
		||||
  if (pid > 0) {
 | 
			
		||||
     const unsigned int timeoutms = 100;
 | 
			
		||||
     unsigned int waitms = 0;
 | 
			
		||||
     siginfo_t waitStatus;
 | 
			
		||||
     bool waitOver = false;
 | 
			
		||||
     // signal and wait for termination
 | 
			
		||||
     int retval = kill(pid, SIGINT);
 | 
			
		||||
     // Signal and wait for termination
 | 
			
		||||
     int retval = killpg(pid, SIGINT);
 | 
			
		||||
     ERROR_IF_RET(retval < 0, "kill()", waitOver = true);
 | 
			
		||||
     while (!waitOver) {
 | 
			
		||||
       retval = 0;
 | 
			
		||||
       waitms += timeoutms;
 | 
			
		||||
       if ((waitms % 2000) == 0) {
 | 
			
		||||
          error("Script '%s' won't terminate - killing it!", *scriptFile);
 | 
			
		||||
          kill(pid, SIGKILL);
 | 
			
		||||
          killpg(pid, SIGKILL);
 | 
			
		||||
          }
 | 
			
		||||
       // Clear wait status to make sure child exit status is accessible
 | 
			
		||||
       // and wait for child termination
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
       int waitStatus = 0;
 | 
			
		||||
       retval = waitpid(pid, &waitStatus, WNOHANG);
 | 
			
		||||
#else  // __FreeBSD__
 | 
			
		||||
       siginfo_t waitStatus;
 | 
			
		||||
       memset(&waitStatus, '\0', sizeof(waitStatus));
 | 
			
		||||
       // Wait for child termination
 | 
			
		||||
       retval = waitid(P_PID, pid, &waitStatus, (WNOHANG | WEXITED));
 | 
			
		||||
#endif // __FreeBSD__
 | 
			
		||||
       ERROR_IF_RET(retval < 0, "waitid()", waitOver = true);
 | 
			
		||||
       // These are the acceptable conditions under which child exit is
 | 
			
		||||
       // regarded as successful
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
       if (retval > 0 && (WIFEXITED(waitStatus) || WIFSIGNALED(waitStatus))) {
 | 
			
		||||
#else  // __FreeBSD__
 | 
			
		||||
       if (!retval && waitStatus.si_pid && (waitStatus.si_pid == pid) &&
 | 
			
		||||
          ((waitStatus.si_code == CLD_EXITED) || (waitStatus.si_code == CLD_KILLED))) {
 | 
			
		||||
#endif // __FreeBSD__
 | 
			
		||||
          debug("Child (%d) exited as expected\n", pid);
 | 
			
		||||
          waitOver = true;
 | 
			
		||||
          }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,9 @@
 | 
			
		||||
#ifndef __IPTV_SECTIONFILTER_H
 | 
			
		||||
#define __IPTV_SECTIONFILTER_H
 | 
			
		||||
 | 
			
		||||
#ifdef __FreeBSD__
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#endif // __FreeBSD__
 | 
			
		||||
#include <vdr/device.h>
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								socket.c
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								socket.c
									
									
									
									
									
								
							@@ -57,9 +57,11 @@ bool cIptvSocket::OpenSocket(const int Port, const bool isUdp)
 | 
			
		||||
     // Allow multiple sockets to use the same PORT number
 | 
			
		||||
     ERROR_IF_FUNC(setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0, "setsockopt(SO_REUSEADDR)",
 | 
			
		||||
                   CloseSocket(), return false);
 | 
			
		||||
#ifndef __FreeBSD__
 | 
			
		||||
     // Allow packet information to be fetched
 | 
			
		||||
     ERROR_IF_FUNC(setsockopt(socketDesc, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0, "setsockopt(IP_PKTINFO)",
 | 
			
		||||
                   CloseSocket(), return false);
 | 
			
		||||
#endif // __FreeBSD__
 | 
			
		||||
     // Bind socket
 | 
			
		||||
     memset(&sockAddr, '\0', sizeof(sockAddr));
 | 
			
		||||
     sockAddr.sin_family = AF_INET;
 | 
			
		||||
@@ -180,11 +182,13 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
 | 
			
		||||
    else
 | 
			
		||||
       break;
 | 
			
		||||
    if (len > 0) {
 | 
			
		||||
#ifndef __FreeBSD__
 | 
			
		||||
       // Process auxiliary received data and validate source address
 | 
			
		||||
       for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
 | 
			
		||||
           if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
 | 
			
		||||
              struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg);
 | 
			
		||||
              if ((i->ipi_addr.s_addr == streamAddr) || (INADDR_ANY == streamAddr)) {
 | 
			
		||||
#endif // __FreeBSD__
 | 
			
		||||
                 if (BufferAddr[0] == TS_SYNC_BYTE)
 | 
			
		||||
                    return len;
 | 
			
		||||
                 else if (len > 3) {
 | 
			
		||||
@@ -215,9 +219,11 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
 | 
			
		||||
                       return (len - headerlen);
 | 
			
		||||
                       }
 | 
			
		||||
                    }
 | 
			
		||||
#ifndef __FreeBSD__
 | 
			
		||||
                 }
 | 
			
		||||
              }
 | 
			
		||||
           }
 | 
			
		||||
#endif // __FreeBSD__
 | 
			
		||||
       }
 | 
			
		||||
    } while (len > 0);
 | 
			
		||||
  ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user