-/*
- * 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);
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
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;
* 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;
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;
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;
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, ',')))
if(pw == NULL)
{
printf("No such user\n");
- free(f);
return 0;
}
sp->uid = pw->pw_uid;
if (gr == NULL)
{
printf("No such group\n");
- free(f);
return 0;
}
sp->gid = gr->gr_gid;
{
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
{
printf("invalid or double argument: %s\n", s);
- free(f);
return 0;
}
} while((s = eol));
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;
{
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);
}
/*
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;
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"));
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;
}
return 0;
}
- if (!(cnew->blocking&1) &&
+ if (!(cnew->flags&CS_FLAGS_BLOCKING) &&
(fcntl(cnew->iofile, F_SETFL, O_NONBLOCK) < 0)
)
{
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;
sp->altsize = tmpi;
}
h->io_pending = 0;
- while (!(berlen = (*sp->complete)((unsigned char *)*buf, hasread)))
+ while (!(berlen = (*sp->complete)(*buf, hasread)))
{
if (!*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)
return 0;
}
-static int unix_close(COMSTACK h)
+static void unix_close(COMSTACK h)
{
unix_state *sp = (struct unix_state *)h->cprivate;
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;
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