Merge pull request #30 from SpamExperts/master
[exim.git] / src / src / ip.c
index a50e209a21fc1a0ab207ed3aaa73d511e7f19fc7..f6072c2e80019e4df87e34f3d490f956bb8c39b9 100644 (file)
@@ -337,7 +337,8 @@ for (h = &shost; h != NULL; h = h->next)
       {
       if (fd != fd6) close(fd6);
       if (fd != fd4) close(fd4);
-      if (connhost) {
+      if (connhost)
+       {
        h->port = port;
        *connhost = *h;
        connhost->next = NULL;
@@ -354,6 +355,58 @@ bad:
 }
 
 
+int
+ip_tcpsocket(const uschar * hostport, uschar ** errstr, int tmo)
+{
+  int scan;
+  uschar hostname[256];
+  unsigned int portlow, porthigh;
+
+  /* extract host and port part */
+  scan = sscanf(CS hostport, "%255s %u-%u", hostname, &portlow, &porthigh);
+  if ( scan != 3 ) {
+    if ( scan != 2 ) {
+      *errstr = string_sprintf("invalid socket '%s'", hostport);
+      return -1;
+    }
+    porthigh = portlow;
+  }
+
+  return ip_connectedsocket(SOCK_STREAM, hostname, portlow, porthigh,
+                           tmo, NULL, errstr);
+}
+
+int
+ip_unixsocket(const uschar * path, uschar ** errstr)
+{
+  int sock;
+  struct sockaddr_un server;
+
+  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+    *errstr = US"can't open UNIX socket.";
+    return -1;
+  }
+
+  server.sun_family = AF_UNIX;
+  Ustrncpy(server.sun_path, path, sizeof(server.sun_path)-1);
+  server.sun_path[sizeof(server.sun_path)-1] = '\0';
+  if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
+    int err = errno;
+    (void)close(sock);
+    *errstr =  string_sprintf("unable to connect to UNIX socket (%s): %s",
+                 path, strerror(err));
+    return -1;
+    }
+  return sock;
+}
+
+int
+ip_streamsocket(const uschar * spec, uschar ** errstr, int tmo)
+{
+  return *spec == '/'
+    ? ip_unixsocket(spec, errstr) : ip_tcpsocket(spec, errstr, tmo);
+}
+
 /*************************************************
 *         Set keepalive on a socket              *
 *************************************************/
@@ -369,7 +422,7 @@ Returns:     nothing
 */
 
 void
-ip_keepalive(int sock, uschar *address, BOOL torf)
+ip_keepalive(int sock, const uschar *address, BOOL torf)
 {
 int fodder = 1;
 if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
@@ -413,7 +466,7 @@ for (;;)
   tv.tv_sec = timeout;
   tv.tv_usec = 0;
 
-  DEBUG(D_transport) debug_printf("waiting for data on fd\n");
+  /*DEBUG(D_transport) debug_printf("waiting for data on fd\n");*/
   rc = select(fd + 1, (SELECT_ARG2_TYPE *)&select_inset, NULL, NULL, &tv);
 
   /* If some interrupt arrived, just retry. We presume this to be rare,
@@ -668,3 +721,5 @@ for (i=0; i < dscp_table_size; ++i)
 
 
 /* End of ip.c */
+/* vi: aw ai sw=2
+*/