X-Git-Url: http://dolda2000.com/gitweb/?a=blobdiff_plain;f=lib%2Fuilib.c;fp=lib%2Fuilib.c;h=65215b7d5d3b4dadb12465addd7d3217de7694b7;hb=9e5f2b29cf819c9f79113bf3ae7edcb484d8ee14;hp=034c8233fd0dd1dd356094447e75eee3c64873ff;hpb=6a97462ee92722d88e01bb18abd57f1f44d5125b;p=doldaconnect.git diff --git a/lib/uilib.c b/lib/uilib.c index 034c823..65215b7 100644 --- a/lib/uilib.c +++ b/lib/uilib.c @@ -96,8 +96,12 @@ static int state = -1; static int fd = -1; static iconv_t ichandle; static int resetreader = 1; -static char *dchostname = NULL; static struct addrinfo *hostlist = NULL, *curhost = NULL; +struct { + char *hostname; + int family; + int sentcreds; +} servinfo; static struct dc_response *makeresp(void) { @@ -276,9 +280,9 @@ void dc_disconnect(void) while((resp = dc_getresp()) != NULL) dc_freeresp(resp); dc_uimisc_disconnected(); - if(dchostname != NULL) - free(dchostname); - dchostname = NULL; + if(servinfo.hostname != NULL) + free(servinfo.hostname); + memset(&servinfo, 0, sizeof(servinfo)); } void dc_freeresp(struct dc_response *resp) @@ -532,7 +536,8 @@ int dc_handleread(void) } } if(curhost->ai_canonname != NULL) - dchostname = sstrdup(curhost->ai_canonname); + servinfo.hostname = sstrdup(curhost->ai_canonname); + servinfo.family = curhost->ai_family; state = 1; resetreader = 1; break; @@ -744,17 +749,48 @@ int dc_handleread(void) return(0); } +static void mkcreds(struct msghdr *msg) +{ + struct ucred *ucred; + static char buf[CMSG_SPACE(sizeof(*ucred))]; + struct cmsghdr *cmsg; + + msg->msg_control = buf; + msg->msg_controllen = sizeof(buf); + cmsg = CMSG_FIRSTHDR(msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = CMSG_LEN(sizeof(*ucred)); + ucred = (struct ucred *)CMSG_DATA(cmsg); + ucred->pid = getpid(); + ucred->uid = getuid(); + ucred->gid = getgid(); + msg->msg_controllen = cmsg->cmsg_len; +} + int dc_handlewrite(void) { int ret; int errnobak; + struct msghdr msg; + struct iovec bufvec; switch(state) { case 1: if(queue->buflen > 0) { - ret = send(fd, queue->buf, queue->buflen, MSG_NOSIGNAL | MSG_DONTWAIT); + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &bufvec; + msg.msg_iovlen = 1; + bufvec.iov_base = queue->buf; + bufvec.iov_len = queue->buflen; + if((servinfo.family == PF_UNIX) && !servinfo.sentcreds) + { + mkcreds(&msg); + servinfo.sentcreds = 1; + } + ret = sendmsg(fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT); if(ret < 0) { if((errno == EAGAIN) || (errno == EINTR)) @@ -1108,7 +1144,8 @@ int dc_connect(char *host) fd = -1; } else { if(curhost->ai_canonname != NULL) - dchostname = sstrdup(curhost->ai_canonname); + servinfo.hostname = sstrdup(curhost->ai_canonname); + servinfo.family = curhost->ai_family; state = 1; break; } @@ -1190,5 +1227,5 @@ void dc_freeires(struct dc_intresp *ires) const char *dc_gethostname(void) { - return(dchostname); + return(servinfo.hostname); }