summaryrefslogtreecommitdiff
path: root/common.c
diff options
context:
space:
mode:
authorhorchi <vdr@jwendel.de>2020-08-21 16:36:52 +0200
committerhorchi <vdr@jwendel.de>2020-08-21 16:36:52 +0200
commit740602403557156183e5fdedca7f0e9b9618897f (patch)
tree682debe540be0d18547c47f4ff09ddd1b5673d75 /common.c
parent6853f2b6327e468efb77fa989dfa6080c257cf6c (diff)
downloadvdr-plugin-seduatmo-740602403557156183e5fdedca7f0e9b9618897f.tar.gz
vdr-plugin-seduatmo-740602403557156183e5fdedca7f0e9b9618897f.tar.bz2
2020-08-21: Version 0.0.10\n - added: Auto powerof by TV state (option -t <ip\ndns>)\n\n0.0.10
Diffstat (limited to 'common.c')
-rw-r--r--common.c181
1 files changed, 174 insertions, 7 deletions
diff --git a/common.c b/common.c
index 17b594b..a9d4466 100644
--- a/common.c
+++ b/common.c
@@ -6,6 +6,11 @@
*/
#include <sys/time.h>
+#include <sys/param.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip_icmp.h>
+#include <netdb.h>
+
#include <stdarg.h>
#include <string.h>
#include <syslog.h>
@@ -31,12 +36,12 @@ void tell(int eloquence, const char* format, ...)
va_list ap;
cMutexLock lock(&logMutex);
-
+
va_start(ap, format);
snprintf(t, sizeBuffer, "SEDUATMO: ");
vsnprintf(t+strlen(t), sizeBuffer-strlen(t), format, ap);
-
+
syslog(LOG_ERR, "%s", t);
va_end(ap);
@@ -53,12 +58,12 @@ int error(const char* format, ...)
va_list ap;
cMutexLock lock(&logMutex);
-
+
va_start(ap, format);
snprintf(t, sizeBuffer, "SEDUATMO: ");
vsnprintf(t+strlen(t), sizeBuffer-strlen(t), format, ap);
-
+
syslog(LOG_ERR, "%s", t);
va_end(ap);
@@ -67,6 +72,15 @@ int error(const char* format, ...)
}
//***************************************************************************
+// is Empty
+//***************************************************************************
+
+int isEmpty(const char* str)
+{
+ return !str || !*str;
+}
+
+//***************************************************************************
// msNow
//***************************************************************************
@@ -74,7 +88,7 @@ MsTime msNow()
{
timeval tv;
- gettimeofday(&tv, 0);
+ gettimeofday(&tv, 0);
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
@@ -87,10 +101,10 @@ int minMax(int x, int min, int max)
{
if (x < min)
return min;
-
+
if (max < x)
return max;
-
+
return x;
}
@@ -109,3 +123,156 @@ int getrand(int min, int max)
srand(time(0));
return rand() % (max-min) + min;
}
+
+//***************************************************************************
+// Is Alive (fork ping therefore no root permissions needed)
+//***************************************************************************
+
+int isAlive(const char* address)
+{
+ return ping(address) == success;
+}
+
+uint16_t cksum(uint16_t *addr, unsigned len)
+{
+ uint16_t answer = 0;
+ uint32_t sum = 0;
+
+ while (len > 1)
+ {
+ sum += *addr++;
+ len -= 2;
+ }
+
+ if (len == 1)
+ {
+ *(unsigned char *)&answer = *(unsigned char *)addr ;
+ sum += answer;
+ }
+
+ sum = (sum >> 16) + (sum & 0xffff);
+ sum += (sum >> 16);
+ answer = ~sum;
+
+ return answer;
+}
+
+int ping(const char* target)
+{
+ const size_t DEFDATALEN = (64-ICMP_MINLEN);
+ const size_t MAXIPLEN = 60;
+ const size_t MAXICMPLEN = 76;
+ const size_t MAXPACKET = (65536 - 60 - ICMP_MINLEN);
+
+ int i, cc, packlen, datalen = DEFDATALEN;
+ struct hostent *hp;
+ struct sockaddr_in to, from;
+
+ u_char *packet, outpack[MAXPACKET];
+ char hnamebuf[MAXHOSTNAMELEN];
+ std::string hostname;
+ struct icmp *icp;
+ int ret, fromlen, hlen;
+ fd_set rfds;
+ struct timeval tv;
+
+ to.sin_family = AF_INET;
+ to.sin_addr.s_addr = inet_addr(target);
+
+ if (to.sin_addr.s_addr != (u_int)-1)
+ hostname = target;
+ else
+ {
+ if (!(hp = gethostbyname(target)))
+ {
+ tell(0, "unknown host '%s'", target);
+ return fail;
+ }
+
+ to.sin_family = hp->h_addrtype;
+ bcopy(hp->h_addr, (caddr_t)&to.sin_addr, hp->h_length);
+ strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
+ hostname = hnamebuf;
+ }
+
+ packlen = datalen + MAXIPLEN + MAXICMPLEN;
+ packet = (u_char*)malloc((u_int)packlen);
+
+ int sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+
+ if (sd < 0)
+ {
+ tell(0, "Error: sokett failed due to '%s'", strerror(errno));
+ return fail; // Needs to run as root ore set rights "setcap cap_net_raw+ep /usr/bin/vdr"
+ }
+
+ icp = (struct icmp*)outpack;
+ icp->icmp_type = ICMP_ECHO;
+ icp->icmp_code = 0;
+ icp->icmp_cksum = 0;
+ icp->icmp_seq = 12345;
+ icp->icmp_id = getpid();
+
+ cc = datalen + ICMP_MINLEN;
+ icp->icmp_cksum = cksum((unsigned short *)icp,cc);
+ i = sendto(sd, (char *)outpack, cc, 0, (struct sockaddr*)&to, (socklen_t)sizeof(struct sockaddr_in));
+
+ if (i < 0)
+ tell(0, "Error: Sendto '%s'", strerror(errno));
+
+ FD_ZERO(&rfds);
+ FD_SET(sd, &rfds);
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+
+ while (true)
+ {
+ int retval = select(sd+1, &rfds, NULL, NULL, &tv);
+
+ if (retval <= 0)
+ {
+ if (retval == -1)
+ tell(0, "Error: select() '%s'", strerror(errno));
+
+ close(sd);
+ return fail;
+ }
+
+ fromlen = sizeof(sockaddr_in);
+
+ if ((ret = recvfrom(sd, (char*)packet, packlen, 0, (struct sockaddr*)&from, (socklen_t*)&fromlen)) < 0)
+ {
+ tell(0, "Error: recvfrom '%s'", strerror(errno));
+ close(sd);
+ return fail;
+ }
+
+ // Check the IP header
+
+ hlen = sizeof(struct ip);
+
+ if (ret < (hlen + ICMP_MINLEN))
+ {
+ tell(0, "Packet too short (%d) bytes from '%s'", ret, hostname.c_str());
+ close(sd);
+ return fail;
+ }
+
+ // Now the ICMP part
+
+ icp = (struct icmp*)(packet + hlen);
+
+ if (icp->icmp_type == ICMP_ECHOREPLY)
+ {
+ if (icp->icmp_seq == 12345 && icp->icmp_id == getpid())
+ {
+ close(sd);
+ return success;
+ }
+ }
+ }
+
+ close(sd);
+
+ return fail;
+}