[ez-ipupdate] Import patches from openSUSE. Update patches from Debian and actually apply them. Add patches for st

abo abo at fedoraproject.org
Sat Dec 14 19:25:45 UTC 2013


commit dbb15b05a15ae4ff18c387a9990a190cdca0785c
Author: Alexander Boström <abo at root.snowtree.se>
Date:   Sat Dec 14 18:31:06 2013 +0100

    Import patches from openSUSE.
    Update patches from Debian and actually apply them.
    Add patches for stricter C code.
    Improve systemd unit file, support multiple instances.
    Add tmpfiles config to create /run directory.
    General tidying up.

 .gitignore                           |    1 +
 ez-ipupdate-3.0.11b8-include.diff    |   11 +
 ez-ipupdate-code_cleanup.patch       |   41 ++++
 ez-ipupdate-dnsexit.patch            |  252 +++++++++++++++++++++++
 ez-ipupdate-fix_autofoo.patch        |  151 ++++++++++++++
 ez-ipupdate-format-string-vuln.patch |   12 +
 ez-ipupdate-includes.patch           |   18 ++
 ez-ipupdate-joker_com.patch          |  236 ++++++++++++++++++++++
 ez-ipupdate-returnvalues.patch       |  366 ++++++++++++++++++++++++++++++++++
 ez-ipupdate-shortexamples.patch      |  308 ++++++++++++++++++++++++++++
 ez-ipupdate-type-punning.patch       |   36 ++++
 ez-ipupdate.service                  |   10 +-
 ez-ipupdate.spec                     |  186 ++++++++++--------
 sources                              |    3 +-
 14 files changed, 1544 insertions(+), 87 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 310c609..e37aefe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 ez-ipupdate-3.0.11b8.tar.gz
 ez-ipupdate_3.0.11b8-10.diff.gz
