Provide yaz_log_{lock,unlock}
[yaz-moved-to-github.git] / src / unix.c
index 71f9d4f..559740a 100644 (file)
@@ -1,14 +1,14 @@
-/*
- * Copyright (C) 1995-2005, Index Data ApS
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
- *
- * $Id: unix.c,v 1.15 2005-06-25 15:46:06 adam Exp $
- * UNIX socket COMSTACK. By Morten Bøgeskov.
  */
 /**
  * \file unix.c
  * \brief Implements UNIX domain socket COMSTACK
  */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #ifndef WIN32
 
 #endif
 
 #include <yaz/unix.h>
-#include <yaz/nmem.h>
+#include <yaz/errno.h>
 
 #ifndef YAZ_SOCKLEN_T
 #define YAZ_SOCKLEN_T int
 #endif
 
-static int unix_close(COMSTACK h);
+/* stat(2) masks: S_IFMT and S_IFSOCK may not be defined in gcc -ansi mode */
+#if __STRICT_ANSI__
+#ifndef S_IFSOCK
+#define S_IFMT   0170000
+#define S_IFSOCK 0140000
+#endif
+#endif
+
+static void unix_close(COMSTACK h);
 static int unix_put(COMSTACK h, char *buf, int size);
 static int unix_get(COMSTACK h, char **buf, int *bufsize);
 static int unix_connect(COMSTACK h, void *address);
@@ -60,7 +68,7 @@ static int unix_listen(COMSTACK h, char *raddr, int *addrlen,
 static int unix_set_blocking(COMSTACK p, int blocking);
 
 static COMSTACK unix_accept(COMSTACK h);
-static char *unix_addrstr(COMSTACK h);
+static const char *unix_addrstr(COMSTACK h);
 static void *unix_straddr(COMSTACK h, const char *str);
 
 #ifndef SUN_LEN
@@ -82,7 +90,7 @@ typedef struct unix_state
 
     int written;  /* -1 if we aren't writing */
     int towrite;  /* to verify against user input */
-    int (*complete)(const unsigned char *buf, int len); /* length/comple. */
+    int (*complete)(const char *buf, int len); /* length/complete. */
     struct sockaddr_un addr;  /* returned by cs_straddr */
     int uid;
     int gid;
@@ -99,7 +107,7 @@ static int unix_init (void)
  * This function is always called through the cs_create() macro.
  * s >= 0: socket has already been established for us.
  */
-COMSTACK unix_type(int s, int blocking, int protocol, void *vp)
+COMSTACK unix_type(int s, int flags, int protocol, void *vp)
 {
     COMSTACK p;
     unix_state *state;
@@ -121,7 +129,8 @@ COMSTACK unix_type(int s, int blocking, int protocol, void *vp)
                                         xmalloc(sizeof(unix_state)))))
         return 0;
 
-    if (!((p->blocking = blocking)&1))
+    p->flags = flags;
+    if (!(p->flags&CS_FLAGS_BLOCKING))
     {
         if (fcntl(s, F_SETFL, O_NONBLOCK) < 0)
             return 0;
@@ -151,18 +160,13 @@ COMSTACK unix_type(int s, int blocking, int protocol, void *vp)
     p->state = new_socket ? CS_ST_UNBND : CS_ST_IDLE; /* state of line */
     p->event = CS_NONE;
     p->cerrno = 0;
-    p->stackerr = 0;
     p->user = 0;
 
     state->altbuf = 0;
     state->altsize = state->altlen = 0;
     state->towrite = state->written = -1;
-    if (protocol == PROTO_WAIS)
-        state->complete = completeWAIS;
-    else
-        state->complete = cs_complete_auto;
+    state->complete = cs_complete_auto;
 
-    p->timeout = COMSTACK_DEFAULT_TIMEOUT;
     TRC(fprintf(stderr, "Created new UNIX comstack\n"));
 
     return p;
@@ -176,25 +180,25 @@ static int unix_strtoaddr_ex(const char *str, struct sockaddr_un *add)
         return 0;
     TRC(fprintf(stderr, "unix_strtoaddress: %s\n", str ? str : "NULL"));
     add->sun_family = AF_UNIX;
-    strncpy(add->sun_path, str, sizeof(add->sun_path));
+    strncpy(add->sun_path, str, sizeof(add->sun_path)-1);
+    add->sun_path[sizeof(add->sun_path)-1] = 0;
     cp = strchr (add->sun_path, ':');
     if (cp)
         *cp = '\0';
     return 1;
 }
 
