update for beta release
[framework/uifw/e17.git] / src / modules / mixer / msg.c
1 #include "pa.h"
2 #include <arpa/inet.h>
3 #include <sys/socket.h>
4 #include <unistd.h>
5
6 void
7 msg_recv_creds(Pulse *conn, Pulse_Tag *tag)
8 {
9 #ifdef __linux__
10    int r;
11    struct msghdr mh;
12    struct iovec iov;
13    union {
14        struct cmsghdr hdr;
15        uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
16    } cmsg;
17
18    memset(&iov, 0, sizeof(iov));
19    iov.iov_base = &tag->header[tag->pos];
20    iov.iov_len = sizeof(tag->header) - tag->pos;
21
22    memset(&cmsg, 0, sizeof(cmsg));
23    memset(&mh, 0, sizeof(mh));
24    mh.msg_iov = &iov;
25    mh.msg_iovlen = 1;
26    mh.msg_control = &cmsg;
27    mh.msg_controllen = sizeof(cmsg);
28
29    r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0);
30    if ((!r) || (r == sizeof(tag->header))) tag->auth = EINA_TRUE;
31    else if (r < 0)
32      {
33         if (errno != EAGAIN) ecore_main_fd_handler_del(conn->fdh);
34      }
35    else
36      {
37         DBG("%zu bytes left", sizeof(tag->header) - r);
38         tag->pos += r;
39      }
40 #else
41    conn = NULL;
42    tag = NULL;
43 #endif   
44 }
45
46 Eina_Bool
47 msg_recv(Pulse *conn, Pulse_Tag *tag)
48 {
49 #ifdef __linux__
50    long r;
51    struct msghdr mh;
52    struct iovec iov;
53    union {
54        struct cmsghdr hdr;
55        uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
56    } cmsg;
57
58    memset(&iov, 0, sizeof(iov));
59    iov.iov_base = tag->data + tag->pos;
60    iov.iov_len = tag->dsize - tag->pos;
61
62    memset(&cmsg, 0, sizeof(cmsg));
63    memset(&mh, 0, sizeof(mh));
64    mh.msg_iov = &iov;
65    mh.msg_iovlen = 1;
66    mh.msg_control = &cmsg;
67    mh.msg_controllen = sizeof(cmsg);
68
69    r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0);
70    DBG("recv %li bytes", r);
71    /* things we don't really care about: credentials */
72    if ((!r) || ((unsigned int)r == tag->dsize))
73      {
74         conn->iq = eina_list_remove(conn->iq, tag);
75         return EINA_TRUE;
76      }
77    else if (r < 0)
78      {
79         if (errno != EAGAIN) ecore_main_fd_handler_del(conn->fdh);
80      }
81    else
82      tag->pos += r;
83 #else
84    conn = NULL;
85    tag = NULL;
86 #endif   
87    return EINA_FALSE;
88 }
89
90 void
91 msg_sendmsg_creds(Pulse *conn, Pulse_Tag *tag)
92 {
93 #ifdef __linux__   
94    int r;
95    struct msghdr mh;
96    struct iovec iov;
97    union {
98        struct cmsghdr hdr;
99        uint8_t data[CMSG_SPACE(sizeof(struct ucred))];
100    } cmsg;
101    struct ucred *u;
102
103    memset(&iov, 0, sizeof(iov));
104    iov.iov_base = (void*) &tag->header[tag->pos];
105    iov.iov_len = sizeof(tag->header) - tag->pos;
106
107    memset(&cmsg, 0, sizeof(cmsg));
108    cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred));
109    cmsg.hdr.cmsg_level = SOL_SOCKET;
110    cmsg.hdr.cmsg_type = SCM_CREDENTIALS;
111
112    u = (struct ucred*) CMSG_DATA(&cmsg.hdr);
113
114    u->pid = getpid();
115    u->uid = getuid();
116    u->gid = getgid();
117
118    memset(&mh, 0, sizeof(mh));
119    mh.msg_iov = &iov;
120    mh.msg_iovlen = 1;
121    mh.msg_control = &cmsg;
122    mh.msg_controllen = sizeof(cmsg);
123
124    r = sendmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, MSG_NOSIGNAL);
125    if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE;
126    else if (r < 0)
127      {
128         if (errno != EAGAIN) ecore_main_fd_handler_del(conn->fdh);
129      }
130    else
131      tag->pos += r;
132 #else
133    conn = NULL;
134    tag = NULL;
135 #endif   
136 }
137
138 void
139 msg_send_creds(Pulse *conn, Pulse_Tag *tag)
140 {
141 #ifdef __linux__   
142    int r;
143
144    INF("trying to send 20 byte auth header");
145    r = send(ecore_main_fd_handler_fd_get(conn->fdh), &tag->header[tag->pos], sizeof(tag->header) - tag->pos, MSG_NOSIGNAL);
146    INF("%i bytes sent!", r);
147    if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE;
148    else if (r < 0)
149      {
150         if (errno != EAGAIN) ecore_main_fd_handler_del(conn->fdh);
151      }
152    else
153      tag->pos += r;
154 #else
155    conn = NULL;
156    tag = NULL;
157 #endif
158 }
159
160 Eina_Bool
161 msg_send(Pulse *conn, Pulse_Tag *tag)
162 {
163 #ifdef __linux__
164    int r;
165
166    INF("trying to send %zu bytes", tag->dsize - tag->pos);
167    r = send(ecore_main_fd_handler_fd_get(conn->fdh), tag->data + tag->pos, tag->dsize - tag->pos, MSG_NOSIGNAL);
168    INF("%i bytes sent!", r);
169    if ((!r) || ((unsigned int)r == tag->dsize - tag->pos))
170      {
171         DBG("Send complete! Deleting tag...");
172         conn->oq = eina_list_remove(conn->oq, tag);
173         pulse_tag_free(tag);
174         return EINA_TRUE;
175      }
176    if (r < 0)
177      {
178         if (errno != EAGAIN) ecore_main_fd_handler_del(conn->fdh);
179      }
180    else
181      tag->pos += r;
182 #else
183    conn = NULL;
184    tag = NULL;
185 #endif
186    return EINA_FALSE;
187 }