enlightenment/src/modules/mixer/msg.c

208 lines
4.6 KiB
C

#include "pa.h"
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
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 * sizeof(tag->header[0])), 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;
}