-static void *unix_straddr(COMSTACK h, const char *str)
+static void *unix_straddr1(COMSTACK h, const char *str, char *f)
 {
     unix_state *sp = (unix_state *)h->cprivate;
-    char * s = strdup(str);
-    char * f = s;
+    char * s = f;
     const char * file = NULL;
-    char * eol;
 
     sp->uid = sp->gid = sp->umask = -1;
 
-    if ((eol = strchr(s, ',')))
+    if (strchr(s, '='))
     {
+        char *eol;
         do
         {
             if ((eol = strchr(s, ',')))
@@ -212,7 +216,6 @@ static void *unix_straddr(COMSTACK h, const char *str)
                     if(pw == NULL)
                     {
                         printf("No such user\n");
-                        free(f);
                         return 0;
                     }
                     sp->uid = pw->pw_uid;
@@ -231,7 +234,6 @@ static void *unix_straddr(COMSTACK h, const char *str)
                     if (gr == NULL)
                     {
                         printf("No such group\n");
-                        free(f);
                         return 0;
                     }
                     sp->gid = gr->gr_gid;
@@ -241,13 +243,12 @@ static void *unix_straddr(COMSTACK h, const char *str)
             {
                 char * end;
                 char * arg = s + 6;
-                
+
                 sp->umask = strtol(arg, &end, 8);
                 if (errno == EINVAL ||
                     *end)
                 {
                     printf("Invalid umask\n");
-                    free(f);
                     return 0;
                 }
             }
@@ -259,7 +260,6 @@ static void *unix_straddr(COMSTACK h, const char *str)
             else
             {
                 printf("invalid or double argument: %s\n", s);
-                free(f);
                 return 0;
             }
         } while((s = eol));
@@ -277,14 +277,18 @@ static void *unix_straddr(COMSTACK h, const char *str)
     TRC(fprintf(stderr, "unix_straddr: %s\n", str ? str : "NULL"));
 
     if (!unix_strtoaddr_ex (file, &sp->addr))
-    {
-        free(f);
         return 0;
-    }
-    free(f);
     return &sp->addr;
 }
 
+static void *unix_straddr(COMSTACK h, const char *str)
+{
+    char *f = xstrdup(str);
+    void *vp = unix_straddr1(h, str, f);
+    xfree(f);
+    return vp;
+}
+
 struct sockaddr_un *unix_strtoaddr(const char *str)
 {
     static struct sockaddr_un add;
@@ -300,8 +304,7 @@ static int unix_more(COMSTACK h)
 {
     unix_state *sp = (unix_state *)h->cprivate;
 
-    return sp->altlen && (*sp->complete)((unsigned char *) sp->altbuf,
-                                         sp->altlen);
+    return sp->altlen && (*sp->complete)(sp->altbuf, sp->altlen);
 }
 
 /*
@@ -386,7 +389,8 @@ static int unix_bind(COMSTACK h, void *address, int mode)
     if(stat(path, &stat_buf) != -1) {
         struct sockaddr_un socket_unix;
         int socket_out = -1;
-        if(! S_ISSOCK(stat_buf.st_mode)) {
+
+        if((stat_buf.st_mode&S_IFMT) != S_IFSOCK) { /* used to be S_ISSOCK */
             h->cerrno = CSYSERR;
             yaz_set_errno(EEXIST); /* Not a socket (File exists) */
             return -1;
@@ -396,7 +400,8 @@ static int unix_bind(COMSTACK h, void *address, int mode)
             return -1;
         }
         socket_unix.sun_family = AF_UNIX;
-        strncpy(socket_unix.sun_path, path, sizeof(socket_unix.sun_path));
+        strncpy(socket_unix.sun_path, path, sizeof(socket_unix.sun_path)-1);
+        socket_unix.sun_path[sizeof(socket_unix.sun_path)-1] = 0;
         if(connect(socket_out, (struct sockaddr *) &socket_unix, SUN_LEN(&socket_unix)) < 0) {
             if(yaz_errno() == ECONNREFUSED) {
                 TRC (fprintf (stderr, "Socket exists but nobody is listening\n"));
@@ -418,8 +423,16 @@ static int unix_bind(COMSTACK h, void *address, int mode)
         h->cerrno = CSYSERR;
         return -1;
     }
-    chown(path, sp->uid, sp->gid);
-    chmod(path, sp->umask != -1 ? sp->umask : 0666);
+    if (chown(path, sp->uid, sp->gid))
+    {
+        h->cerrno = CSYSERR;
+        return -1;
+    }
+    if (chmod(path, sp->umask != -1 ? sp->umask : 0666))
+    {
+        h->cerrno = CSYSERR;
+        return -1;
+    }
     if (mode == CS_SERVER && listen(h->iofile, 100) < 0)
     {
         h->cerrno = CSYSERR;
@@ -496,7 +509,7 @@ static COMSTACK unix_accept(COMSTACK h)
             }
             return 0;
         }
-        if (!(cnew->blocking&1) && 
+        if (!(cnew->flags&CS_FLAGS_BLOCKING) &&
             (fcntl(cnew->iofile, F_SETFL, O_NONBLOCK) < 0)
             )
         {
@@ -552,8 +565,8 @@ static int unix_get(COMSTACK h, char **buf, int *bufsize)
     TRC(fprintf(stderr, "unix_get: bufsize=%d\n", *bufsize));
     if (sp->altlen) /* switch buffers */
     {
-        TRC(fprintf(stderr, "  %d bytes in altbuf (0x%x)\n", sp->altlen,
-                    (unsigned) sp->altbuf));
+        TRC(fprintf(stderr, "  %d bytes in altbuf (%p )\n", sp->altlen,
+                    sp->altbuf));
         tmpc = *buf;
         tmpi = *bufsize;
         *buf = sp->altbuf;
@@ -564,7 +577,7 @@ static int unix_get(COMSTACK h, char **buf, int *bufsize)
         sp->altsize = tmpi;
     }
     h->io_pending = 0;
-    while (!(berlen = (*sp->complete)((unsigned char *)*buf, hasread)))
+    while (!(berlen = (*sp->complete)(*buf, hasread)))
     {
         if (!*bufsize)
         {
@@ -615,8 +628,8 @@ static int unix_get(COMSTACK h, char **buf, int *bufsize)
         } else if (sp->altsize < req)
             if (!(sp->altbuf =(char *)xrealloc(sp->altbuf, sp->altsize = req)))
                 return -1;
-        TRC(fprintf(stderr, "  Moving %d bytes to altbuf(0x%x)\n", tomove,
-                    (unsigned) sp->altbuf));
+        TRC(fprintf(stderr, "  Moving %d bytes to altbuf(%p)\n", tomove,
+                    sp->altbuf));
         memcpy(sp->altbuf, *buf + berlen, sp->altlen = tomove);
     }
     if (berlen < CS_UNIX_BUFCHUNK - 1)
@@ -686,7 +699,7 @@ static int unix_put(COMSTACK h, char *buf, int size)
     return 0;
 }
 
-static int unix_close(COMSTACK h)
+static void unix_close(COMSTACK h)
 {
     unix_state *sp = (struct unix_state *)h->cprivate;
 
@@ -699,10 +712,9 @@ static int unix_close(COMSTACK h)
         xfree(sp->altbuf);
     xfree(sp);
     xfree(h);
-    return 0;
 }
 
-static char *unix_addrstr(COMSTACK h)
+static const char *unix_addrstr(COMSTACK h)
 {
     unix_state *sp = (struct unix_state *)h->cprivate;
     char *buf = sp->buf;
@@ -710,26 +722,27 @@ static char *unix_addrstr(COMSTACK h)
     return buf;
 }
 
-static int unix_set_blocking(COMSTACK p, int blocking)
+static int unix_set_blocking(COMSTACK p, int flags)
 {
     unsigned long flag;
 
-    if (p->blocking == blocking)
+    if (p->flags == flags)
         return 1;
     flag = fcntl(p->iofile, F_GETFL, 0);
-    if(!blocking)
+    if (flags & CS_FLAGS_BLOCKING)
         flag = flag & ~O_NONBLOCK;
     else
         flag = flag | O_NONBLOCK;
     if (fcntl(p->iofile, F_SETFL, flag) < 0)
         return 0;
-    p->blocking = blocking;
+    p->flags = flags;
     return 1;
 }
 #endif /* WIN32 */
 /*
  * Local variables:
  * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
  * indent-tabs-mode: nil
  * End:
  * vim: shiftwidth=4 tabstop=8 expandtab