X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Funix.c;h=559740a4f7aff8b55617c15545949f0a7d4517b4;hp=71f9d4fc14908ba4b8b7e58f7020c443506922d5;hb=b80d372819c8c909455ca5868f6d7412dfbbef66;hpb=fb6d99a0c7e07d9cc4a315c447deaf6564a85505 diff --git a/src/unix.c b/src/unix.c index 71f9d4f..559740a 100644 --- a/src/unix.c +++ b/src/unix.c @@ -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 +#endif #ifndef WIN32 @@ -41,13 +41,21 @@ #endif #include -#include +#include #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