#include "pa.h" #include #include #include void msg_recv_creds(Pulse *conn, Pulse_Tag *tag) { #ifdef __linux__ int r; struct msghdr mh; struct iovec iov; union { struct cmsghdr hdr; uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; } cmsg; memset(&iov, 0, sizeof(iov)); iov.iov_base = &tag->header[tag->pos]; iov.iov_len = sizeof(tag->header) - tag->pos; memset(&cmsg, 0, sizeof(cmsg)); memset(&mh, 0, sizeof(mh)); mh.msg_iov = &iov; mh.msg_iovlen = 1; mh.msg_control = &cmsg; mh.msg_controllen = sizeof(cmsg); r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0); if ((!r) || (r == sizeof(tag->header))) tag->auth = EINA_TRUE; else if (r < 0) { if (errno != EAGAIN) { ERR("%d: %s", errno, strerror(errno)); pulse_disconnect(conn); } } else { DBG("%zu bytes left", sizeof(tag->header) - r); tag->pos += r; } #else conn = NULL; tag = NULL; #endif } Eina_Bool msg_recv(Pulse *conn, Pulse_Tag *tag) { #ifdef __linux__ long r; struct msghdr mh; struct iovec iov; union { struct cmsghdr hdr; uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; } cmsg; memset(&iov, 0, sizeof(iov)); iov.iov_base = tag->data + tag->pos; iov.iov_len = tag->dsize - tag->pos; memset(&cmsg, 0, sizeof(cmsg)); memset(&mh, 0, sizeof(mh)); mh.msg_iov = &iov; mh.msg_iovlen = 1; mh.msg_control = &cmsg; mh.msg_controllen = sizeof(cmsg); r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0); DBG("recv %li bytes", r); /* things we don't really care about: credentials */ if ((!r) || ((unsigned int)r == tag->dsize)) { conn->iq = eina_list_remove(conn->iq, tag); return EINA_TRUE; } else if (r < 0) { if (errno != EAGAIN) { ERR("%d: %s", errno, strerror(errno)); pulse_disconnect(conn); } } else tag->pos += r; #else conn = NULL; tag = NULL; #endif return EINA_FALSE; } void msg_sendmsg_creds(Pulse *conn, Pulse_Tag *tag) { #ifdef __linux__ int r; struct msghdr mh; struct iovec iov; union { struct cmsghdr hdr; uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; } cmsg; struct ucred *u; memset(&iov, 0, sizeof(iov)); iov.iov_base = (void*) &tag->header[tag->pos]; iov.iov_len = sizeof(tag->header) - tag->pos; memset(&cmsg, 0, sizeof(cmsg)); cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)); cmsg.hdr.cmsg_level = SOL_SOCKET; cmsg.hdr.cmsg_type = SCM_CREDENTIALS; u = (struct ucred*) CMSG_DATA(&cmsg.hdr); u->pid = getpid(); u->uid = getuid(); u->gid = getgid(); memset(&mh, 0, sizeof(mh)); mh.msg_iov = &iov; mh.msg_iovlen = 1; mh.msg_control = &cmsg; mh.msg_controllen = sizeof(cmsg); r = sendmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, MSG_NOSIGNAL); if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE; else if (r < 0) { if (errno != EAGAIN) { ERR("%d: %s", errno, strerror(errno)); pulse_disconnect(conn); } } else tag->pos += r; #else conn = NULL; tag = NULL; #endif } void msg_send_creds(Pulse *conn, Pulse_Tag *tag) { #ifdef __linux__ int r; INF("trying to send 20 byte auth header"); r = send(ecore_main_fd_handler_fd_get(conn->fdh), &tag->header[tag->pos], sizeof(tag->header) - tag->pos, MSG_NOSIGNAL); INF("%i bytes sent!", r); if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE; else if (r < 0) { if (errno != EAGAIN) { ERR("%d: %s", errno, strerror(errno)); pulse_disconnect(conn); } } else tag->pos += r; #else conn = NULL; tag = NULL; #endif } Eina_Bool msg_send(Pulse *conn, Pulse_Tag *tag) { #ifdef __linux__ int r; INF("trying to send %zu bytes", tag->dsize - tag->pos); r = send(ecore_main_fd_handler_fd_get(conn->fdh), tag->data + tag->pos, tag->dsize - tag->pos, MSG_NOSIGNAL); INF("%i bytes sent!", r); if ((!r) || ((unsigned int)r == tag->dsize - tag->pos)) { DBG("Send complete! Deleting tag..."); conn->oq = eina_list_remove(conn->oq, tag); pulse_tag_free(tag); return EINA_TRUE; } if (r < 0) { if (errno != EAGAIN) { ERR("%d: %s", errno, strerror(errno)); pulse_disconnect(conn); } } else tag->pos += r; #else conn = NULL; tag = NULL; #endif return EINA_FALSE; }