File nullmailer-1.10-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;
 }
--- nullmailer-1.10/protocols/protocol.cc.orig	2012-04-20 01:10:16.000000000 +0200
+++ nullmailer-1.10/protocols/protocol.cc	2012-04-30 12:23:32.000000000 +0200
@@ -29,16 +29,18 @@
 
 const char* user = 0;
 const char* pass = 0;
-int port = 0;
+const char* port = 0;
 int auth_method = AUTH_DETECT;
 int use_ssl = 0;
 int use_starttls = 0;
+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 },
@@ -46,6 +48,10 @@
     "Set the password for authentication", 0 },
   { 0, "auth-login", cli_option::flag, AUTH_LOGIN, &auth_method,
     "Use AUTH LOGIN instead of auto-detecting 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 },
 #ifdef HAVE_TLS
   { 0, "ssl", cli_option::flag, 1, &use_ssl,
     "Connect using SSL (on an alternate port by default)", 0 },
@@ -92,6 +98,9 @@
 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; }
   if (port == 0)
     port = use_ssl ? default_ssl_port : default_port;
   if (port < 0)
@@ -100,7 +109,7 @@
     tls_init(remote);
   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");
   if (use_ssl)
--- nullmailer-1.10/protocols/protocol.h.orig	2012-04-20 01:10:16.000000000 +0200
+++ nullmailer-1.10/protocols/protocol.h	2012-04-30 12:25:13.000000000 +0200
@@ -5,8 +5,8 @@
 
 #define DEFAULT_CA_FILE "/etc/ssl/certs/ca-certificates.crt"
 
-extern const int default_port;
-extern const int default_ssl_port;
+extern const char* default_port;
+extern const char* default_ssl_port;
 extern void protocol_fail(int e, const char* msg);
 extern void protocol_succ(const char* msg);
 
@@ -16,7 +16,9 @@
 extern const char* user;
 extern const char* pass;
 extern int auth_method;
-extern int port;
+extern int ipv4_only;
+extern int ipv6_only;
+extern const char* port;
 extern int use_ssl;
 extern int use_starttls;
 extern int tls_insecure;
--- nullmailer-1.10/protocols/qmqp.cc.orig	2012-04-20 01:10:16.000000000 +0200
+++ nullmailer-1.10/protocols/qmqp.cc	2012-04-30 12:25:38.000000000 +0200
@@ -30,8 +30,8 @@
 #include "netstring.h"
 #include "protocol.h"
 
-const int default_port = 628;
-const int default_ssl_port = -1; // No standard for QMQP over SSL exists
+const char* default_port = "628";
+const char* default_ssl_port = "-1"; // No standard for QMQP over SSL exists
 const char* cli_program = "qmqp";
 const char* cli_help_prefix = "Send an emal message via QMQP\n";
 
--- nullmailer-1.10/protocols/smtp.cc.orig	2012-04-20 01:10:16.000000000 +0200
+++ nullmailer-1.10/protocols/smtp.cc	2012-04-30 12:26:03.000000000 +0200
@@ -30,8 +30,8 @@
 #include "mystring/mystring.h"
 #include "protocol.h"
 
-const int default_port = 25;
-const int default_ssl_port = 465;
+const char* default_port = "25";
+const char* default_ssl_port = "465";
 const char* cli_program = "smtp";
 const char* cli_help_prefix = "Send an email message via SMTP\n";
 
openSUSE Build Service is sponsored by