blob: 12e182288920c75ba4977c5686c687f22a04bcc2 [file] [log] [blame]
lhf4a45922022-02-17 22:08:54 -08001/* SPDX-License-Identifier: MediaTekProprietary */
xjb04a4022021-11-25 15:01:52 +08002
3#include <stdio.h>
4#include <stdlib.h>
5#include <stddef.h>
6#include <string.h>
7#include <errno.h>
8#include <assert.h>
9#include <unistd.h>
10#include <fcntl.h>
11#include <time.h>
12#include <sys/types.h>
13#include <sys/socket.h>
14#include <sys/un.h>
15#include <syslog.h>
16#include "property.h"
17#include "utility.h"
18#include "request.h"
19
20/*******************************************************************************/
21/* REQUEST local definitions */
22/*******************************************************************************/
23
24/*******************************************************************************/
25/* REQUEST local prototypes */
26/*******************************************************************************/
27
28/*******************************************************************************/
29/* REQUEST local variables */
30/*******************************************************************************/
31
32/*******************************************************************************/
33/* REQUEST local functions */
34/*******************************************************************************/
35static int pack_request_string(char **p, char **next, const char *roof)
36{
37 if (*p == NULL) {
38 return 0;
39 } else {
40 size_t len = strlen(*p) + 1;
41
42 if ((roof - *next) < (ptrdiff_t)len) {
43 return -1;
44 } else {
45 strcpy(*next, *p);
46 *next += len;
47 *p = (char *)0x12345678;
48 return 0;
49 }
50 }
51}
52
53static int unpack_request_string(char **p, char **next, const char *roof)
54{
55 if (*p == NULL) {
56 return 0;
57 } else if (*p == (char *)0x12345678) {
58 char *end = memchr(*next, '\0', roof - *next);
59
60 if (end == NULL) {
61 return -1;
62 } else {
63 *p = *next;
64 *next = end + 1;
65 return 0;
66 }
67 }
68 return -1;
69}
70
71/*******************************************************************************/
72/* REQUEST functions */
73/*******************************************************************************/
74int pack_request(struct sncfg_request *request)
75{
76 int size;
77 char *next, *roof;
78
79 next = request->string + request->reservedLen;
80 roof = next + sizeof(request->string);
81
82 if (request->magic != SNCFG_REQUEST_MAGIC) {
83 return -1;
84 }
85
86 if (request->type >= SNCFG_REQUEST_TYPE_RESERVED) {
87 return -1;
88 }
89
90 if (pack_request_string(&request->key, &next, roof) < 0 ||
91 pack_request_string(&request->value, &next, roof) < 0) {
92 return -1;
93 }
94
95 size = next - (char *)request;
96 return size;
97}
98
99int unpack_request(struct sncfg_request *request, int size)
100{
101 char *next, *roof;
102
103 next = request->string + request->reservedLen;
104 roof = (char *)request + size;
105
106 if (roof < next) {
107 return -1;
108 }
109
110 if (request->magic != SNCFG_REQUEST_MAGIC) {
111 return -1;
112 }
113
114 if (request->type >= SNCFG_REQUEST_TYPE_RESERVED) {
115 return -1;
116 }
117
118 if (unpack_request_string(&request->key, &next, roof) < 0 ||
119 unpack_request_string(&request->value, &next, roof) < 0) {
120 return -1;
121 }
122
123 return 0;
124}
125
126int connect_request(void)
127{
128 int sock;
129 struct sockaddr_un addr = { AF_UNIX, SNCFG_REQUEST_UNIX_SOCKET };
130
131 if (access(addr.sun_path, R_OK | W_OK) < 0) {
132 return -1;
133 }
134
135 sock = socket(AF_UNIX, SOCK_STREAM, 0);
136 if (sock == -1) {
137 return -1;
138 }
139
140 struct timeval tm;
141 tm.tv_sec = 8; /* 8 Secs Timeout */
142 tm.tv_usec = 0;
143
144 if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
145 fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for connect ... %s !!\r\n", getpid(), strerror(errno));
146 syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for connect ... %s !!", getpid(), strerror(errno));
147 close(sock);
148 return -1;
149 }
150 if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
151 fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for connect ... %s !!\r\n", getpid(), strerror(errno));
152 syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for connect ... %s !!", getpid(), strerror(errno));
153 close(sock);
154 return -1;
155 }
156
157 if (connect(sock, (struct sockaddr *)&addr,
158 offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path)) < 0) {
159 close(sock);
160 return -1;
161 }
162
163 return sock;
164}
165
166int accept_request(int sockfd)
167{
168 int sock;
169 socklen_t addrlen;
170 struct sockaddr_un addr;
171
172 addrlen = sizeof(addr);
173 sock = accept(sockfd, (struct sockaddr *)&addr, &addrlen);
174 if (sock == -1) {
175 return -1;
176 }
177
178 if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) {
179 close(sock);
180 return -1;
181 }
182
183 struct timeval tm;
184 tm.tv_sec = 8; /* 8 Secs Timeout */
185 tm.tv_usec = 0;
186
187 if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
188 fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for accept ... %s !!\r\n", getpid(), strerror(errno));
189 syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_SNDTIMEO 8 seconds for accept ... %s !!", getpid(), strerror(errno));
190 close(sock);
191 return -1;
192 }
193 if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tm, sizeof(tm)) < 0) {
194 fprintf(stderr, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for accept ... %s !!\r\n", getpid(), strerror(errno));
195 syslog(LOG_WARNING, "[LIBSNCFG][%d] Can't setsockopt SO_RCVTIMEO 8 seconds for accept ... %s !!", getpid(), strerror(errno));
196 close(sock);
197 return -1;
198 }
199
200 return sock;
201}
202
203int request_for_sncfg(struct sncfg_request *request)
204{
205 int sock, size;
206
207 size = pack_request(request);
208 if (size < 0) {
209 return -1;
210 }
211
212 sock = connect_request();
213 if (sock < 0) {
214 return -1;
215 }
216
217 if (safe_write(sock, request, size) != size) {
218 close(sock);
219 return -1;
220 }
221
222 size = safe_read(sock, request, sizeof(struct sncfg_request));
223
224 if (size < 0 ||
225 unpack_request(request, size) < 0 ||
226 request->status < 0) {
227 /* request processing failed */
228 close(sock);
229 return -1;
230 }
231
232 close(sock);
233 return 0;
234}