X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fcnid_dbd%2Fcomm.c;h=64038714961320c2adc775d46cdf016d20939e4a;hb=6d60f95c388da5f8f901d67e0018cf4896e6c6dc;hp=e909d6345374ca79e17aa5e70008942c5743e2ef;hpb=ecfc96169ab669b578e53fa8e13592934fe37788;p=netatalk.git diff --git a/etc/cnid_dbd/comm.c b/etc/cnid_dbd/comm.c index e909d634..64038714 100644 --- a/etc/cnid_dbd/comm.c +++ b/etc/cnid_dbd/comm.c @@ -1,48 +1,40 @@ /* - * $Id: comm.c,v 1.2 2005-04-28 20:49:47 bfernhomberg Exp $ - * * Copyright (C) Joerg Lenneis 2003 + * Copyright (C) Frank Lahm 2010 + * * All Rights Reserved. See COPYING. */ #ifdef HAVE_CONFIG_H #include "config.h" -#endif +#endif + +#ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 600 +#endif +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ +#endif +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif #include #include #include #include - -#ifdef HAVE_UNISTD_H #include -#endif - #include -#define _XPG4_2 1 -#include - -#ifdef HAVE_SYS_TYPES_H #include -#endif - -#ifdef HAVE_SYS_TIME_H #include -#endif - -#ifdef HAVE_SYS_UIO_H #include -#endif - -#ifdef HAVE_SYS_SOCKET_H #include -#endif - - +#include #include #include #include +#include #include #include "db_param.h" @@ -51,7 +43,7 @@ /* Length of the space taken up by a padded control message of length len */ #ifndef CMSG_SPACE -#define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len)) +#define CMSG_SPACE(len) (__CMSG_ALIGN(sizeof(struct cmsghdr)) + __CMSG_ALIGN(len)) #endif @@ -73,64 +65,19 @@ static void invalidate_fd(int fd) if (fd == control_fd) return; - for (i = 0; i != fds_in_use; i++) - if (fd_table[i].fd == fd) - break; - + for (i = 0; i != fds_in_use; i++) + if (fd_table[i].fd == fd) + break; + assert(i < fds_in_use); fds_in_use--; fd_table[i] = fd_table[fds_in_use]; fd_table[fds_in_use].fd = -1; - close(fd); + close(fd); return; } -static int recv_cred(int fd) -{ -int ret; -struct msghdr msgh; -struct iovec iov[1]; -struct cmsghdr *cmsgp = NULL; -char buf[CMSG_SPACE(sizeof(int))]; -char dbuf[80]; - - memset(&msgh,0,sizeof(msgh)); - memset(buf,0,sizeof(buf)); - - msgh.msg_name = NULL; - msgh.msg_namelen = 0; - - msgh.msg_iov = iov; - msgh.msg_iovlen = 1; - - iov[0].iov_base = dbuf; - iov[0].iov_len = sizeof(dbuf); - - msgh.msg_control = buf; - msgh.msg_controllen = sizeof(buf); - - do { - ret = recvmsg(fd ,&msgh,0); - } while ( ret == -1 && errno == EINTR ); - - if ( ret == -1 ) { - return -1; - } - - for ( cmsgp = CMSG_FIRSTHDR(&msgh); cmsgp != NULL; cmsgp = CMSG_NXTHDR(&msgh,cmsgp) ) { - if ( cmsgp->cmsg_level == SOL_SOCKET && cmsgp->cmsg_type == SCM_RIGHTS ) { - return *(int *) CMSG_DATA(cmsgp); - } - } - - if ( ret == sizeof (int) ) - errno = *(int *)dbuf; /* Rcvd errno */ - else - errno = ENOENT; /* Default errno */ - - return -1; -} /* * Check for client requests. We keep up to fd_table_size open descriptors in @@ -141,72 +88,75 @@ char dbuf[80]; * things and clean up fd_table. The same happens for any read/write errors. */ -static int check_fd() +static int check_fd(time_t timeout, const sigset_t *sigmask, time_t *now) { int fd; fd_set readfds; - struct timeval tv; + struct timespec tv; int ret; int i; int maxfd = control_fd; time_t t; - + FD_ZERO(&readfds); FD_SET(control_fd, &readfds); - + for (i = 0; i != fds_in_use; i++) { - FD_SET(fd_table[i].fd, &readfds); - if (maxfd < fd_table[i].fd) - maxfd = fd_table[i].fd; + FD_SET(fd_table[i].fd, &readfds); + if (maxfd < fd_table[i].fd) + maxfd = fd_table[i].fd; } - tv.tv_usec = 0; - tv.tv_sec = 1; - if ((ret = select(maxfd + 1, &readfds, NULL, NULL, &tv)) < 0) { + tv.tv_nsec = 0; + tv.tv_sec = timeout; + if ((ret = pselect(maxfd + 1, &readfds, NULL, NULL, &tv, sigmask)) < 0) { if (errno == EINTR) return 0; LOG(log_error, logtype_cnid, "error in select: %s",strerror(errno)); return -1; } + time(&t); + if (now) + *now = t; + if (!ret) - return 0; + return 0; - time(&t); if (FD_ISSET(control_fd, &readfds)) { - int l = 0; - - fd = recv_cred(control_fd); + int l = 0; + + fd = recv_fd(control_fd, 0); if (fd < 0) { return -1; } - if (fds_in_use < fd_table_size) { - fd_table[fds_in_use].fd = fd; - fd_table[fds_in_use].tm = t; - fds_in_use++; - } else { - time_t older = t; - - for (i = 0; i != fds_in_use; i++) { - if (older <= fd_table[i].tm) { - older = fd_table[i].tm; - l = i; - } - } - close(fd_table[l].fd); - fd_table[l].fd = fd; - fd_table[l].tm = t; - } - return 0; + if (fds_in_use < fd_table_size) { + fd_table[fds_in_use].fd = fd; + fd_table[fds_in_use].tm = t; + fds_in_use++; + } else { + time_t older = t; + + for (i = 0; i != fds_in_use; i++) { + if (older <= fd_table[i].tm) { + older = fd_table[i].tm; + l = i; + } + } + close(fd_table[l].fd); + fd_table[l].fd = fd; + fd_table[l].tm = t; + } + return 0; } for (i = 0; i != fds_in_use; i++) { - if (FD_ISSET(fd_table[i].fd, &readfds)) { - fd_table[i].tm = t; - return fd_table[i].fd; - } - } + if (FD_ISSET(fd_table[i].fd, &readfds)) { + fd_table[i].tm = t; + return fd_table[i].fd; + } + } /* We should never get here */ return 0; } @@ -217,13 +167,13 @@ int comm_init(struct db_param *dbp, int ctrlfd, int clntfd) fds_in_use = 0; fd_table_size = dbp->fd_table_size; - + if ((fd_table = malloc(fd_table_size * sizeof(struct connection))) == NULL) { LOG(log_error, logtype_cnid, "Out of memory"); - return -1; + return -1; } for (i = 0; i != fd_table_size; i++) - fd_table[i].fd = -1; + fd_table[i].fd = -1; /* from dup2 */ control_fd = ctrlfd; #if 0 @@ -231,17 +181,17 @@ int comm_init(struct db_param *dbp, int ctrlfd, int clntfd) /* this one dump core in recvmsg, great */ if ( setsockopt(control_fd, SOL_SOCKET, SO_PASSCRED, &b, sizeof (b)) < 0) { LOG(log_error, logtype_cnid, "setsockopt SO_PASSCRED %s", strerror(errno)); - return -1; + return -1; } #endif /* push the first client fd */ fd_table[fds_in_use].fd = clntfd; fds_in_use++; - + return 0; } -/* ------------ +/* ------------ nbe of clients */ int comm_nbe(void) @@ -250,34 +200,46 @@ int comm_nbe(void) } /* ------------ */ -int comm_rcv(struct cnid_dbd_rqst *rqst) +int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask, time_t *now) { char *nametmp; int b; - if ((cur_fd = check_fd()) < 0) + if ((cur_fd = check_fd(timeout, sigmask, now)) < 0) return -1; if (!cur_fd) return 0; - nametmp = rqst->name; - if ((b = read(cur_fd, rqst, sizeof(struct cnid_dbd_rqst))) != sizeof(struct cnid_dbd_rqst)) { - if (b) - LOG(log_error, logtype_cnid, "error reading message header: %s", strerror(errno)); + + LOG(log_maxdebug, logtype_cnid, "comm_rcv: got data on fd %u", cur_fd); + + if (setnonblock(cur_fd, 1) != 0) { + LOG(log_error, logtype_cnid, "comm_rcv: setnonblock: %s", strerror(errno)); + return -1; + } + + nametmp = (char *)rqst->name; + if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), 1, CNID_DBD_TIMEOUT)) + != sizeof(struct cnid_dbd_rqst)) { + if (b) + LOG(log_error, logtype_cnid, "error reading message header: %s", strerror(errno)); invalidate_fd(cur_fd); rqst->name = nametmp; return 0; } rqst->name = nametmp; - if (rqst->namelen && read(cur_fd, rqst->name, rqst->namelen) != rqst->namelen) { + if (rqst->namelen && readt(cur_fd, (char *)rqst->name, rqst->namelen, 1, CNID_DBD_TIMEOUT) + != rqst->namelen) { LOG(log_error, logtype_cnid, "error reading message name: %s", strerror(errno)); invalidate_fd(cur_fd); return 0; } /* We set this to make life easier for logging. None of the other stuff needs zero terminated strings. */ - rqst->name[rqst->namelen] = '\0'; - + ((char *)(rqst->name))[rqst->namelen] = '\0'; + + LOG(log_maxdebug, logtype_cnid, "comm_rcv: got %u bytes", b + rqst->namelen); + return 1; } @@ -285,9 +247,9 @@ int comm_rcv(struct cnid_dbd_rqst *rqst) #define USE_WRITEV int comm_snd(struct cnid_dbd_rply *rply) { -#ifdef USE_WRITEV - struct iovec iov[2]; - size_t towrite; +#ifdef USE_WRITEV + struct iovec iov[2]; + size_t towrite; #endif if (!rply->namelen) { @@ -298,7 +260,7 @@ int comm_snd(struct cnid_dbd_rply *rply) } return 1; } -#ifdef USE_WRITEV +#ifdef USE_WRITEV iov[0].iov_base = rply; iov[0].iov_len = sizeof(struct cnid_dbd_rply); @@ -322,7 +284,7 @@ int comm_snd(struct cnid_dbd_rply *rply) invalidate_fd(cur_fd); return 0; } -#endif +#endif return 1; }