1 /*
2  * Copyright (c) 2011 Kilian Klimek <kilian.klimek@gmail.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 #include <stdio.h>
17 #include <string.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <unistd.h>
22 
23 #include "socket.h"
24 #include "commands.h"
25 
26 #define VITUNES_SOCK    "/tmp/.vitunes"
27 
28 
29 int
sock_send_msg(const char * msg)30 sock_send_msg(const char *msg)
31 {
32    int                  ret;
33    struct sockaddr_un   addr;
34    socklen_t            addr_len;
35 
36 
37    if((ret = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
38       return -1;
39 
40    addr.sun_family = AF_UNIX;
41    strcpy(addr.sun_path, VITUNES_SOCK);
42    addr_len = sizeof(addr.sun_family) + strlen(VITUNES_SOCK) + 1;
43 
44    if(sendto(ret, msg, strlen(msg), 0, (struct sockaddr *) &addr, addr_len) == -1) {
45       close(ret);
46       return -1;
47    }
48 
49    return 0;
50 }
51 
52 
53 int
sock_listen(void)54 sock_listen(void)
55 {
56    int                  ret;
57    struct sockaddr_un   addr;
58    socklen_t            addr_len;
59    int                  coe = 1;
60 
61    unlink(VITUNES_SOCK);
62 
63    if((ret = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
64       return -1;
65 
66    addr.sun_family = AF_UNIX;
67    strcpy(addr.sun_path, VITUNES_SOCK);
68    addr_len = sizeof(addr.sun_family) + strlen(VITUNES_SOCK) + 1;
69 
70    if(bind(ret, (struct sockaddr *) &addr, addr_len) == -1)
71       return -1;
72 
73    fcntl(ret, F_SETFD, FD_CLOEXEC, &coe);
74 
75    return ret;
76 }
77 
78 
79 ssize_t
sock_recv_msg(int sock,char * msg,size_t msg_len)80 sock_recv_msg(int sock, char *msg, size_t msg_len)
81 {
82    struct sockaddr_un   addr;
83    socklen_t            addr_len = sizeof(struct sockaddr_un);
84    ssize_t              ret;
85 
86    ret = recvfrom(sock, msg, msg_len, 0, (struct sockaddr *) &addr, &addr_len);
87 
88    if(ret > -1)
89       msg[ret] = '\0';
90 
91    return ret;
92 }
93 
94 
95 void
sock_recv_and_exec(int sock)96 sock_recv_and_exec(int sock)
97 {
98    char   msg[64];
99 
100    if(sock_recv_msg(sock, msg, sizeof(msg)) == -1)
101       return;
102 
103    if(!strcmp(msg, VITUNES_RUNNING))
104       return;
105 
106    if(!kb_execute_by_name(msg))
107       cmd_execute(msg);
108 }
109