Implemented and-list and or-list for CCL module.
[yaz-moved-to-github.git] / comstack / tcpip.c
index 94e05c8..dd9e03b 100644 (file)
@@ -1,10 +1,27 @@
 /*
- * Copyright (c) 1995-1999, Index Data
+ * Copyright (c) 1995-2000, Index Data
  * See the file LICENSE for details.
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: tcpip.c,v $
- * Revision 1.28  1999-03-31 11:11:14  adam
+ * Revision 1.33  2000-09-04 08:27:11  adam
+ * Work on error handling for tcpip_accept.
+ *
+ * Revision 1.32  1999/11/30 13:47:11  adam
+ * Improved installation. Moved header files to include/yaz.
+ *
+ * Revision 1.31  1999/04/29 07:31:23  adam
+ * Changed tcpip_strtoaddr_ex so that only part 'till '/' is considered
+ * part of hostname.
+ *
+ * Revision 1.30  1999/04/20 09:56:48  adam
+ * Added 'name' paramter to encoder/decoder routines (typedef Odr_fun).
+ * Modified all encoders/decoders to reflect this change.
+ *
+ * Revision 1.29  1999/04/16 14:45:55  adam
+ * Added interface for tcpd wrapper for access control.
+ *
+ * Revision 1.28  1999/03/31 11:11:14  adam
  * Function getprotobyname only called once. Minor change in tcpip_get
  * to handle multi-threaded conditions.
  *
 #include <errno.h>
 #include <fcntl.h>
 
-#include <comstack.h>
-#include <tcpip.h>
+#include <yaz/comstack.h>
+#include <yaz/tcpip.h>
+#include <yaz/log.h>
 
 /* Chas added the following, so we get the definition of completeBER */
-#include <odr.h>
+#include <yaz/odr.h>
 
 int tcpip_close(COMSTACK h);
 int tcpip_put(COMSTACK h, char *buf, int size);
@@ -325,7 +343,10 @@ int tcpip_strtoaddr_ex(const char *str, struct sockaddr_in *add)
         return 0;
     TRC(fprintf(stderr, "tcpip_strtoaddress: %s\n", str ? str : "NULL"));
     add->sin_family = AF_INET;
-    strcpy(buf, str);
+    strncpy(buf, str, 511);
+    buf[511] = 0;
+    if ((p = strchr(buf, '/')))
+        *p = 0;
     if ((p = strchr(buf, ':')))
     {
         *p = 0;
@@ -433,21 +454,8 @@ int tcpip_bind(COMSTACK h, void *address, int mode)
     return 0;
 }
 
-#if 0
-void tcpip_get_ip(COMSTACK h, char *ip_buf)
-{
-    struct tcpip_state *sp = (tcpip_state *)h->cprivate;
-    const char *ip_addr = (const char *) (&sp->addr->sin_addr.s_addr);
-    int i;
-
-    for (i = 0; i<4; i++)
-       TRC (fprintf (stderr, "%u ", ip_addr[i]));
-    TRC (fprintf (stderr, "\n"));
-}
-#endif
-
 int tcpip_listen(COMSTACK h, char *raddr, int *addrlen,
-                int (*check_ip)(void *cd, const char *a, int len, int type),
+                int (*check_ip)(void *cd, const char *a, int len, int t),
                 void *cd)
 {
     struct sockaddr_in addr;
@@ -459,32 +467,35 @@ int tcpip_listen(COMSTACK h, char *raddr, int *addrlen,
         h->cerrno = CSOUTSTATE;
         return -1;
     }
-    if ((h->newfd = accept(h->iofile, (struct sockaddr*)&addr, &len)) < 0)
+    h->newfd = accept(h->iofile, (struct sockaddr*)&addr, &len);
+    if (h->newfd < 0)
     {
+       if (
 #ifdef WIN32
-        if (WSAGetLastError() == WSAEWOULDBLOCK)
+           WSAGetLastError() == WSAEWOULDBLOCK
 #else
-        if (errno == EWOULDBLOCK)
+           errno == EWOULDBLOCK
 #endif
-
-            h->cerrno = CSNODATA;
-        else
-            h->cerrno = CSYSERR;
+           )
+           h->cerrno = CSNODATA;
+       else
+           h->cerrno = CSYSERR;
         return -1;
     }
-    if (addrlen && *addrlen >= sizeof(struct sockaddr_in))
+    if (addrlen && (size_t) (*addrlen) >= sizeof(struct sockaddr_in))
         memcpy(raddr, &addr, *addrlen = sizeof(struct sockaddr_in));
     else if (addrlen)
         *addrlen = 0;
-    if (check_ip && (*check_ip)(cd, (const char *) &addr.sin_addr,
-        sizeof(addr.sin_addr), AF_INET))
+    if (check_ip && (*check_ip)(cd, (const char *) &addr,
+        sizeof(addr), AF_INET))
     {
        h->cerrno = CSDENY;
 #ifdef WIN32
-        closesocket(h->iofile);
+        closesocket(h->newfd);
 #else
-        close(h->iofile);
+        close(h->newfd);
 #endif
+       h->newfd = -1;
        return -1;
     }
     h->state = CS_INCON;
@@ -508,6 +519,12 @@ COMSTACK tcpip_accept(COMSTACK h)
     if (!(cnew = (COMSTACK)xmalloc(sizeof(*cnew))))
     {
         h->cerrno = CSYSERR;
+#ifdef WIN32
+        closesocket(h->newfd);
+#else
+        close(h->newfd);
+#endif
+       h->newfd = -1;
         return 0;
     }
     memcpy(cnew, h, sizeof(*h));
@@ -516,6 +533,15 @@ COMSTACK tcpip_accept(COMSTACK h)
          (cnew->cprivate = xmalloc(sizeof(tcpip_state)))))
     {
         h->cerrno = CSYSERR;
+       if (h->newfd != -1)
+       {
+#ifdef WIN32
+           closesocket(h->newfd);
+#else
+           close(h->newfd);
+#endif
+           h->newfd = -1;
+       }
         return 0;
     }
 #ifdef WIN32
@@ -523,7 +549,22 @@ COMSTACK tcpip_accept(COMSTACK h)
 #else
     if (!cnew->blocking && fcntl(cnew->iofile, F_SETFL, O_NONBLOCK) < 0)
 #endif
+    {
+       h->cerrno = CSYSERR;
+       if (h->newfd != -1)
+       {
+#ifdef WIN32
+           closesocket(h->newfd);
+#else
+           close(h->newfd);
+#endif
+           h->newfd = -1;
+       }
+       xfree (cnew);
+       xfree (state);
         return 0;
+    }
+    h->newfd = -1;
     state->altbuf = 0;
     state->altsize = state->altlen = 0;
     state->towrite = state->written = -1;
@@ -690,7 +731,7 @@ char *tcpip_addrstr(COMSTACK h)
     struct sockaddr_in addr;
     tcpip_state *sp = (struct tcpip_state *)h->cprivate;
     char *r, *buf = sp->buf;
-    int len;
+    size_t len;
     struct hostent *host;
     
     len = sizeof(addr);