1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <sys/un.h>
9 #include <errno.h>
10
11 #include "ipcsocket.h"
12
13
opensocket(int * sockfd,const char * name,int connecttype)14 int opensocket(int *sockfd, const char *name, int connecttype)
15 {
16 int ret, temp = 1;
17
18 if (!name || strlen(name) > MAX_SOCK_NAME_LEN) {
19 fprintf(stderr, "<%s>: Invalid socket name.\n", __func__);
20 return -1;
21 }
22
23 ret = socket(PF_LOCAL, SOCK_STREAM, 0);
24 if (ret < 0) {
25 fprintf(stderr, "<%s>: Failed socket: <%s>\n",
26 __func__, strerror(errno));
27 return ret;
28 }
29
30 *sockfd = ret;
31 if (setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR,
32 (char *)&temp, sizeof(int)) < 0) {
33 fprintf(stderr, "<%s>: Failed setsockopt: <%s>\n",
34 __func__, strerror(errno));
35 goto err;
36 }
37
38 sprintf(sock_name, "/tmp/%s", name);
39
40 if (connecttype == 1) {
41 /* This is for Server connection */
42 struct sockaddr_un skaddr;
43 int clientfd;
44 socklen_t sklen;
45
46 unlink(sock_name);
47 memset(&skaddr, 0, sizeof(skaddr));
48 skaddr.sun_family = AF_LOCAL;
49 strcpy(skaddr.sun_path, sock_name);
50
51 ret = bind(*sockfd, (struct sockaddr *)&skaddr,
52 SUN_LEN(&skaddr));
53 if (ret < 0) {
54 fprintf(stderr, "<%s>: Failed bind: <%s>\n",
55 __func__, strerror(errno));
56 goto err;
57 }
58
59 ret = listen(*sockfd, 5);
60 if (ret < 0) {
61 fprintf(stderr, "<%s>: Failed listen: <%s>\n",
62 __func__, strerror(errno));
63 goto err;
64 }
65
66 memset(&skaddr, 0, sizeof(skaddr));
67 sklen = sizeof(skaddr);
68
69 ret = accept(*sockfd, (struct sockaddr *)&skaddr,
70 (socklen_t *)&sklen);
71 if (ret < 0) {
72 fprintf(stderr, "<%s>: Failed accept: <%s>\n",
73 __func__, strerror(errno));
74 goto err;
75 }
76
77 clientfd = ret;
78 *sockfd = clientfd;
79 } else {
80 /* This is for client connection */
81 struct sockaddr_un skaddr;
82
83 memset(&skaddr, 0, sizeof(skaddr));
84 skaddr.sun_family = AF_LOCAL;
85 strcpy(skaddr.sun_path, sock_name);
86
87 ret = connect(*sockfd, (struct sockaddr *)&skaddr,
88 SUN_LEN(&skaddr));
89 if (ret < 0) {
90 fprintf(stderr, "<%s>: Failed connect: <%s>\n",
91 __func__, strerror(errno));
92 goto err;
93 }
94 }
95
96 return 0;
97
98 err:
99 if (*sockfd)
100 close(*sockfd);
101
102 return ret;
103 }
104
sendtosocket(int sockfd,struct socketdata * skdata)105 int sendtosocket(int sockfd, struct socketdata *skdata)
106 {
107 int ret, buffd;
108 unsigned int len;
109 char cmsg_b[CMSG_SPACE(sizeof(int))];
110 struct cmsghdr *cmsg;
111 struct msghdr msgh;
112 struct iovec iov;
113 struct timeval timeout;
114 fd_set selFDs;
115
116 if (!skdata) {
117 fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
118 return -1;
119 }
120
121 FD_ZERO(&selFDs);
122 FD_SET(0, &selFDs);
123 FD_SET(sockfd, &selFDs);
124 timeout.tv_sec = 20;
125 timeout.tv_usec = 0;
126
127 ret = select(sockfd+1, NULL, &selFDs, NULL, &timeout);
128 if (ret < 0) {
129 fprintf(stderr, "<%s>: Failed select: <%s>\n",
130 __func__, strerror(errno));
131 return -1;
132 }
133
134 if (FD_ISSET(sockfd, &selFDs)) {
135 buffd = skdata->data;
136 len = skdata->len;
137 memset(&msgh, 0, sizeof(msgh));
138 msgh.msg_control = &cmsg_b;
139 msgh.msg_controllen = CMSG_LEN(len);
140 iov.iov_base = "OK";
141 iov.iov_len = 2;
142 msgh.msg_iov = &iov;
143 msgh.msg_iovlen = 1;
144 cmsg = CMSG_FIRSTHDR(&msgh);
145 cmsg->cmsg_level = SOL_SOCKET;
146 cmsg->cmsg_type = SCM_RIGHTS;
147 cmsg->cmsg_len = CMSG_LEN(len);
148 memcpy(CMSG_DATA(cmsg), &buffd, len);
149
150 ret = sendmsg(sockfd, &msgh, MSG_DONTWAIT);
151 if (ret < 0) {
152 fprintf(stderr, "<%s>: Failed sendmsg: <%s>\n",
153 __func__, strerror(errno));
154 return -1;
155 }
156 }
157
158 return 0;
159 }
160
receivefromsocket(int sockfd,struct socketdata * skdata)161 int receivefromsocket(int sockfd, struct socketdata *skdata)
162 {
163 int ret, buffd;
164 unsigned int len = 0;
165 char cmsg_b[CMSG_SPACE(sizeof(int))];
166 struct cmsghdr *cmsg;
167 struct msghdr msgh;
168 struct iovec iov;
169 fd_set recvFDs;
170 char data[32];
171
172 if (!skdata) {
173 fprintf(stderr, "<%s>: socketdata is NULL\n", __func__);
174 return -1;
175 }
176
177 FD_ZERO(&recvFDs);
178 FD_SET(0, &recvFDs);
179 FD_SET(sockfd, &recvFDs);
180
181 ret = select(sockfd+1, &recvFDs, NULL, NULL, NULL);
182 if (ret < 0) {
183 fprintf(stderr, "<%s>: Failed select: <%s>\n",
184 __func__, strerror(errno));
185 return -1;
186 }
187
188 if (FD_ISSET(sockfd, &recvFDs)) {
189 len = sizeof(buffd);
190 memset(&msgh, 0, sizeof(msgh));
191 msgh.msg_control = &cmsg_b;
192 msgh.msg_controllen = CMSG_LEN(len);
193 iov.iov_base = data;
194 iov.iov_len = sizeof(data)-1;
195 msgh.msg_iov = &iov;
196 msgh.msg_iovlen = 1;
197 cmsg = CMSG_FIRSTHDR(&msgh);
198 cmsg->cmsg_level = SOL_SOCKET;
199 cmsg->cmsg_type = SCM_RIGHTS;
200 cmsg->cmsg_len = CMSG_LEN(len);
201
202 ret = recvmsg(sockfd, &msgh, MSG_DONTWAIT);
203 if (ret < 0) {
204 fprintf(stderr, "<%s>: Failed recvmsg: <%s>\n",
205 __func__, strerror(errno));
206 return -1;
207 }
208
209 memcpy(&buffd, CMSG_DATA(cmsg), len);
210 skdata->data = buffd;
211 skdata->len = len;
212 }
213 return 0;
214 }
215
closesocket(int sockfd,char * name)216 int closesocket(int sockfd, char *name)
217 {
218 char sockname[MAX_SOCK_NAME_LEN];
219
220 if (sockfd)
221 close(sockfd);
222 sprintf(sockname, "/tmp/%s", name);
223 unlink(sockname);
224 shutdown(sockfd, 2);
225
226 return 0;
227 }
228