X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Funix.c;h=c5f55af99e48fc5827d84e545a7d6f5cf32428cc;hb=60a702f390f7e2addfdab79f2328db3ba2897c8b;hp=2c1c979cc3d3802c7d974b53389b2050f992a2d4;hpb=c6e47cbbff56f39f6d81b079ebaeac41d793d4d9;p=yaz-moved-to-github.git diff --git a/src/unix.c b/src/unix.c index 2c1c979..c5f55af 100644 --- a/src/unix.c +++ b/src/unix.c @@ -1,27 +1,46 @@ /* - * Copyright (c) 1995-2003, Index Data + * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: unix.c,v 1.1 2003-10-27 12:21:36 adam Exp $ + * $Id: unix.c,v 1.13 2005-02-08 13:23:23 adam Exp $ * UNIX socket COMSTACK. By Morten Bøgeskov. */ +/** + * \file unix.c + * \brief Implements UNIX domain socket COMSTACK + */ + #ifndef WIN32 #include #include #include -#include #include +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_SYS_SOCKET_H +#include +#endif #include #include -#include +#include +#if HAVE_PWD_H +#include +#endif + +#if HAVE_SYS_STAT_H #include +#endif +#if HAVE_SYS_UN_H #include +#endif -#include #include -#include #include #ifndef YAZ_SOCKLEN_T @@ -65,6 +84,9 @@ typedef struct unix_state int towrite; /* to verify against user input */ int (*complete)(const unsigned char *buf, int len); /* length/comple. */ struct sockaddr_un addr; /* returned by cs_straddr */ + int uid; + int gid; + int umask; char buf[128]; /* returned by cs_addrstr */ } unix_state; @@ -130,6 +152,7 @@ COMSTACK unix_type(int s, int blocking, int protocol, void *vp) p->event = CS_NONE; p->cerrno = 0; p->stackerr = 0; + p->user = 0; state->altbuf = 0; state->altsize = state->altlen = 0; @@ -163,11 +186,102 @@ static int unix_strtoaddr_ex(const char *str, struct sockaddr_un *add) static void *unix_straddr(COMSTACK h, const char *str) { unix_state *sp = (unix_state *)h->cprivate; + char * s = strdup(str); + char * f = s; + const char * file = NULL; + char * eol; + + sp->uid = sp->gid = sp->umask = -1; + + if ((eol = strchr(s, ','))) + { + do + { + if ((eol = strchr(s, ','))) + *eol++ = '\0'; + if (sp->uid == -1 && strncmp(s, "user=", 5) == 0) + { + char * arg = s + 5; + if (strspn(arg, "0123456789") == strlen(arg)) + { + sp->uid = atoi(arg); + } + else + { + struct passwd * pw = getpwnam(arg); + if(pw == NULL) + { + printf("No such user\n"); + free(f); + return 0; + } + sp->uid = pw->pw_uid; + } + } + else if (sp->gid == -1 && strncmp(s, "group=", 6) == 0) + { + char * arg = s + 6; + if (strspn(arg, "0123456789") == strlen(arg)) + { + sp->gid = atoi(arg); + } + else + { + struct group * gr = getgrnam(arg); + if (gr == NULL) + { + printf("No such group\n"); + free(f); + return 0; + } + sp->gid = gr->gr_gid; + } + } + else if (sp->umask == -1 && strncmp(s, "umask=", 6) == 0) + { + char * end; + char * arg = s + 6; + + sp->umask = strtol(arg, &end, 8); + if (errno == EINVAL || + *end) + { + printf("Invalid umask\n"); + free(f); + return 0; + } + } + else if (file == NULL && strncmp(s, "file=", 5) == 0) + { + char * arg = s + 5; + file = arg; + } + else + { + printf("invalid or double argument: %s\n", s); + free(f); + return 0; + } + } while((s = eol)); + } + else + { + file = str; + } + if(! file) + { + errno = EINVAL; + return 0; + } TRC(fprintf(stderr, "unix_straddr: %s\n", str ? str : "NULL")); - if (!unix_strtoaddr_ex (str, &sp->addr)) + if (!unix_strtoaddr_ex (file, &sp->addr)) + { + free(f); return 0; + } + free(f); return &sp->addr; } @@ -199,6 +313,7 @@ static int unix_connect(COMSTACK h, void *address) { struct sockaddr_un *add = (struct sockaddr_un *)address; int r; + int i; TRC(fprintf(stderr, "unix_connect\n")); h->io_pending = 0; @@ -207,14 +322,28 @@ static int unix_connect(COMSTACK h, void *address) h->cerrno = CSOUTSTATE; return -1; } - r = connect(h->iofile, (struct sockaddr *) add, SUN_LEN(add)); + for (i = 0; i<3; i++) + { + r = connect(h->iofile, (struct sockaddr *) add, SUN_LEN(add)); + if (r < 0 && yaz_errno() == EAGAIN) + { +#if HAVE_USLEEP + usleep(i*10000+1000); /* 1ms, 11ms, 21ms */ +#else + sleep(1); +#endif + continue; + } + else + break; + } if (r < 0) { if (yaz_errno() == EINPROGRESS) { h->event = CS_CONNECT; h->state = CS_ST_CONNECTING; - h->io_pending = CS_WANT_WRITE|CS_WANT_READ; + h->io_pending = CS_WANT_WRITE; return 1; } h->cerrno = CSYSERR; @@ -245,11 +374,9 @@ static int unix_rcvconnect(COMSTACK h) return 0; } -#define CERTF "ztest.pem" -#define KEYF "ztest.pem" - static int unix_bind(COMSTACK h, void *address, int mode) { + unix_state *sp = (unix_state *)h->cprivate; struct sockaddr *addr = (struct sockaddr *)address; const char * path = ((struct sockaddr_un *)addr)->sun_path; struct stat stat_buf; @@ -291,7 +418,8 @@ static int unix_bind(COMSTACK h, void *address, int mode) h->cerrno = CSYSERR; return -1; } - chmod(path, 0777); + chown(path, sp->uid, sp->gid); + chmod(path, sp->umask != -1 ? sp->umask : 0666); if (mode == CS_SERVER && listen(h->iofile, 3) < 0) { h->cerrno = CSYSERR; @@ -468,7 +596,7 @@ static int unix_get(COMSTACK h, char **buf, int *bufsize) return -1; } else if (!res) - return 0; + return hasread; hasread += res; } TRC (fprintf (stderr, " Out of read loop with hasread=%d, berlen=%d\n", @@ -598,4 +726,4 @@ static int unix_set_blocking(COMSTACK p, int blocking) p->blocking = blocking; return 1; } -#endif +#endif /* WIN32 */