summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2014-03-06 11:15:29 +0000
committerChris Michael <cp.michael@samsung.com>2014-03-06 11:15:29 +0000
commit3d5f93a9cfb7aa92c8dc8e4848d885ceb824b269 (patch)
tree57466ca4a1232cff2fdbd87f6a53a920ae34255b /src/bin
parent8e30a4eeab1d5d60fc55feb9429d1f512b198465 (diff)
ecore-drm: Add code for SPARTACUS !! ;)
@ferature: This adds code for the ecore-drm auth process to open restricted inputs/cards/etc by the user. Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/ecore_drm/ecore_drm_launch.c407
1 files changed, 407 insertions, 0 deletions
diff --git a/src/bin/ecore_drm/ecore_drm_launch.c b/src/bin/ecore_drm/ecore_drm_launch.c
new file mode 100644
index 0000000000..14c3ad720a
--- /dev/null
+++ b/src/bin/ecore_drm/ecore_drm_launch.c
@@ -0,0 +1,407 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5/* standard headers */
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <string.h>
10#include <limits.h>
11#include <fcntl.h>
12#include <errno.h>
13#include <signal.h>
14#include <sys/types.h>
15#include <sys/socket.h>
16#include <sys/epoll.h>
17#include <sys/ioctl.h>
18/* #include <syslog.h> */
19/* #include <pwd.h> */
20
21/* #include <linux/major.h> */
22/* #include <linux/vt.h> */
23/* #include <linux/kd.h> */
24
25#include <xf86drm.h>
26#include <xf86drmMode.h>
27#include <drm_fourcc.h>
28
29#include <Eina.h>
30#include <Ecore_Drm.h>
31
32#define RIGHTS_LEN CMSG_LEN(sizeof(int))
33
34#define IOVSET(_iov, _addr, _len) \
35 (_iov)->iov_base = (void *)(_addr); \
36 (_iov)->iov_len = (_len);
37
38/* local prototypes */
39static int _send_msg(int opcode, int fd, void *data, size_t bytes);
40
41/* local variables */
42static struct cmsghdr *cmsgptr = NULL;
43static int _read_fd = -1;
44static int _write_fd = -1;
45
46static int
47_open_device(const char *device)
48{
49 int fd = -1, ret = ECORE_DRM_OP_SUCCESS;
50
51 if (!device)
52 {
53 ret = ECORE_DRM_OP_FAILURE;
54 _send_msg(ECORE_DRM_OP_DEVICE_OPEN, fd, &ret, sizeof(int));
55 return ret;
56 }
57
58 fprintf(stderr, "Launcher Trying to Open Device: %s\n", device);
59
60 if ((fd = open(device, O_RDWR | O_NONBLOCK)) < 0)
61 {
62 fprintf(stderr, "Failed to Open Device: %s: %m\n", device);
63 ret = ECORE_DRM_OP_FAILURE;
64 }
65 else
66 fprintf(stderr, "Launcher Opened Device: %s %d\n", device, fd);
67
68 _send_msg(ECORE_DRM_OP_DEVICE_OPEN, fd, &ret, sizeof(int));
69
70 return ret;
71}
72
73static int
74_close_device(int fd)
75{
76 int ret = ECORE_DRM_OP_SUCCESS;
77
78 if (!fd)
79 {
80 ret = ECORE_DRM_OP_FAILURE;
81 _send_msg(ECORE_DRM_OP_DEVICE_CLOSE, fd, &ret, sizeof(int));
82 return ret;
83 }
84
85 close(fd);
86
87 _send_msg(ECORE_DRM_OP_DEVICE_CLOSE, fd, &ret, sizeof(int));
88
89 return ret;
90}
91
92static int
93_open_tty(const char *name)
94{
95 int fd = -1, ret = ECORE_DRM_OP_SUCCESS;
96 /* struct stat st; */
97
98 if (!name) goto fail;
99
100 fprintf(stderr, "Launcher Trying to Open Tty: %s\n", name);
101
102 if ((fd = open(name, O_RDWR | O_NOCTTY)) < 0)
103 {
104 fprintf(stderr, "Failed to Open Tty: %s: %m\n", name);
105 goto fail;
106 }
107 else
108 fprintf(stderr, "Launcher Opened Tty: %s %d\n", name, fd);
109
110 /* if ((fstat(fd, &st) == -1) || */
111 /* (major(st.st_rdev) != TTY_MAJOR) || (minor(st.st_rdev) == 0)) */
112 /* { */
113 /* fprintf(stderr, "%d is Not a Tty\n", fd); */
114 /* goto fail; */
115 /* } */
116
117 _send_msg(ECORE_DRM_OP_TTY_OPEN, fd, &ret, sizeof(int));
118
119 return ret;
120
121fail:
122 if (fd > -1) close(fd);
123 fd = -1;
124 ret = ECORE_DRM_OP_FAILURE;
125 _send_msg(ECORE_DRM_OP_DEVICE_OPEN, fd, &ret, sizeof(int));
126 return ret;
127}
128
129static int
130_drop_master(int fd)
131{
132 int ret = ECORE_DRM_OP_SUCCESS;
133
134 fprintf(stderr, "Drop Master: %d\n", fd);
135
136 if (drmDropMaster(fd) != 0)
137 {
138 ret = ECORE_DRM_OP_FAILURE;
139 fprintf(stderr, "\tFailed to drop master: %m\n");
140 }
141
142 _send_msg(ECORE_DRM_OP_DEVICE_MASTER_DROP, fd, &ret, sizeof(int));
143
144 close(fd);
145
146 return ret;
147}
148
149static int
150_set_master(int fd)
151{
152 int ret = ECORE_DRM_OP_SUCCESS;
153
154 fprintf(stderr, "Set Master: %d\n", fd);
155
156 if (drmSetMaster(fd) != 0)
157 {
158 ret = ECORE_DRM_OP_FAILURE;
159 fprintf(stderr, "\tFailed to set master: %m\n");
160 }
161
162 _send_msg(ECORE_DRM_OP_DEVICE_MASTER_SET, fd, &ret, sizeof(int));
163
164 close(fd);
165
166 return ret;
167}
168
169static int
170_read_fd_get(void)
171{
172 char *ev, *end;
173 int fd = -1, flags = -1;
174
175 if (!(ev = getenv("ECORE_DRM_LAUNCHER_SOCKET_READ")))
176 return -1;
177
178 fd = strtol(ev, &end, 0);
179 if (*end != '\0') return -1;
180
181 flags = fcntl(fd, F_GETFD);
182 if (flags < 0) return -1;
183
184 fprintf(stderr, "Got Read FD: %d\n", fd);
185
186 return fd;
187}
188
189static int
190_write_fd_get(void)
191{
192 char *ev, *end;
193 int fd = -1, flags = -1;
194
195 if (!(ev = getenv("ECORE_DRM_LAUNCHER_SOCKET_WRITE")))
196 return -1;
197
198 fd = strtol(ev, &end, 0);
199 if (*end != '\0') return -1;
200
201 flags = fcntl(fd, F_GETFD);
202 if (flags < 0) return -1;
203
204 fprintf(stderr, "Got Write FD: %d\n", fd);
205
206 return fd;
207}
208
209static int
210_send_msg(int opcode, int fd, void *data, size_t bytes)
211{
212 Ecore_Drm_Message dmsg;
213 struct iovec iov[2];
214 struct msghdr msg;
215 ssize_t size;
216
217 /* send a message to the calling process */
218 /* 'fd' is the fd to send */
219
220 memset(&dmsg, 0, sizeof(dmsg));
221
222 IOVSET(iov + 0, &dmsg, sizeof(dmsg));
223 IOVSET(iov + 1, &data, bytes);
224
225 dmsg.opcode = opcode;
226 dmsg.size = bytes;
227
228 msg.msg_name = NULL;
229 msg.msg_namelen = 0;
230 msg.msg_iov = iov;
231 msg.msg_iovlen = 2;
232 msg.msg_flags = 0;
233
234 if ((!cmsgptr) && (!(cmsgptr = malloc(RIGHTS_LEN))))
235 return -1;
236
237 cmsgptr->cmsg_level = SOL_SOCKET;
238 cmsgptr->cmsg_type = SCM_RIGHTS;
239 cmsgptr->cmsg_len = RIGHTS_LEN;
240
241 msg.msg_control = cmsgptr;
242 msg.msg_controllen = RIGHTS_LEN;
243
244 fprintf(stderr, "Launcher Sending FD: %d\n", fd);
245 *((int *)CMSG_DATA(cmsgptr)) = fd;
246
247 errno = 0;
248 size = sendmsg(_write_fd, &msg, MSG_EOR);
249 if (errno != 0)
250 {
251 fprintf(stderr, "Failed to send message: %s", strerror(errno));
252 return -1;
253 }
254
255 fprintf(stderr, "Launcher Wrote %li to %d\n", size, _write_fd);
256
257 return size;
258}
259
260static int
261_recv_msg(void)
262{
263 int fd = -1;
264 Ecore_Drm_Message dmsg;
265 struct iovec iov[2];
266 struct msghdr msg;
267 struct cmsghdr *cmsg = NULL;
268 char data[BUFSIZ];
269 ssize_t size;
270
271 fprintf(stderr, "Received Message\n");
272
273 memset(&dmsg, 0, sizeof(dmsg));
274 memset(&data, 0, sizeof(data));
275
276 IOVSET(iov + 0, &dmsg, sizeof(dmsg));
277 IOVSET(iov + 1, &data, sizeof(data));
278
279 msg.msg_name = NULL;
280 msg.msg_namelen = 0;
281 msg.msg_iov = iov;
282 msg.msg_iovlen = 2;
283 msg.msg_flags = 0;
284
285 if ((!cmsgptr) && (!(cmsgptr = malloc(RIGHTS_LEN))))
286 return -1;
287
288 msg.msg_control = cmsgptr;
289 msg.msg_controllen = RIGHTS_LEN;
290
291 errno = 0;
292 size = recvmsg(_read_fd, &msg, 0);
293 if (errno != 0)
294 {
295 fprintf(stderr, "Failed to receive message: %m\n");
296 return -1;
297 }
298
299 fprintf(stderr, "\tReceived %li bytes from %d\n", size, _read_fd);
300
301 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
302 cmsg = CMSG_NXTHDR(&msg, cmsg))
303 {
304 if (cmsg->cmsg_level != SOL_SOCKET)
305 continue;
306
307 switch (cmsg->cmsg_type)
308 {
309 case SCM_RIGHTS:
310 fd = *((int *)CMSG_DATA(cmsg));
311 switch (dmsg.opcode)
312 {
313 case ECORE_DRM_OP_DEVICE_OPEN:
314 fprintf(stderr, "Open Device: %s\n", (char *)data);
315 _open_device((char *)data);
316 break;
317 case ECORE_DRM_OP_DEVICE_CLOSE:
318 fprintf(stderr, "Close Device: %d\n", fd);
319 _close_device(fd);
320 case ECORE_DRM_OP_TTY_OPEN:
321 fprintf(stderr, "Open Tty: %s\n", (char *)data);
322 _open_tty((char *)data);
323 break;
324 case ECORE_DRM_OP_DEVICE_MASTER_DROP:
325 fprintf(stderr, "Drop Master: %d\n", fd);
326 _drop_master(fd);
327 break;
328 case ECORE_DRM_OP_DEVICE_MASTER_SET:
329 fprintf(stderr, "Set Master\n");
330 _set_master(fd);
331 break;
332 default:
333 fprintf(stderr, "Unhandled Opcode: %d\n", dmsg.opcode);
334 break;
335 }
336 break;
337 default:
338 fprintf(stderr, "Unhandled message type: %d\n", cmsg->cmsg_type);
339 return -1;
340 break;
341 }
342 }
343
344 return size;
345}
346
347int
348main(int argc EINA_UNUSED, char **argv EINA_UNUSED)
349{
350 struct epoll_event ev, events[1];
351 int ret, i, _epoll_fd = -1;
352
353 setvbuf(stdout, NULL, _IONBF, 0);
354 setvbuf(stderr, NULL, _IONBF, 0);
355
356 fprintf(stderr, "Spartacus Is Alive\n");
357
358 _read_fd = _read_fd_get();
359 if (_read_fd < 0) return EXIT_FAILURE;
360
361 _write_fd = _write_fd_get();
362 if (_write_fd < 0) return EXIT_FAILURE;
363
364 fprintf(stderr, "Creating Epoll\n");
365 _epoll_fd = epoll_create(1);
366
367 memset(&ev, 0, sizeof(ev));
368 ev.events = EPOLLIN;
369 ev.data.fd = _read_fd;
370
371 if (epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, _read_fd, &ev) < 0)
372 {
373 return EXIT_FAILURE;
374 }
375
376 memset(&events, 0, sizeof(events));
377
378 while (1)
379 {
380 ret = epoll_wait(_epoll_fd, events, sizeof(events) / sizeof(struct epoll_event), -1);
381 if (ret < 0)
382 {
383 fprintf(stderr, "Epoll Failed: %m\n");
384 return EXIT_FAILURE;
385 }
386
387 for (i = 0; i < ret; i++)
388 {
389 fprintf(stderr, "Epoll Event on: %d\n", events[i].data.fd);
390 if (events[i].data.fd != _read_fd) continue;
391
392 if (events[i].events & EPOLLIN)
393 {
394 fprintf(stderr, "Epoll Data In\n");
395 _recv_msg();
396 }
397 else if (events[i].events & EPOLLERR)
398 {
399 fprintf(stderr, "Epoll Data Error\n");
400 }
401 }
402 }
403
404 fprintf(stderr, "Spartacus Is Dead\n");
405
406 return EXIT_SUCCESS;
407}