File nullmailer-1.05-ipv6.patch of Package nullmailer

diff -rU3 nullmailer-1.05/lib/connect.h nullmailer-1.05-ipv6/lib/connect.h
--- nullmailer-1.05/lib/connect.h	2007-10-08 00:48:27.000000000 +0200
+++ nullmailer-1.05-ipv6/lib/connect.h	2010-12-10 13:55:53.000000000 +0100
@@ -3,6 +3,8 @@
 
 #include "mystring/mystring.h"
 
-extern int tcpconnect(const mystring& hostname, int port);
+typedef enum { v4_or_v6, v4_only, v6_only } tcpconn_addresstype_t;
+
+extern int tcpconnect(const mystring& hostname, const char* service, const tcpconn_addresstype_t addresstype);
 
 #endif // NULLMAILER_CONNECT__H__
diff -rU3 nullmailer-1.05/lib/tcpconnect.cc nullmailer-1.05-ipv6/lib/tcpconnect.cc
--- nullmailer-1.05/lib/tcpconnect.cc	2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/lib/tcpconnect.cc	2010-12-10 14:07:56.000000000 +0100
@@ -26,43 +26,53 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <unistd.h>
 #include "errcodes.h"
 #include "connect.h"
 
-static int sethostbyname(const mystring& hostname, struct sockaddr_in& sa)
+int tcpconnect(const mystring& hostname, const char* service, const tcpconn_addresstype_t addresstype)
 {
-  struct hostent *he = gethostbyname(hostname.c_str());
-  if(!he) {
-    switch(h_errno) {
-    case HOST_NOT_FOUND: return -ERR_HOST_NOT_FOUND;
-    case NO_ADDRESS: return -ERR_NO_ADDRESS;
-    case NO_RECOVERY: return -ERR_GHBN_FATAL;
-    case TRY_AGAIN: return -ERR_GHBN_TEMP;
+  int family;
+  switch (addresstype) {
+    case v4_only: family = AF_INET; break;
+    case v6_only: family = AF_INET6; break;
+    default: family = AF_INET | AF_INET6;
+  }
+
+  struct addrinfo *ai = NULL,
+	 hints = {AI_V4MAPPED | AI_ADDRCONFIG | AI_ALL, family, SOCK_STREAM, 0, 0, NULL, NULL, NULL};
+  if (addresstype == v6_only) { hints.ai_flags &= ~AI_ALL; }
+  int res = getaddrinfo(hostname.c_str(), service, &hints, &ai);
+  if(res != 0) {
+    switch(res) {
+    case EAI_NONAME: return -ERR_HOST_NOT_FOUND;
+    case EAI_FAIL: return -ERR_GHBN_FATAL;
+    case EAI_AGAIN: return -ERR_GHBN_TEMP;
     default: return -ERR_GHBN_TEMP;
     }
   }
-  memcpy(&sa.sin_addr, he->h_addr, he->h_length);
-  return 0;
-}
 
-int tcpconnect(const mystring& hostname, int port)
-{
-  struct sockaddr_in sa;
-  memset(&sa, 0, sizeof(sa));
-  int e = sethostbyname(hostname, sa);
-  if(e) return e;
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons(port);
-  int s = socket(PF_INET, SOCK_STREAM, 0);
-  if(s == -1)
-    return -ERR_SOCKET;
-  if(connect(s, (sockaddr*)&sa, sizeof(sa)) != 0) {
+  struct addrinfo *trythis = ai;
+  int result = -ERR_HOST_NOT_FOUND;
+  while (trythis) {
+    int s = socket(trythis->ai_addr->sa_family, SOCK_STREAM, 0);
+    if(s == -1) {
+      result = -ERR_SOCKET;
+      break;
+    }
+    if(connect(s, trythis->ai_addr, trythis->ai_addrlen) == 0) {
+      result = s;
+      break;
+    }
     switch(errno) {
-    case ECONNREFUSED: return -ERR_CONN_REFUSED;
-    case ETIMEDOUT: return -ERR_CONN_TIMEDOUT;
-    case ENETUNREACH: return -ERR_CONN_UNREACHABLE;
-    default: return -ERR_CONN_FAILED;
+      case ECONNREFUSED: result = -ERR_CONN_REFUSED; break;
+      case ETIMEDOUT: result = -ERR_CONN_TIMEDOUT; break;
+      case ENETUNREACH: result = -ERR_CONN_UNREACHABLE; break;
+      default: result = -ERR_CONN_FAILED; break;
     }
+    close(s);
+    trythis = trythis->ai_next;
   }
-  return s;
+  freeaddrinfo(ai);
+  return result;
 }
diff -rU3 nullmailer-1.05/protocols/protocol.cc nullmailer-1.05-ipv6/protocols/protocol.cc
--- nullmailer-1.05/protocols/protocol.cc	2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/protocol.cc	2010-12-10 13:44:00.000000000 +0100
@@ -30,12 +30,14 @@
 const char* user = 0;
 const char* pass = 0;
 int auth_method = AUTH_PLAIN;
+int ipv4_only = 0;
+int ipv6_only = 0;
 const char* cli_help_suffix = "";
 const char* cli_args_usage = "remote-address < mail-file";
 const int cli_args_min = 1;
 const int cli_args_max = 1;
 cli_option cli_options[] = {
-  { 'p', "port", cli_option::integer, 0, &port,
+  { 'p', "port", cli_option::string, 0, &port,
     "Set the port number on the remote host to connect to", 0 },
   { 0, "user", cli_option::string, 0, &user,
     "Set the user name for authentication", 0 },
@@ -43,6 +45,10 @@
     "Set the password for authentication", 0 },
   { 0, "auth-login", cli_option::flag, AUTH_LOGIN, &auth_method,
     "Use AUTH LOGIN instead of AUTH PLAIN in SMTP", 0 },
+  { '4', "ipv4", cli_option::flag, 1, &ipv4_only,
+    "Try connecting with IPv4 only", 0 },
+  { '6', "ipv6", cli_option::flag, 1, &ipv6_only,
+    "Try connecting with IPv6 only", 0 },
   {0, 0, cli_option::flag, 0, 0, 0, 0}
 };
 
@@ -61,9 +67,12 @@
 int cli_main(int, char* argv[])
 {
   const char* remote = argv[0];
+  tcpconn_addresstype_t addresstype = v4_or_v6;
+  if (ipv4_only && !ipv6_only) { addresstype = v4_only; }
+  if (!ipv4_only && ipv6_only) { addresstype = v6_only; }
   fdibuf in(0, true);
   protocol_prep(&in);
-  int fd = tcpconnect(remote, port);
+  int fd = tcpconnect(remote, port, addresstype);
   if(fd < 0)
     protocol_fail(-fd, "Connect failed");
   protocol_send(&in, fd);
diff -rU3 nullmailer-1.05/protocols/protocol.h nullmailer-1.05-ipv6/protocols/protocol.h
--- nullmailer-1.05/protocols/protocol.h	2007-10-08 00:48:27.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/protocol.h	2010-12-10 13:49:41.000000000 +0100
@@ -11,9 +11,11 @@
 extern const char* user;
 extern const char* pass;
 extern int auth_method;
+extern int ipv4_only;
+extern int ipv6_only;
 
 // This must be provided by the protocol, but will be set by the lib.
-extern int port;
+extern const char* port;
 
 extern void protocol_prep(fdibuf* in);
 extern void protocol_send(fdibuf* in, int fd);
diff -rU3 nullmailer-1.05/protocols/qmqp.cc nullmailer-1.05-ipv6/protocols/qmqp.cc
--- nullmailer-1.05/protocols/qmqp.cc	2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/qmqp.cc	2010-12-10 13:49:15.000000000 +0100
@@ -30,7 +30,7 @@
 #include "netstring.h"
 #include "protocol.h"
 
-int port = 628;
+const char *port = "628";
 const char* cli_program = "qmqp";
 const char* cli_help_prefix = "Send an emal message via QMQP\n";
 
diff -rU3 nullmailer-1.05/protocols/smtp.cc nullmailer-1.05-ipv6/protocols/smtp.cc
--- nullmailer-1.05/protocols/smtp.cc	2007-10-10 07:02:13.000000000 +0200
+++ nullmailer-1.05-ipv6/protocols/smtp.cc	2010-12-10 13:49:20.000000000 +0100
@@ -30,7 +30,7 @@
 #include "mystring/mystring.h"
 #include "protocol.h"
 
-int port = 25;
+const char* port = "25";
 const char* cli_program = "smtp";
 const char* cli_help_prefix = "Send an email message via SMTP\n";
 
openSUSE Build Service is sponsored by