+/ez-ipupdate_3.0.11b8-13.4.diff.gz
diff --git a/ez-ipupdate-3.0.11b8-include.diff b/ez-ipupdate-3.0.11b8-include.diff
new file mode 100644
index 0000000..7ea20e5
--- /dev/null
+++ b/ez-ipupdate-3.0.11b8-include.diff
@@ -0,0 +1,11 @@
+--- ez-ipupdate-3.0.11b8/ez-ipupdate.c
++++ ez-ipupdate-3.0.11b8/ez-ipupdate.c
+@@ -205,6 +205,8 @@
+ #  define OS "unknown"
+ #endif
+ 
++#include <time.h>
++
+ // the min period for checking the interface
+ #define MIN_UPDATE_PERIOD 10
+ // the min/max time to wait if we fail to update
diff --git a/ez-ipupdate-code_cleanup.patch b/ez-ipupdate-code_cleanup.patch
new file mode 100644
index 0000000..c437b93
--- /dev/null
+++ b/ez-ipupdate-code_cleanup.patch
@@ -0,0 +1,41 @@
+From: Philipp Thomas <pth at suse.de>
+Date: 2013-04-11 11:25:14+02:00
+Subject: Clean up the code
+
+---
+ ez-ipupdate.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+signed-off-by: pth at suse.de
+
+Index: ez-ipupdate.c
+===================================================================
+--- ez-ipupdate.c.orig	2013-04-11 10:54:02.685445947 +0200
++++ ez-ipupdate.c	2013-04-11 11:21:24.515547623 +0200
+@@ -2525,7 +2525,7 @@ int DHS_update_entry(void)
+   p += strlen(p);
+   limit = BUFFER_SIZE - 1 - strlen(buf);
+ 
+-  snprintf(buf, BUFFER_SIZE, "Content-length: %d\015\012", strlen(putbuf));
++  snprintf(buf, BUFFER_SIZE, "Content-length: %d\015\012", (int)strlen(putbuf));
+   output(buf);
+   snprintf(buf, BUFFER_SIZE, "\015\012");
+   output(buf);
+@@ -2662,7 +2662,7 @@ int DHS_update_entry(void)
+     p += strlen(p);
+     limit = BUFFER_SIZE - 1 - strlen(buf);
+ 
+-    snprintf(buf, BUFFER_SIZE, "Content-length: %d\015\012", strlen(putbuf));
++    snprintf(buf, BUFFER_SIZE, "Content-length: %d\015\012", (int)strlen(putbuf));
+     output(buf);
+     snprintf(buf, BUFFER_SIZE, "\015\012");
+     output(buf);
+@@ -4257,8 +4257,6 @@ int HEIPV6TB_update_entry(void)
+ 
+   switch(ret)
+   {
+-    char *p;
+-
+     case -1:
+       if(!(options & OPT_QUIET))
+       {
diff --git a/ez-ipupdate-dnsexit.patch b/ez-ipupdate-dnsexit.patch
new file mode 100644
index 0000000..43f13d1
--- /dev/null
+++ b/ez-ipupdate-dnsexit.patch
@@ -0,0 +1,252 @@
+--- ez-ipupdate.c.old	2005-09-11 05:41:27.000000000 -0400
++++ ez-ipupdate.c	2005-09-11 05:42:44.000000000 -0400
+@@ -103,6 +103,10 @@
+ #define HEIPV6TB_DEFAULT_PORT "80"
+ #define HEIPV6TB_REQUEST "/index.cgi"
+ 
++#define DNSEXIT_DEFAULT_SERVER "www.dnsexit.com"
++#define DNSEXIT_DEFAULT_PORT "80"
++#define DNSEXIT_REQUEST "/RemoteUpdate.sv"
++
+ #define DEFAULT_TIMEOUT 120
+ #define DEFAULT_UPDATE_PERIOD 120
+ #define DEFAULT_RESOLV_PERIOD 30
+@@ -343,6 +349,12 @@
+ int HEIPV6TB_check_info(void);
+ static char *HEIPV6TB_fields_used[] = { "server", "user", NULL };
+ 
++#ifdef USE_MD5
++int DNSEXIT_update_entry(void);
++int DNSEXIT_check_info(void);
++static char *DNSEXIT_fields_used[] = { "server", "user", "address", "wildcard", "mx", "host", NULL };
++#endif
++
+ struct service_t services[] = {
+   { "NULL",
+     { "null", "NULL", 0, },
+@@ -516,6 +528,18 @@
+     HEIPV6TB_DEFAULT_PORT,
+     HEIPV6TB_REQUEST
+   },
++#ifdef USE_MD5
++  { "dnsexit",
++  {"dnsexit", 0, 0, },
++  NULL,
++  DNSEXIT_update_entry,
++  DNSEXIT_check_info,
++  DNSEXIT_fields_used,
++  DNSEXIT_DEFAULT_SERVER,
++  DNSEXIT_DEFAULT_PORT,
++  DNSEXIT_REQUEST
++},
++#endif
+ };
+ 
+ static struct service_t *service = NULL;
+@@ -675,7 +699,7 @@
+   fprintf( stdout, "AUTHORS / CONTRIBUTORS\n"
+       "  Angus Mackay <amackay at gusnet.cx>\n"
+       "  Jeremy Bopp <jbopp at mail.utexas.edu>\n"
+-      "  Mark Jeftovic <markjr at easydns.com>\n"
++      "  Mark Jeftovic <markjr at dnsexit.com>\n"
+       "  Stefaan Ponnet <webmaster at dyns.cx>\n"
+       "  Colin Viebrock <colin at easydns.com>\n"
+       "  Tim Brown <timb at machine.org.uk>\n"
+@@ -4248,6 +4272,175 @@
+   return(UPDATERES_OK);
+ }
+ 
++#ifdef USE_MD5
++int DNSEXIT_check_info(void)
++{
++	char buf[BUFSIZ+1];
++
++	if((host == NULL) || (*host == '\0'))
++	{
++		if(options & OPT_DAEMON)
++		{
++			return(-1);
++		}
++		if(host) { free(host); }
++		printf("host: ");
++		*buf = '\0';
++		fgets(buf, BUFSIZ, stdin);
++		host = strdup(buf);
++		chomp(host);
++	}
++
++	if(interface == NULL && address == NULL)
++	{
++		if(options & OPT_DAEMON)
++		{
++			fprintf(stderr, "you must provide either an interface or an address\n");
++			return(-1);
++		}
++		if(interface) { free(interface); }
++		printf("interface: ");
++		*buf = '\0';
++		fgets(buf, BUFSIZ, stdin);
++		chomp(buf);
++		option_handler(CMD_interface, buf);
++	}
++
++	warn_fields(service->fields_used);
++
++	return 0;
++}
++
++int DNSEXIT_update_entry(void)
++{
++	char buf[BUFFER_SIZE+1];
++	char *bp = buf;
++	int bytes;
++	int btot;
++	int ret;
++
++	buf[BUFFER_SIZE] = '\0';
++
++	if(do_connect((int*)&client_sockfd, server, port) != 0)
++	{
++		if(!(options & OPT_QUIET))
++		{
++			show_message("error connecting to %s:%s\n", server, port);
++		}
++		return(UPDATERES_ERROR);
++	}
++
++	snprintf(buf, BUFFER_SIZE, "GET %s?action=edit&", request);
++	output(buf);
++	if(address != NULL && *address != '\0')
++	{
++		snprintf(buf, BUFFER_SIZE, "%s=%s&", "myip", address);
++		output(buf);
++	}
++	snprintf(buf, BUFFER_SIZE, "%s=%s&", "wildcard", wildcard ? "ON" : "OFF");
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "%s=%s&", "mx", mx);
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "%s=%s&", "backmx", *mx == '\0' ? "NO" : "YES");
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "%s=%s&", "host", host);
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "%s=%s&", "login", user_name);
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "%s=%s&", "password", password);
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, " HTTP/1.0\015\012");
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "Authorization: Basic %s\015\012", auth);
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "User-Agent: %s-%s %s [%s] (%s)\015\012",
++		 "ez-update", VERSION, OS, (options & OPT_DAEMON) ? "daemon" : "", "by Angus Mackay");
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "Host: %s\015\012", server);
++	output(buf);
++	snprintf(buf, BUFFER_SIZE, "\015\012");
++	output(buf);
++
++	bp = buf;
++	bytes = 0;
++	btot = 0;
++	while((bytes=read_input(bp, BUFFER_SIZE-btot)) > 0)
++	{
++		bp += bytes;
++		btot += bytes;
++		dprintf((stderr, "btot: %d\n", btot));
++	}
++	close(client_sockfd);
++	buf[btot] = '\0';
++
++	dprintf((stderr, "server output: %s\n", buf));
++
++	if(sscanf(buf, " HTTP/1.%*c %3d", &ret) != 1)
++	{
++		ret = -1;
++	}
++
++	switch(ret)
++	{
++		case -1:
++			if(!(options & OPT_QUIET))
++			{
++				show_message("strange server response, are you connecting to the right server?\n");
++			}
++			return(UPDATERES_ERROR);
++			break;
++
++		case 200:
++
++			if(strstr(buf, "0=Success") != NULL)
++			{
++				if(!(options & OPT_QUIET))
++				{
++					printf("Request successful\n");
++				}
++			}
++			else if(strstr(buf, "1=IP stays same") != NULL)
++			{
++				if(!(options & OPT_QUIET))
++				{
++					printf("Request successful but the IP is the same as previous update\n");
++				}
++			}
++			else
++			{
++				show_message("Errors return from server\n");
++				if(!(options & OPT_QUIET))
++				{
++					fprintf(stderr, "server output: %s\n", buf);
++				}
++				return(UPDATERES_ERROR);
++			}
++			break;
++
++		case 401:
++			if(!(options & OPT_QUIET))
++			{
++				show_message("authentication failure\n");
++			}
++			return(UPDATERES_SHUTDOWN);
++			break;
++
++		default:
++			if(!(options & OPT_QUIET))
++			{
++        // reuse the auth buffer
++				*auth = '\0';
++				sscanf(buf, " HTTP/1.%*c %*3d %255[^\r\n]", auth);
++				show_message("unknown return code: %d\n", ret);
++				show_message("server response: %s\n", auth);
++			}
++			return(UPDATERES_ERROR);
++			break;
++	}
++
++	return(UPDATERES_OK);
++}
++#endif
+ static int is_in_list(char *needle, char **haystack)
+ {
+   char **p;
+--- example-dnsexit.conf
++++ example-dnsexit.conf
+@@ -0,0 +1,19 @@
++#!/usr/local/bin/ez-ipupdate -c
++#
++# example config file for ez-ipupdate
++#
++# this file is actually executable!
++#
++
++service-type=dnsexit
++user=loginname:password
++host=www.yourdomain.com
++interface=eth0
++
++# please ensure the user has permission to write this file
++cache-file=/var/lib/ez-ipupdate/ez-ipupdate.cache
++
++# uncomment this once you have everything working how you want and you are
++# ready to have ez-ipupdate running in the background all the time. to stop it
++# you can use "killall -QUIT ez-ipupdate" under linux.
++#daemon
diff --git a/ez-ipupdate-fix_autofoo.patch b/ez-ipupdate-fix_autofoo.patch
new file mode 100644
index 0000000..1205102
--- /dev/null
+++ b/ez-ipupdate-fix_autofoo.patch
@@ -0,0 +1,151 @@
+---
+ Makefile.am  |   11 ++++++++---
+ configure.ac |   59 ++++++++++++++++++++++++++++++++---------------------------
+ 2 files changed, 40 insertions(+), 30 deletions(-)
+
+Index: Makefile.am
+===================================================================
+--- Makefile.am.orig	2013-10-29 13:53:18.608827074 +0100
++++ Makefile.am	2013-10-29 13:54:03.306789770 +0100
+@@ -1,8 +1,13 @@
+ 
+ bin_PROGRAMS = ez-ipupdate
+-ez_ipupdate_SOURCES = ez-ipupdate.c conf_file.c conf_file.h md5.c md5.h cache_file.c cache_file.h error.h pid_file.c pid_file.h dprintf.h @EXTRASRC@
+-ez_ipupdate_LDADD = @EXTRAOBJ@
++ez_ipupdate_SOURCES = ez-ipupdate.c conf_file.c conf_file.h md5.c md5.h \
++		      cache_file.c cache_file.h error.h pid_file.c pid_file.h \
++		      dprintf.h
+ 
+-EXTRA_DIST = getpass.c ez-ipupdate.lsm example.conf example-pgpow.conf example-dhs.conf example-dyndns.conf example-ods.conf example-tzo.conf example-gnudip.conf example-easydns.conf example-justlinux.conf example-dyns.conf CHANGELOG mkbinary example-heipv6tb.conf
++EXTRA_DIST = getpass.c ez-ipupdate.lsm example.conf example-pgpow.conf \
++	     example-dhs.conf example-dyndns.conf example-ods.conf \
++	     example-tzo.conf example-gnudip.conf example-easydns.conf \
++	     example-justlinux.conf example-dyns.conf CHANGELOG mkbinary \
++	     example-heipv6tb.conf
+ 
+ AUTOMAKE_OPTIONS=foreign
+Index: configure.ac
+===================================================================
+--- configure.ac.orig	2003-04-17 19:32:34.000000000 +0200
++++ configure.ac	2013-10-29 13:54:34.338065989 +0100
+@@ -1,9 +1,10 @@
+ 
+ dnl Process this file with autoconf to produce a configure script.
+-AC_INIT(ez-ipupdate.c)
+-AM_CONFIG_HEADER(config.h)
+-AM_INIT_AUTOMAKE(ez-ipupdate,3.0.11b8)
+-
++AC_INIT([ez-ipupdat]e, [3.0.11b8])
++AC_CONFIG_SRCDIR([ez-ipupdate.c])
++AC_CONFIG_HEADERS(config.h)
++AC_CONFIG_FILES(Makefile)
++AM_INIT_AUTOMAKE([foreign])
+ 
+ dnl Checks for programs.
+ 
+@@ -16,13 +17,13 @@ AC_TYPE_SIGNAL
+ 
+ dnl Checks for libraries.
+ 
+-AC_CHECK_FUNC(gethostbyname)
++AC_CHECK_FUNC([gethostbyname])
+ if test $ac_cv_func_gethostbyname = no; then
+-    AC_CHECK_LIB(nsl, gethostbyname)
++    AC_CHECK_LIB([nsl], [gethostbyname])
+ fi
+-AC_CHECK_FUNC(connect)
++AC_CHECK_FUNC([connect])
+ if test $ac_cv_func_connect = no; then
+-    AC_CHECK_LIB(socket, connect)
++    AC_CHECK_LIB([socket], [connect])
+ fi
+ 
+ AC_CHECK_FUNCS( socket \
+@@ -77,7 +78,8 @@ AC_CHECK_HEADERS( unistd.h \
+                   ,,
+                   AC_MSG_ERROR(could not locate neccessary system header files) )
+ 
+-AC_CHECK_LIB(c, sys_errlist, AC_DEFINE(HAVE_SYS_ERRLIST))
++AC_CHECK_LIB(c, sys_errlist, AC_DEFINE([HAVE_SYS_ERRLIST], 1,
++                                       [Define if you have sys_errlist]))
+ 
+ dnl you need at least to have getopt, but getopt_long will be used if it
+ dnl is present
+@@ -86,27 +88,31 @@ if test "$ac_cv_func_getopt" != yes; the
+   AC_MSG_ERROR(getopt is needed for this program to work)
+ fi
+ 
+-AC_CHECK_FUNC(getpass, AC_DEFINE(HAVE_GETPASS),
+-    [EXTRASRC="$EXTRASRC \$(srcdir)/getpass.c"]
+-    [EXTRAOBJ="$EXTRAOBJ \$(srcdir)/getpass.o"] )
++AC_CHECK_FUNC(getpass,
++              AC_DEFINE([HAVE_GETPASS], 1, [Define if you have the getpass function]),
++              AC_MSG_ERROR(Your system does not define getpass, fix it))
+ 
+ dnl Get system canonical name
+ AC_CANONICAL_HOST
+-AC_DEFINE_UNQUOTED(OS, "${host}")
++AC_DEFINE_UNQUOTED([OS], "${host}", [Define the system canonical name])
+ 
+ dnl allow selection of the default service
+ dnl the default is to use ez-ip
+-AC_MSG_CHECKING(for user supplied default service)
+-AC_ARG_ENABLE(default-service,
+-              [  --enable-default-service=SERVICE
+-                          the default service type to use
+-                          possibilities are: ezip, pgpow, justlinux, dhs,
+-                          dyndns, dyndns-static, ods, tzo, gnudip, easydns, easydns-partner, dyns, hn, zoneedit, heipv6tb],
++AC_MSG_CHECKING([for user supplied default service])
++AC_ARG_ENABLE([default-service],
++              AS_HELP_STRING([--enable-default-service=SERVICE],
++                             [the default service type to use
++                              possibilities are: ezip, pgpow, justlinux, dhs,
++                              dyndns, dyndns-static, ods, tzo, gnudip, easydns,
++                              easydns-partner, dyns, hn, zoneedit, heipv6tb, joker]),
+ 	      [ use_SERVICE=$enableval;
+ 		AC_MSG_RESULT(yes) ],
+ 	      [ AC_MSG_RESULT(no) 
+                 use_SERVICE=null
+-                AC_MSG_WARN(not setting default service) ]   )
++                AC_MSG_WARN([not setting default service]) ]   )
++
++AH_TEMPLATE([DEF_SERVICE], [Define the dyndns service to use by default])
++
+ case "$use_SERVICE" in
+   ezip ) AC_DEFINE(DEF_SERVICE, "ezip");;
+   ez-ip ) AC_DEFINE(DEF_SERVICE, "ezip");;
+@@ -126,6 +132,7 @@ case "$use_SERVICE" in
+   hn ) AC_DEFINE(DEF_SERVICE, "hn");;
+   zoneedit ) AC_DEFINE(DEF_SERVICE, "zoneedit");;
+   heipv6tb ) AC_DEFINE(DEF_SERVICE, "heipv6tb");;
++  joker) AC_DEFINE(DEF_SERVICE, "joker");;
+   null ) AC_DEFINE(DEF_SERVICE, "NULL");;
+   "" ) ;;
+   * ) AC_MSG_ERROR(unknown default service type);;
+@@ -135,21 +142,19 @@ dnl check weather we want debugging supp
+ dnl the default is to NOT use debugging support
+ AC_MSG_CHECKING(whether user wants debugging support)
+ AC_ARG_ENABLE(debug,
+-	      [  --enable-debug          include support for debugging],
+-	      [ AC_DEFINE(DEBUG)
++	      AS_HELP_STRING([--enable-debug], [include support for debugging]),
++	      [ AC_DEFINE(DEBUG, 1, [Define if you want to debug the program])
+ 		AC_MSG_RESULT(yes) ],
+ 	      [ AC_MSG_RESULT(no) ]   )
+ 
+ dnl check weather we want to disable MD5 support
+ AC_MSG_CHECKING(whether user wants to dissable MD5 support)
+ AC_ARG_ENABLE(md5,
+-	      [  --disable-md5           disable MD5 support],
++	      AS_HELP_STRING([--disable-md5], [disable MD5 support]),
+ 	      [ AC_MSG_RESULT(yes) ],
+-	      [ AC_DEFINE(USE_MD5)
++	      [ AC_DEFINE(USE_MD5, 1, [Define to use md5])
+                 AC_MSG_RESULT(no) ]   )
+ 
+-AC_SUBST(EXTRASRC)
+-AC_SUBST(EXTRAOBJ)
+ 
+-AC_OUTPUT(Makefile)
++AC_OUTPUT()
+ 
diff --git a/ez-ipupdate-format-string-vuln.patch b/ez-ipupdate-format-string-vuln.patch
new file mode 100644
index 0000000..7a00208
--- /dev/null
+++ b/ez-ipupdate-format-string-vuln.patch
@@ -0,0 +1,12 @@
+diff -ur ez-ipupdate-3.0.11b8.orig/ez-ipupdate.c ez-ipupdate-3.0.11b8/ez-ipupdate.c
+--- ez-ipupdate-3.0.11b8.orig/ez-ipupdate.c	2002-03-12 00:31:47.000000000 +0100
++++ ez-ipupdate-3.0.11b8/ez-ipupdate.c	2004-11-02 18:03:02.690856993 +0100
+@@ -798,7 +798,7 @@
+     sprintf(buf, "message incomplete because your OS sucks: %s\n", fmt);
+ #endif
+ 
+-    syslog(LOG_NOTICE, buf);
++    syslog(LOG_NOTICE, "%s", buf);
+   }
+   else
+   {
diff --git a/ez-ipupdate-includes.patch b/ez-ipupdate-includes.patch
new file mode 100644
index 0000000..28f5b9a
--- /dev/null
+++ b/ez-ipupdate-includes.patch
@@ -0,0 +1,18 @@
+--- md5.c
++++ md5.c
+@@ -27,12 +27,9 @@
+ #ifdef USE_MD5
+ 
+ #include <stdlib.h>
+-#ifdef HAVE_STRING_H
+-# include <string.h>
+-#else
+-# include <strings.h>
+-#endif
+-
++#include <stdio.h>
++#include <unistd.h>
++#include <string.h>
+ #include "md5.h"
+ 
+ #ifdef _LIBC
diff --git a/ez-ipupdate-joker_com.patch b/ez-ipupdate-joker_com.patch
new file mode 100644
index 0000000..64ff213
--- /dev/null
+++ b/ez-ipupdate-joker_com.patch
@@ -0,0 +1,236 @@
+From: Philipp Thomas <pth at suse.de>
+Date: 2013-04-10 17:53:34+02:00
+Subject: Add support for joker.com
+
+Add support for the dyndns service of joker.com.
+
+---
+ ez-ipupdate.c |  192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 192 insertions(+)
+
+signed-off-by: pth at suse.de
+
+Index: ez-ipupdate.c
+===================================================================
+--- ez-ipupdate.c.orig	2013-04-11 10:50:22.180672887 +0200
++++ ez-ipupdate.c	2013-04-11 10:54:02.685445947 +0200
+@@ -107,6 +107,10 @@
+ #define DNSEXIT_DEFAULT_PORT "80"
+ #define DNSEXIT_REQUEST "/RemoteUpdate.sv"
+ 
++#define JOKER_DEFAULT_SERVER "svc.joker.com"
++#define JOKER_DEFAULT_PORT "80"
++#define JOKER_REQUEST "/nic/update"
++
+ #define DEFAULT_TIMEOUT 120
+ #define DEFAULT_UPDATE_PERIOD 120
+ #define DEFAULT_RESOLV_PERIOD 30
+@@ -353,6 +357,10 @@ int DNSEXIT_check_info(void);
+ static char *DNSEXIT_fields_used[] = { "server", "user", "address", "wildcard", "mx", "host", NULL };
+ #endif
+ 
++int JOKER_update_entry(void);
++int JOKER_check_info(void);
++static char *JOKER_fields_used[] = { "server", "user", "address", "wildcard", "mx", "host", NULL };
++
+ struct service_t services[] = {
+   { "NULL",
+     { "null", "NULL", 0, },
+@@ -538,6 +546,16 @@ struct service_t services[] = {
+   DNSEXIT_REQUEST
+ },
+ #endif
++  { "joker",
++    { "joker", 0, 0, },
++    NULL,
++    JOKER_update_entry,
++    JOKER_check_info,
++    JOKER_fields_used,
++    JOKER_DEFAULT_SERVER,
++    JOKER_DEFAULT_PORT,
++    JOKER_REQUEST
++  },
+ };
+ 
+ static struct service_t *service = NULL;
+@@ -4265,6 +4283,180 @@ int HEIPV6TB_update_entry(void)
+       }
+       return(UPDATERES_ERROR);
+       break;
++  }
++
++  return(UPDATERES_OK);
++}
++
++int JOKER_check_info(void)
++{
++  char buf[BUFSIZ+1];
++
++  if((host == NULL) || (*host == '\0'))
++  {
++    if(options & OPT_DAEMON)
++    {
++      return(-1);
++    }
++    if(host) { free(host); }
++    printf("host: ");
++    *buf = '\0';
++    fgets(buf, BUFSIZ, stdin);
++    host = strdup(buf);
++    chomp(host);
++  }
++
++  if(interface == NULL && address == NULL)
++  {
++    if(options & OPT_DAEMON)
++    {
++      fprintf(stderr, "you must provide either an interface or an address\n");
++      return(-1);
++    }
++    if(interface) { free(interface); }
++    printf("interface: ");
++    *buf = '\0';
++    fgets(buf, BUFSIZ, stdin);
++    chomp(buf);
++    option_handler(CMD_interface, buf);
++  }
++
++  warn_fields(service->fields_used);
++
++  return 0;
++}
++
++int JOKER_update_entry(void)
++{
++  char buf[BUFFER_SIZE+1];
++  char *bp = buf;
++  int bytes;
++  int btot;
++  int ret;
++
++  buf[BUFFER_SIZE] = '\0';
++
++  if(do_connect((int*)&client_sockfd, server, port) != 0)
++  {
++    if(!(options & OPT_QUIET))
++    {
++      show_message("error connecting to %s:%s\n", server, port);
++    }
++    return(UPDATERES_ERROR);
++  }
++
++  snprintf(buf, BUFFER_SIZE, "GET %s?", request);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "username", user_name);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "password", password);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "hostname", host);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "myip", address);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "wildcard", wildcard ? "yes" : "no");
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "mx", mx);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "%s=%s&", "backmx", *mx == '\0' ? "NO" : "YES");
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, " HTTP/1.0\015\012");
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "User-Agent: %s-%s %s [%s] (%s)\015\012",
++      "ez-update", VERSION, OS, (options & OPT_DAEMON) ? "daemon" : "", "by Angus Mackay");
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "Host: %s\015\012", server);
++  output(buf);
++  snprintf(buf, BUFFER_SIZE, "\015\012");
++  output(buf);
++
++  bp = buf;
++  bytes = 0;
++  btot = 0;
++  while((bytes=read_input(bp, BUFFER_SIZE-btot)) > 0)
++  {
++    bp += bytes;
++    btot += bytes;
++    dprintf((stderr, "btot: %d\n", btot));
++  }
++  close(client_sockfd);
++  buf[btot] = '\0';
++
++  dprintf((stderr, "server output: %s\n", buf));
++
++  if(sscanf(buf, " HTTP/1.%*c %3d", &ret) != 1)
++  {
++    ret = -1;
++  }
++
++  switch(ret)
++  {
++    case -1:
++      if(!(options & OPT_QUIET))
++      {
++        show_message("strange server response, are you connecting to the right server?\n");
++      }
++      return(UPDATERES_ERROR);
++      break;
++
++    case 200:
++      if(!(options & OPT_QUIET))
++      {
++        printf("request successful\n");
++      }
++      break;
++
++    case 302:
++      // There is no neat way to determine the exact error other than to
++      // parse the Location part of the mime header to find where we're
++      // being redirected.
++      if(!(options & OPT_QUIET))
++      {
++        // reuse the auth buffer
++        *auth = '\0';
++        bp = strstr(buf, "Location: ");
++        if((bp < strstr(buf, "\r\n\r\n")) && (sscanf(bp, "Location: http://%*[^/]%255[^\r\n]", auth) == 1))
++        {
++          bp = strrchr(auth, '/') + 1;
++        }
++        else
++        {
++          bp = "";
++        }
++        dprintf((stderr, "location: %s\n", bp));
++
++        if(!(strncmp(bp, "domainmismatch.htm", strlen(bp)) && strncmp(bp, "invname.htm", strlen(bp))))
++        {
++          show_message("invalid host name\n");
++        }
++        else if(!strncmp(bp, "invkey.htm", strlen(bp)))
++        {
++          show_message("invalid password(tzo key)\n");
++        }
++        else if(!(strncmp(bp, "emailmismatch.htm", strlen(bp)) && strncmp(bp, "invemail.htm", strlen(bp))))
++        {
++          show_message("invalid user name(email address)\n");
++        }
++        else
++        {
++          show_message("unknown error\n");
++        }
++      }
++      return(UPDATERES_ERROR);
++      break;
++
++    default:
++      if(!(options & OPT_QUIET))
++      {
++        // reuse the auth buffer
++        *auth = '\0';
++        sscanf(buf, " HTTP/1.%*c %*3d %255[^\r\n]", auth);
++        show_message("unknown return code: %d\n", ret);
++        show_message("server response: %s\n", auth);
++      }
++      return(UPDATERES_ERROR);
++      break;
+   }
+ 
+   return(UPDATERES_OK);
diff --git a/ez-ipupdate-returnvalues.patch b/ez-ipupdate-returnvalues.patch
new file mode 100644
index 0000000..02453f3
--- /dev/null
+++ b/ez-ipupdate-returnvalues.patch
@@ -0,0 +1,366 @@
+--- pid_file.c	2001-07-04 11:35:01.000000000 +0200
++++ pid_file.c.fixes	2013-12-13 23:55:23.212451006 +0100
+@@ -34,8 +34,17 @@
+   oldegid = getegid();
+   oldeuid = geteuid();
+ 
+-  setegid(getgid());
+-  seteuid(getuid());
++  if (setegid(getgid()) != 0) {
++    fprintf(stderr, "could not setegid(%d).\n", (int)getgid());
++    return(-1);
++  }
++  if (seteuid(getuid()) != 0) {
++    fprintf(stderr, "could not seteuid(%d).\n", (int)getuid());
++    if (setegid(oldegid) != 0) {
++      fprintf(stderr, "could not setegid(%d).\n", (int)oldegid);
++    }
++    return(-1);
++  }
+ #endif
+ 
+   // check if the pid file exists
+@@ -74,8 +83,11 @@
+       pid_file, (int)mypid));
+ 
+ #if HAVE_SETEUID && HAVE_SETEGID
+-  setegid(oldegid);
+-  seteuid(oldeuid);
++  if (setegid(oldegid) == 0 && seteuid(oldeuid) == 0) {
++    return 0;
++  } else {
++    goto ERR;
++  }
+ #endif
+ 
+   return 0;
+@@ -83,8 +95,12 @@
+ ERR:
+   if(fp) { fclose(fp); fp = NULL; }
+ #if HAVE_SETEUID && HAVE_SETEGID
+-  setegid(oldegid);
+-  seteuid(oldeuid);
++  if (setegid(oldegid) != 0) {
++    fprintf(stderr, "could not setegid(%d).\n", (int)oldegid);
++  }
++  if (seteuid(oldeuid) != 0) {
++    fprintf(stderr, "could not seteuid(%d).\n", (int)oldeuid);
++  }
+ #endif
+   return(-1);
+ 
+@@ -106,15 +122,23 @@
+   oldegid = getegid();
+   oldeuid = geteuid();
+ 
+-  setegid(getgid());
+-  seteuid(getuid());
++  if (setegid(getgid()) != 0) {
++    fprintf(stderr, "could not setegid(%d).\n", (int)getgid());
++  }
++  if (seteuid(getuid()) != 0) {
++    fprintf(stderr, "could not seteuid(%d).\n", (int)getuid());
++  }
+ #endif
+ 
+   ret = unlink(pid_file);
+ 
+ #if HAVE_SETEUID && HAVE_SETEGID
+-  setegid(oldegid);
+-  seteuid(oldeuid);
++  if (setegid(oldegid) != 0) {
++    fprintf(stderr, "could not setegid(%d).\n", (int)oldegid);
++  }
++  if (seteuid(oldeuid) != 0) {
++    fprintf(stderr, "could not seteuid(%d).\n", (int)oldeuid);
++  }
+ #endif
+ 
+   return ret;
+--- ez-ipupdate.c	2013-12-13 23:40:16.029173192 +0100
++++ ez-ipupdate.c.buildfixes	2013-12-14 15:35:09.217704189 +0100
+@@ -737,7 +737,7 @@
+ {
+   char message[] = "interrupted\n";
+   close(client_sockfd);
+-  write(2, message, sizeof(message)-1);
++  if (write(2, message, sizeof(message)-1) != 0) {};
+ 
+ #if HAVE_GETPID
+   if(pid_file)
+@@ -1757,7 +1757,7 @@
+   }
+   printf("service: ");
+   *buf = '\0';
+-  fgets(buf, sizeof(buf), stdin);
++  if (fgets(buf, sizeof(buf), stdin) == NULL ) { return(-1); }
+   chomp(buf);
+   option_handler(CMD_service_type, buf);
+ 
+@@ -1902,7 +1902,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -1923,7 +1923,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -2198,7 +2198,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -2213,7 +2213,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -2397,7 +2397,7 @@
+     }
+     if(host) { free(host); }
+     printf("host: ");
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -2412,7 +2412,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -2751,7 +2751,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -2875,7 +2875,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -2890,7 +2890,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -3043,7 +3043,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -3058,7 +3058,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -3199,7 +3199,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -3213,7 +3213,7 @@
+     if(partner) { free(partner); }
+     printf("easyDNS partner: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     partner = strdup(buf);
+     chomp(partner);
+   }
+@@ -3228,7 +3228,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -3395,7 +3395,7 @@
+     if(server) { free(server); }
+     printf("server: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     server = strdup(buf);
+     chomp(server);
+   }
+@@ -3409,7 +3409,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -3570,7 +3570,7 @@
+     }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     host = strdup(buf);
+   }
+@@ -3585,7 +3585,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -3720,7 +3720,7 @@
+     }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     host = strdup(buf);
+   }
+@@ -3735,7 +3735,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -3958,7 +3958,7 @@
+ 
+     case 200:
+       ret = -1;
+-      if((p=strstr(buf, "DDNS_Response_")) != NULL)
++      char *p; if((p=strstr(buf, "DDNS_Response_")) != NULL)
+       {
+          sscanf(p, "DDNS_Response_%*code=%3d", &ret);
+       }
+@@ -4056,7 +4056,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -4195,7 +4195,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -4303,7 +4303,7 @@
+     if(host) { free(host); }
+     printf("host: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     host = strdup(buf);
+     chomp(host);
+   }
+@@ -4318,7 +4318,7 @@
+     if(interface) { free(interface); }
+     printf("interface: ");
+     *buf = '\0';
+-    fgets(buf, BUFSIZ, stdin);
++    if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+     chomp(buf);
+     option_handler(CMD_interface, buf);
+   }
+@@ -4478,7 +4478,7 @@
+ 		if(host) { free(host); }
+ 		printf("host: ");
+ 		*buf = '\0';
+-		fgets(buf, BUFSIZ, stdin);
++		if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+ 		host = strdup(buf);
+ 		chomp(host);
+ 	}
+@@ -4493,7 +4493,7 @@
+ 		if(interface) { free(interface); }
+ 		printf("interface: ");
+ 		*buf = '\0';
+-		fgets(buf, BUFSIZ, stdin);
++		if (fgets(buf, BUFSIZ, stdin) == NULL ) { return(-1); }
+ 		chomp(buf);
+ 		option_handler(CMD_interface, buf);
+ 	}
+@@ -4848,7 +4848,11 @@
+   if(*user_name == '\0' && !(options & OPT_DAEMON))
+   {
+     printf("user name: ");
+-    fgets(user_name, sizeof(user_name), stdin);
++    if (fgets(user_name, sizeof(user_name), stdin) == NULL)
++    {
++      fprintf(stderr, "invalid input\n");
++      exit(1);
++    }
+     chomp(user_name);
+   }
+   if(*password == '\0' && !(options & OPT_DAEMON))
+@@ -5072,7 +5076,9 @@
+                     " updater for %s due to fatal error.\" | %s %s", host,
+                     SEND_EMAIL_CMD,
+                     notify_email);
+-                system(buf);
++                if (system(buf) != 0) {
++		  show_message("and email error notification failed\n");
++		}
+               }
+               break;
+             }
diff --git a/ez-ipupdate-shortexamples.patch b/ez-ipupdate-shortexamples.patch
new file mode 100644
index 0000000..44b6735
--- /dev/null
+++ b/ez-ipupdate-shortexamples.patch
@@ -0,0 +1,308 @@
+--- example.conf	2013-12-14 16:06:38.536605342 +0100
++++ example.conf.short	2013-12-14 16:59:30.124877696 +0100
+@@ -1,27 +1,11 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=<type of service>
+ user=myuserid:mypassword
+ interface=eth1
+ #host=mydomain.whatever.com
+-
+-# other options:
+ #address=<ip address>
+-#cache-file=/etc/ez-ipupdate.cache.eth1
+-#daemon
+ #debug
+-#foreground
+-#host=<host>
+-#interface=<interface>
+ #mx=<mail exchanger>
+ #retrys=<number of trys>
+-#run-as-user=<user>
+-#run-as-euser=<user>
+ #server=<server name>
+ #timeout=<sec.millisec>
+ #max-interval=<time in seconds>
+--- example-dhs.conf	2013-12-14 16:06:38.540605288 +0100
++++ example-dhs.conf.short	2013-12-14 16:55:12.508795297 +0100
+@@ -1,20 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=dhs
+ user=myuserid:mypassword
+ host=mydomain.whatever.com
+ interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-dnsexit.conf	2013-12-14 16:06:38.559605154 +0100
++++ example-dnsexit.conf.short	2013-12-14 16:55:29.053672142 +0100
+@@ -1,19 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=dnsexit
+ user=loginname:password
+ host=www.yourdomain.com
+ interface=eth0
+-
+-# please ensure the user has permission to write this file
+-cache-file=/var/lib/ez-ipupdate/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+--- example-dyndns.conf	2013-12-14 16:06:38.541605281 +0100
++++ example-dyndns.conf.short	2013-12-14 16:55:51.724503388 +0100
+@@ -1,28 +1,6 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=dyndns
+ #service-type=dyndns-static
+ user=myuserid:mypassword
+ host=mydomain.whatever.com
+ interface=eth1
+ max-interval=2073600
+-
+-# please create this file and ensure that the user that ez-ipupdate is running
+-# as has write permissions to it then uncomment this line, if you don't your
+-# dyndns account will probably get banned. if you run ez-ipupdate as root (bad
+-# idea, use "run-as-user") then you can just uncomment this line.
+-#cache-file=/etc/ez-ipupdate.cache.eth1
+-
+-# for the mean time we'll just use a cache file in the temp directory
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-dyns.conf	2013-12-14 16:06:38.554605191 +0100
++++ example-dyns.conf.short	2013-12-14 16:56:16.992315302 +0100
+@@ -1,20 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=dyns
+ user=myuserid:mypassword
+ host=myhost
+-#interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-#cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
++interface=eth0
+--- example-easydns.conf	2013-12-14 16:06:38.550605220 +0100
++++ example-easydns.conf.short	2013-12-14 16:56:31.029210816 +0100
+@@ -1,20 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=easydns
+ user=myuserid:mypassword
+ host=mydomain.whatever.com
+ interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-gnudip.conf	2013-12-14 16:06:38.547605244 +0100
++++ example-gnudip.conf.short	2013-12-14 16:56:55.055031976 +0100
+@@ -1,10 +1,3 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=gnudip
+ user=myuserid:mypassword
+ host=mydomain.whatever.com
+@@ -13,12 +6,3 @@
+ # set address to 0.0.0.0 to go offline
+ # any other value is ignored
+ #address=0.0.0.0
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-heipv6tb.conf	2013-12-14 16:06:38.556605176 +0100
++++ example-heipv6tb.conf.short	2013-12-14 16:57:18.335858682 +0100
+@@ -1,31 +1,5 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=heipv6tb
+ #service-type=dyndns-static
+ user=myuserid:mypassword
+ interface=eth1
+ max-interval=2073600
+-
+-# please create this file and ensure that the user that ez-ipupdate is running
+-# as has write permissions to it then uncomment this line, if you don't your
+-# dyndns account will probably get banned. if you run ez-ipupdate as root (bad
+-# idea, use "run-as-user") then you can just uncomment this line.
+-#cache-file=/etc/ez-ipupdate.cache.eth1
+-
+-# for the mean time we'll just use a cache file in the temp directory
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+-# for more security use one of the following (run-as-euser is not secure):
+-#run-as-user=nobody
+-#run-as-euser=nobody
+-
+--- example-justlinux.conf	2013-12-14 16:06:38.552605206 +0100
++++ example-justlinux.conf.short	2013-12-14 16:57:29.734773832 +0100
+@@ -1,20 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=justlinux
+ user=myuserid:mypassword
+ host=mydomain.penguinpowered.com
+ interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-ods.conf	2013-12-14 16:06:38.543605273 +0100
++++ example-ods.conf.short	2013-12-14 16:57:51.514611712 +0100
+@@ -1,20 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=ods
+ user=myuserid:mypassword
+ host=mydomain.ods.org
+ interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-pgpow.conf	2013-12-14 16:06:38.538605313 +0100
++++ example-pgpow.conf.short	2013-12-14 16:58:05.471507822 +0100
+@@ -1,20 +1,4 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=pgpow
+ user=myuserid:mypassword
+ host=mydomain.penguinpowered.com
+ interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
+--- example-tzo.conf	2013-12-14 16:06:38.545605261 +0100
++++ example-tzo.conf.short	2013-12-14 16:58:21.282390132 +0100
+@@ -1,10 +1,3 @@
+-#!/usr/bin/ez-ipupdate -c
+-#
+-# example config file for ez-ipupdate
+-#
+-# this file is actually executable!
+-#
+-
+ service-type=tzo
+ user=myuserid:mypassword
+ host=mydomain.whatever.com
+@@ -13,12 +6,3 @@
+ #address=0.0.0.0
+ max-interval=2073600
+ interface=eth1
+-
+-# if you use run-as ensure the user has permission to write this file
+-cache-file=/tmp/ez-ipupdate.cache
+-
+-# uncomment this once you have everything working how you want and you are
+-# ready to have ez-ipupdate running in the background all the time. to stop it
+-# you can use "killall -QUIT ez-ipupdate" under linux.
+-#daemon
+-
diff --git a/ez-ipupdate-type-punning.patch b/ez-ipupdate-type-punning.patch
new file mode 100644
index 0000000..603e1c9
--- /dev/null
+++ b/ez-ipupdate-type-punning.patch
@@ -0,0 +1,36 @@
+From: Philipp Thomas <pth at suse.de>
+Date: 2013-04-11 11:24:54+02:00
+Subject: Use memcpy for type-punning
+
+---
+ md5.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+signed-off-by: pth at suse.de
+
+Index: md5.c
+===================================================================
+--- md5.c.orig	2013-04-11 10:50:22.160673361 +0200
++++ md5.c	2013-04-11 11:18:46.118299579 +0200
+@@ -92,6 +92,7 @@ md5_finish_ctx (struct md5_ctx *ctx, voi
+ {
+   /* Take yet unprocessed bytes into account.  */
+   md5_uint32 bytes = ctx->buflen;
++  md5_uint32 tmp;
+   size_t pad;
+ 
+   /* Now count remaining bytes.  */
+@@ -103,9 +104,10 @@ md5_finish_ctx (struct md5_ctx *ctx, voi
+   memcpy (&ctx->buffer[bytes], fillbuf, pad);
+ 
+   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+-  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
+-  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
+-							(ctx->total[0] >> 29));
++  tmp = SWAP (ctx->total[0] << 3);
++  memcpy(&ctx->buffer[bytes + pad], &tmp, sizeof(md5_uint32));
++  tmp = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
++  memcpy(&ctx->buffer[bytes + pad + 4], &tmp, sizeof(md5_uint32));
+ 
+   /* Process last bytes.  */
+   md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
diff --git a/ez-ipupdate.service b/ez-ipupdate.service
index 9ba2ff6..4da0047 100644
--- a/ez-ipupdate.service
+++ b/ez-ipupdate.service
@@ -4,8 +4,14 @@ After=network.target
 
 [Service]
 Type=forking
-PIDFile=/run/ez-ipupdate/ez-ipupdate.pid
-ExecStart=/usr/sbin/ez-ipupdate --daemon --config-file /etc/ez-ipupdate/default.conf --pid-file /run/ez-ipupdate/ez-ipupdate.pid
+Restart=always
+PIDFile=/run/ez-ipupdate/%i.pid
+ExecStart=/usr/sbin/ez-ipupdate --daemon --config-file /etc/ez-ipupdate/%i.conf --pid-file /run/ez-ipupdate/%i.pid --cache-file /var/cache/ez-ipupdate/%i.cache
+ExecReload=/bin/kill -HUP $MAINPID
+ExecStop=/bin/kill -QUIT $MAINPID
+User=ez-ipupd
+PrivateTmp=true
+NoNewPrivileges=true
 
 [Install]
 WantedBy=multi-user.target
diff --git a/ez-ipupdate.spec b/ez-ipupdate.spec
index be8f914..7b92693 100644
--- a/ez-ipupdate.spec
+++ b/ez-ipupdate.spec
@@ -1,57 +1,104 @@
 Name:           ez-ipupdate
 Version:        3.0.11
-Release:        0.28.b8%{?dist}
+Release:        0.29.b8%{?dist}
 Summary:        Client for Dynamic DNS Services
 
+## Note: Upstream is no longer reachable. Thanks to openSUSE and
+## Debian for maintaning the code, patches have been gathered from
+## there.
+
 Group:          Applications/Internet
 License:        GPLv2+
 URL:            http://www.gusnet.cx/proj/ez-ipupdate/
 Source0:        http://www.gusnet.cx/proj/ez-ipupdate/dist/ez-ipupdate-3.0.11b8.tar.gz
+
+## Fedora specific patches ##
+## systemd unit
 Source1:        %{name}.service
-Patch0:         http://ftp.debian.org/debian/pool/main/e/ez-ipupdate/ez-ipupdate_3.0.11b8-10.diff.gz
+# Make code and man page match.
 Patch1:         %{name}-pidfile.patch
-Patch2:		ez-ipupdate-3.0.11b8-zoneedit-server.patch
-BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-
-Requires(post): systemd-units
-Requires(preun): systemd-units
-Requires(postun): systemd-units
+# Hopefully improve error handling.
+Patch3:         %{name}-returnvalues.patch
+# Remove options which conflict with the way the service is started.
+Patch4:         %{name}-shortexamples.patch
+
+## Patches from openSUSE ##
+# Build fix.
+Patch11:         ez-ipupdate-3.0.11b8-include.diff
+# Security.
+Patch12:         ez-ipupdate-format-string-vuln.patch
+# Build fix.
+Patch13:         ez-ipupdate-includes.patch
+# Feature patch, add support for dnsexit dyndns service.
+Patch14:         ez-ipupdate-dnsexit.patch
+# Various fixes for configure.ac and Makefile.am
+Patch15:         ez-ipupdate-fix_autofoo.patch
+# Feature patch, add support for joker.com dyndns service
+Patch16:         ez-ipupdate-joker_com.patch
+# Do type punning via memcpy
+Patch17:         ez-ipupdate-type-punning.patch
+# Reduce compiler warnings.
+Patch18:         ez-ipupdate-code_cleanup.patch
+
+## Patches from Debian ##
+Patch30:         http://ftp.de.debian.org/debian/pool/main/e/ez-ipupdate/ez-ipupdate_3.0.11b8-13.4.diff.gz
+
+Requires(post): systemd
+Requires(preun): systemd
+Requires(postun): systemd
+BuildRequires: systemd autoconf automake
 Requires(pre):    /usr/sbin/useradd /usr/sbin/groupadd
 
 %description
-ez-ipupdate is a small utility for updating your host name for any of the
-dynamic DNS service offered at:
-  * http://www.ez-ip.net
-  * http://www.justlinux.com
-  * http://www.dhs.org
-  * http://www.dyndns.org
-  * http://www.ods.org
-  * http://gnudip.cheapnet.net (GNUDip)
-  * http://www.dyn.ca (GNUDip)
-  * http://www.tzo.com
-  * http://www.easydns.com
-  * http://www.dyns.cx
-  * http://www.hn.org
-  * http://www.zoneedit.com
-It is pure C and works on Linux, *BSD and Solaris.
-Don't forget to create your own config file to %{_sysconfdir}/ez-ipupdate.conf.
-You can find some examples in %{_docdir}/%{name}-%{version}.
+ez-ipupdate is a utility for updating DNS records at a number of
+different dynamic DNS services.
 
 
 %prep
 %setup -q -n %{name}-%{version}b8
-%patch0 -p1
+
+%patch11 -p1
+%patch12 -p1
+%patch13
+%patch14
+mv configure.in configure.ac
+%patch15
+%patch16
+%patch17
+%patch18
+rm acconfig.h
+
+%patch30 -p1
+
+mv debian/*.8 .
+
+# autotools stuff
+patch <debian/patches/010_rebootstrap.diff -p1
+# code fixes
+patch <debian/patches/102_misc_crashes.diff -p1
+# code fixes
+patch <debian/patches/103_protocol.diff -p1
+# code fixes
+patch <debian/patches/104_misc_crashes.diff -p0
+# text fixes
+patch <debian/patches/150_cosmetic.diff -p1
+
 %patch1 -p0
-%patch2 -p1
+
 touch *.in aclocal.m4 configure
 chmod +x missing
 chmod a-x example*.conf
 
+%patch3 -p0
+find -name "example*" | xargs -n 1 sed -i "s@/usr/local/bin/@/usr/bin/@"
+%patch4 -p0
 
 %build
 export CFLAGS="-D_FILE_OFFSET_BITS=64 $RPM_OPT_FLAGS"
+autoreconf -fiv
 %configure
 make %{?_smp_mflags}
+echo >tmpfiles.conf 'd %{_localstatedir}/run/%{name} 0755 ez-ipupd ez-ipupd -'
 
 
 %install
@@ -62,24 +109,22 @@ make install DESTDIR=$RPM_BUILD_ROOT bindir=%{_sbindir}
 mkdir -p $RPM_BUILD_ROOT%{_mandir}/man8
 cp -p ez-ipupdate.8 $RPM_BUILD_ROOT%{_mandir}/man8
 
-#mkdir -p $RPM_BUILD_ROOT%{_initrddir}
-#%{__perl} -pe \
-#  's|/var/|%{_localstatedir}/|g ;
-#   s|/usr/sbin/|%{_sbindir}/|g ;
-#   s|/etc/([^ir])|%{_sysconfdir}/$1|g ;
-#   s|/etc/rc\.d/init\.d/|%{_initrddir}/|g' \
-#  < %{SOURCE1} > $RPM_BUILD_ROOT%{_initrddir}/ez-ipupdate
-install -D -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_unitdir}/ez-ipupdate.service
+install -D -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_unitdir}/%{name}@.service
 
-mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/ez-ipupdate
-> $RPM_BUILD_ROOT%{_localstatedir}/cache/ez-ipupdate/default-cache
+mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/%{name}
+> $RPM_BUILD_ROOT%{_localstatedir}/cache/%{name}/default.cache
 
 # Make a directory for config files
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/ez-ipupdate
-> $RPM_BUILD_ROOT%{_sysconfdir}/ez-ipupdate/default.conf
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}
+> $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/default.conf
 
 # Create a dedicated dir for the pid file so we can run as non-root.
-mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/run/ez-ipupdate
+mkdir -p $RPM_BUILD_ROOT/run
+install -d -m 0755 $RPM_BUILD_ROOT/run/%{name}/
+
+# Also recreate the directory if needed.
+mkdir -p $RPM_BUILD_ROOT%{_tmpfilesdir}
+install -m 0644 tmpfiles.conf $RPM_BUILD_ROOT%{_tmpfilesdir}/%{name}.conf
 
 
 
@@ -89,64 +134,39 @@ rm -rf $RPM_BUILD_ROOT
 
 %pre
 /usr/sbin/groupadd -r ez-ipupd >/dev/null 2>&1 || :
-/usr/sbin/useradd -r -M -d %{_localstatedir}/cache/ez-ipupdate -g ez-ipupd \
+/usr/sbin/useradd -r -M -d %{_localstatedir}/cache/%{name} -g ez-ipupd \
   -s /sbin/nologin -c "Dynamic DNS Client" ez-ipupd >/dev/null 2>&1 || :
 
 %post
-if [ $1 -eq 1 ] ; then 
-    # Initial installation 
-    /bin/systemctl daemon-reload >/dev/null 2>&1 || :
-fi
-# move config file from old location to new if it exists
-if [ $1 -gt 1 ]; then
-    [ -f %{_sysconfdir}/ez-ipupdate.conf ] && /bin/mv %{_sysconfdir}/ez-ipupdate.conf %{_sysconfdir}/ez-ipupdate/default.conf
-    [ -f %{_localstatedir}/run/ez-ipupdate/ez-ipupdate.pid ] && /bin/mv %{_localstatedir}/run/ez-ipupdate/ez-ipupdate.pid %{_localstatedir}/run/ez-ipupdate/default.pid
-    [ -f %{_localstatedir}/lock/subsys/ez-ipupdate ] && /bin/mv %{_localstatedir}/lock/subsys/ez-ipupdate %{_localstatedir}/lock/subsys/ez-ipupdate-default
-    %{_initrddir}/ez-ipupdate condrestart >/dev/null
-fi
+%systemd_post %{name}@.service
 
 %preun
-if [ $1 -eq 0 ] ; then
-    # Package removal, not upgrade
-    /bin/systemctl --no-reload disable ez-ipupdate.service > /dev/null 2>&1 || :
-    /bin/systemctl stop ez-ipupdate.service > /dev/null 2>&1 || :
-fi
+%systemd_preun %{name}@.service
 
 %postun
-/bin/systemctl daemon-reload >/dev/null 2>&1 || :
-if [ $1 -ge 1 ] ; then
-    # Package upgrade, not uninstall
-    /bin/systemctl try-restart ez-ipupdate.service >/dev/null 2>&1 || :
-fi
-
-%triggerun -- ez-ipupdate < 3.0.11-0.25.b8
-# Save the current service runlevel info
-# User must manually run systemd-sysv-convert --apply ez-ipupdate
-# to migrate them to systemd targets
-/usr/bin/systemd-sysv-convert --save ez-ipupdate >/dev/null 2>&1 ||:
-
-# Run these because the SysV package being removed won't do them
-/sbin/chkconfig --del ez-ipupdate >/dev/null 2>&1 || :
-/bin/systemctl try-restart ez-ipupdate.service >/dev/null 2>&1 || :
+%systemd_postun %{name}@.service
 
 
 %files
 %defattr(-,root,root,-)
-%{_mandir}/man8/ez-ipupdate.8*
+%doc COPYING README example.conf example-*.conf
+%attr(0644,root,root) %{_mandir}/man8/ez-ipupdate.*
 %attr(0755,root,root) %{_sbindir}/ez-ipupdate
-%attr(0644,root,root) %{_unitdir}/ez-ipupdate.service
-%dir %{_sysconfdir}/ez-ipupdate/
-%doc CHANGELOG COPYING README example.conf example-*.conf
-%defattr(0644,root,root,-)
-%defattr(-,ez-ipupd,ez-ipupd,-)
-%dir %{_localstatedir}/cache/ez-ipupdate/
-%dir %{_localstatedir}/run/ez-ipupdate/
-%ghost %{_localstatedir}/cache/ez-ipupdate/default-cache
-%ghost %attr(0640,root,ez-ipupd) %config(noreplace,missingok) %{_sysconfdir}/ez-ipupdate/default.conf
-
+%attr(0644,root,root) %{_unitdir}/%{name}@.service
+%attr(0644,root,root) %{_tmpfilesdir}/%{name}.conf
+%attr(0750,root,ez-ipupd) %dir %{_sysconfdir}/%{name}
+%ghost %attr(0640,root,ez-ipupd) %config(noreplace,missingok) %{_sysconfdir}/%{name}/default.conf
+%attr(0755,ez-ipupd,ez-ipupd) %dir /run/%{name}/
+%attr(0750,ez-ipupd,ez-ipupd) %dir %{_localstatedir}/cache/%{name}/
+%ghost %attr(0640,ez-ipupd,ez-ipupd) %{_localstatedir}/cache/%{name}/default.cache
 
 
 %changelog
+* Fri Dec 13 2013 Alexander Boström <abo at root.snowtree.se> - 3.0.11-0.29.b8
+- Improve systemd unit file and fix broken tmpfiles handling.
+- Pull patches from openSUSE and Debian and fix error handling.
+- General tidying up.
+
 * Sat Aug 03 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 3.0.11-0.28.b8
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
 
diff --git a/sources b/sources
index 0e91da9..b0e5545 100644
--- a/sources
+++ b/sources
@@ -1,2 +1 @@
-000211add4c4845ffa4211841bff4fb0  ez-ipupdate-3.0.11b8.tar.gz
-e400c9c8d594922e394806b717250c35  ez-ipupdate_3.0.11b8-10.diff.gz
+a199cb0332551b438f87153aa3b1135f  ez-ipupdate_3.0.11b8-13.4.diff.gz


More information about the scm-commits mailing list