Doc: s/DNS/domains/ in new text
[exim.git] / src / src / smtp_out.c
index 449b52438b3295d9ae9334d3eb9e431ff6de93c1..d6cfbba7dedf1663e674ba81c5856b4d8f39c0c7 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/smtp_out.c,v 1.2 2004/11/04 12:19:48 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* A number of functions for driving outgoing SMTP calls. */
@@ -155,12 +153,13 @@ non-IPv6 systems, to enable the code to be less messy. However, on such systems
 host->address will always be an IPv4 address.
 
 The port field in the host item is used if it is set (usually router from SRV
-records). In other cases, the default passed as an argument is used.
+records or elsewhere). In other cases, the default passed as an argument is
+used, and the host item is updated with its value.
 
 Arguments:
   host        host item containing name and address (and sometimes port)
   host_af     AF_INET or AF_INET6
-  port        default, remote port to connect to, in host byte order for those
+  port        default remote port to connect to, in host byte order, for those
                 hosts whose port setting is PORT_NONE
   interface   outgoing interface address or NULL
   timeout     timeout value or 0
@@ -184,6 +183,7 @@ if (host->port != PORT_NONE)
       host->port);
   port = host->port;
   }
+else host->port = port;    /* Set the port actually used */
 
 HDEBUG(D_transport|D_acl|D_v)
   {
@@ -223,14 +223,14 @@ else if (ip_connect(sock, host_af, host->address, port, timeout) < 0)
 
 if (save_errno != 0)
   {
-  HDEBUG(D_transport|D_acl|D_v) 
+  HDEBUG(D_transport|D_acl|D_v)
     {
     debug_printf("failed: %s", CUstrerror(save_errno));
-    if (save_errno == ETIMEDOUT) 
+    if (save_errno == ETIMEDOUT)
       debug_printf(" (timeout=%s)", readconf_printtime(timeout));
-    debug_printf("\n");   
-    } 
-  close(sock);
+    debug_printf("\n");
+    }
+  (void)close(sock);
   errno = save_errno;
   return -1;
   }
@@ -239,7 +239,18 @@ if (save_errno != 0)
 
 else
   {
+  union sockaddr_46 interface_sock;
+  EXIM_SOCKLEN_T size = sizeof(interface_sock);
   HDEBUG(D_transport|D_acl|D_v) debug_printf("connected\n");
+  if (getsockname(sock, (struct sockaddr *)(&interface_sock), &size) == 0)
+    sending_ip_address = host_ntoa(-1, &interface_sock, NULL, &sending_port);
+  else
+    {
+    log_write(0, LOG_MAIN | ((errno == ECONNRESET)? 0 : LOG_PANIC),
+      "getsockname() failed: %s", strerror(errno));
+    close(sock);
+    return -1;
+    }
   if (keepalive) ip_keepalive(sock, host->address, TRUE);
   return sock;
   }
@@ -305,7 +316,7 @@ Returns:     0 if command added to pipelining buffer, with nothing transmitted
 */
 
 int
-smtp_write_command(smtp_outblock *outblock, BOOL noflush, char *format, ...)
+smtp_write_command(smtp_outblock *outblock, BOOL noflush, const char *format, ...)
 {
 int count;
 int rc = 0;