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=03827b4ec0ce355d48642239e67dff56531e8228;hpb=03a992a695725cad6e20ce0f9fd83385aa200926;p=netatalk.git diff --git a/etc/cnid_dbd/comm.c b/etc/cnid_dbd/comm.c index 03827b4e..64038714 100644 --- a/etc/cnid_dbd/comm.c +++ b/etc/cnid_dbd/comm.c @@ -9,6 +9,16 @@ #include "config.h" #endif +#ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 600 +#endif +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ +#endif +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + #include #include #include @@ -68,107 +78,6 @@ static void invalidate_fd(int fd) return; } -/*! - * non-blocking drop-in replacement for read with timeout using select - * - * @param socket (r) must be nonblocking ! - * @param data (rw) buffer for the read data - * @param lenght (r) how many bytes to read - * @param timeout (r) number of seconds to try reading - * - * @returns number of bytes actually read or -1 on fatal error - */ -static ssize_t readt(int socket, void *data, const size_t length, int timeout) -{ - size_t stored; - ssize_t len; - struct timeval tv; - fd_set rfds; - int ret; - - stored = 0; - - while (stored < length) { - len = read(socket, (u_int8_t *) data + stored, length - stored); - if (len == -1) { - switch (errno) { - case EINTR: - continue; - case EAGAIN: - tv.tv_usec = 0; - tv.tv_sec = timeout; - - FD_ZERO(&rfds); - FD_SET(socket, &rfds); - while ((ret = select(socket + 1, &rfds, NULL, NULL, &tv)) < 1) { - switch (ret) { - case 0: - LOG(log_warning, logtype_cnid, "select timeout 1s"); - return stored; - default: /* -1 */ - LOG(log_error, logtype_cnid, "select: %s", strerror(errno)); - return -1; - } - } - continue; - } - LOG(log_error, logtype_cnid, "read: %s", strerror(errno)); - return -1; - } - else if (len > 0) - stored += len; - else - break; - } - return stored; -} - - -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 @@ -218,7 +127,7 @@ static int check_fd(time_t timeout, const sigset_t *sigmask, time_t *now) if (FD_ISSET(control_fd, &readfds)) { int l = 0; - fd = recv_cred(control_fd); + fd = recv_fd(control_fd, 0); if (fd < 0) { return -1; } @@ -309,8 +218,8 @@ int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask return -1; } - nametmp = rqst->name; - if ((b = readt(cur_fd, rqst, sizeof(struct cnid_dbd_rqst), CNID_DBD_TIMEOUT)) + 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)); @@ -319,7 +228,7 @@ int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask return 0; } rqst->name = nametmp; - if (rqst->namelen && readt(cur_fd, rqst->name, rqst->namelen, CNID_DBD_TIMEOUT) + 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); @@ -327,7 +236,7 @@ int comm_rcv(struct cnid_dbd_rqst *rqst, time_t timeout, const sigset_t *sigmask } /* 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);