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 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 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 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 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