hi, i prepared two patches for ez-ipupdate.

the first one adds support for the free japanese dyndns service ieserver.net, the second fixes two null string pointer bugs.
i'm not sure if those are intended to be there, but i guess it's much better to have than not. the problems arose because i didn't have an "interface" entry in my config file and fixed that by surrounding two locations where that setting is used with "if(interface != NULL)".

ieserver.net is a bit special because it doesn't use login, password and domain, but login (which is the same as the subdomain), password and domain (which is the domain suffix). i decided it would be good to distinguish that and made the new configuration entry "domain". "user" works the same way as usual.

here's a sample ez-ipupdate.conf:
service-type=ieserver
user=kimi:Naisho
domain=moe.hm
interface=ppp0
cache-file=/tmp/ez-ipupdate.cache
pid-file=/var/run/ez-ipupdate.pid

there's additional work neccessary, because the two patches don't fit in completely yet. 200-ieserver.patch is against the raw source and 300-interface.patch against the 100- and 200-patched tree. but they should work nonetheless (i get patch successes with a few lines offset).

and here are the patches:

200-ieserver.patch:
----------------------------------------------------
--- ez-ipupdate-3.0.11b8.orig/ez-ipupdate.c
+++ ez-ipupdate-3.0.11b8/ez-ipupdate.c
@@ -103,6 +103,10 @@
#define HEIPV6TB_DEFAULT_PORT "80"
#define HEIPV6TB_REQUEST "/index.cgi"

+#define IESERVER_DEFAULT_SERVER "ieserver.net"
+#define IESERVER_DEFAULT_PORT "80"
+#define IESERVER_REQUEST "/cgi-bin/dip.cgi"
+
#define DEFAULT_TIMEOUT 120
#define DEFAULT_UPDATE_PERIOD 120
#define DEFAULT_RESOLV_PERIOD 30
@@ -271,6 +275,7 @@
char *notify_email = NULL;
char *pid_file = NULL;
char *partner = NULL;
+char *domain = NULL;

static volatile int client_sockfd;
static volatile int last_sig = 0;
@@ -341,6 +346,10 @@
int HEIPV6TB_check_info(void);
static char *HEIPV6TB_fields_used[] = { "server", "user", NULL };

+int IESERVER_update_entry(void);
+int IESERVER_check_info(void);
+static char *IESERVER_fields_used[] = { "server", "user", "domain", NULL };
+
struct service_t services[] = {
   { "NULL",
     { "null", "NULL", 0, },
@@ -514,6 +523,16 @@
     HEIPV6TB_DEFAULT_PORT,
     HEIPV6TB_REQUEST
   },
+  { "ieserver",
+    { "ieserver", 0, 0, },
+    NULL,
+    IESERVER_update_entry,
+    IESERVER_check_info,
+    IESERVER_fields_used,
+    IESERVER_DEFAULT_SERVER,
+    IESERVER_DEFAULT_PORT,
+    IESERVER_REQUEST
+  },
};

static struct service_t *service = NULL;
@@ -557,6 +576,7 @@
   CMD_pid_file,
   CMD_offline,
   CMD_partner,
+  CMD_domain,
   CMD__end
};

@@ -591,6 +611,7 @@
   { CMD_connection_type, "connection-type", CONF_NEED_ARG, 1, conf_handler, "%s=<connection type>" },
   { CMD_request,         "request",         CONF_NEED_ARG, 1, conf_handler, "%s=<request uri>" },
   { CMD_partner,         "partner",         CONF_NEED_ARG, 1, conf_handler, "%s=<easydns partner>" },
+  { CMD_domain,    "domain",    CONF_NEED_ARG, 1, conf_handler, "%s=<domain>" },
   { 0, 0, 0, 0, 0 }
};

@@ -1142,6 +1163,12 @@
       dprintf((stderr, "cache_file: %s\n", cache_file));
       break;

+    case CMD_domain:
+      if(domain) { free(domain); }
+      domain = strdup(optarg);
+      dprintf((stderr, "domain: %s\n", domain));
+      break;
+
     default:
       dprintf((stderr, "case not handled: %d\n", id));
       break;
@@ -4246,6 +4273,111 @@
    return(UPDATERES_OK);
}

+int IESERVER_check_info(void)
+{
+  if(domain == NULL)
+  {
+   fprintf(stderr, "you have to specify the ieserver domain\n");
+   return(-1);
+  }
+  warn_fields(service->fields_used);
+
+  return 0;
+}
+
+int IESERVER_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?updatehost=1&", 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&", "domain", domain);
+  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 401:
+      if(!(options & OPT_QUIET))
+      {
+        show_message("authentication failure\n");
+      }
+      return(UPDATERES_SHUTDOWN);
+      break;
+
+    default:
+      if(!(options & OPT_QUIET))
+      {
+        show_message("unknown return code: %d\n", ret);
+      }
+      return(UPDATERES_ERROR);
+      break;
+  }
+
+  return(UPDATERES_OK);
+}
+
static int is_in_list(char *needle, char **haystack)
{
   char **p;


300-interface.patch:
----------------------------------------------------
--- ez-ipupdate-3.0.11b8.orig/ez-ipupdate.c
+++ ez-ipupdate-3.0.11b8/ez-ipupdate.c
@@ -4883,16 +4883,19 @@
         if(address == NULL || *address == '\0')
         {
#ifdef IF_LOOKUP
-          struct sockaddr_in sin;
-          int sock;
-
-          sock = socket(AF_INET, SOCK_STREAM, 0);
-          if(get_if_addr(sock, interface, &sin) != 0)
+          if(interface)
           {
-            exit(1);
-          }
-          close(sock);
-          snprintf(ipbuf, sizeof(ipbuf), "%s", inet_ntoa(sin.sin_addr));
+            struct sockaddr_in sin;
+            int sock;
+
+            sock = socket(AF_INET, SOCK_STREAM, 0);
+            if(get_if_addr(sock, interface, &sin) != 0)
+            {
+              exit(1);
+            }
+            close(sock);
+            snprintf(ipbuf, sizeof(ipbuf), "%s", inet_ntoa(sin.sin_addr));
+          }
#else
           fprintf(stderr, "interface lookup not enabled at compile time\n");
           exit(1);
@@ -4984,16 +4987,19 @@
         if(address == NULL || *address == '\0')
         {
#ifdef IF_LOOKUP
-          struct sockaddr_in sin;
-          int sock;
-
-          sock = socket(AF_INET, SOCK_STREAM, 0);
-          if(get_if_addr(sock, interface, &sin) != 0)
+          if (interface)
           {
-            exit(1);
+            struct sockaddr_in sin;
+            int sock;
+
+            sock = socket(AF_INET, SOCK_STREAM, 0);
+            if(get_if_addr(sock, interface, &sin) != 0)
+            {
+              exit(1);
+            }
+            close(sock);
+            snprintf(ipbuf, sizeof(ipbuf), "%s", inet_ntoa(sin.sin_addr));
           }
-          close(sock);
-          snprintf(ipbuf, sizeof(ipbuf), "%s", inet_ntoa(sin.sin_addr));
#else
           fprintf(stderr, "interface lookup not enabled at compile time\n");
           exit(1);