summaryrefslogtreecommitdiffstats
path: root/libusbmuxd/sock_stuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'libusbmuxd/sock_stuff.c')
-rw-r--r--libusbmuxd/sock_stuff.c370
1 files changed, 0 insertions, 370 deletions
diff --git a/libusbmuxd/sock_stuff.c b/libusbmuxd/sock_stuff.c
deleted file mode 100644
index edc738e..0000000
--- a/libusbmuxd/sock_stuff.c
+++ /dev/null
@@ -1,370 +0,0 @@
1/*
2 libusbmuxd - client library to talk to usbmuxd
3
4Copyright (C) 2009 Nikias Bassen <nikias@gmx.li>
5Copyright (C) 2009 Paul Sladen <libiphone@paul.sladen.org>
6Copyright (C) 2009 Martin Szulecki <opensuse@sukimashita.com>
7
8This library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as
10published by the Free Software Foundation, either version 2.1 of the
11License, or (at your option) any later version.
12
13This library is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU Lesser General Public
19License along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22*/
23
24#include <stdio.h>
25#include <stddef.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29#include <errno.h>
30#include <sys/time.h>
31#include <sys/stat.h>
32#ifdef WIN32
33#include <windows.h>
34#include <winsock2.h>
35static int wsa_init = 0;
36#else
37#include <sys/socket.h>
38#include <sys/un.h>
39#include <netinet/in.h>
40#include <netdb.h>
41#include <arpa/inet.h>
42#endif
43#include "sock_stuff.h"
44
45#define RECV_TIMEOUT 20000
46
47static int verbose = 0;
48
49void sock_stuff_set_verbose(int level)
50{
51 verbose = level;
52}
53
54#ifndef WIN32
55int create_unix_socket(const char *filename)
56{
57 struct sockaddr_un name;
58 int sock;
59 size_t size;
60
61 // remove if still present
62 unlink(filename);
63
64 /* Create the socket. */
65 sock = socket(PF_LOCAL, SOCK_STREAM, 0);
66 if (sock < 0) {
67 perror("socket");
68 return -1;
69 }
70
71 /* Bind a name to the socket. */
72 name.sun_family = AF_LOCAL;
73 strncpy(name.sun_path, filename, sizeof(name.sun_path));
74 name.sun_path[sizeof(name.sun_path) - 1] = '\0';
75
76 /* The size of the address is
77 the offset of the start of the filename,
78 plus its length,
79 plus one for the terminating null byte.
80 Alternatively you can just do:
81 size = SUN_LEN (&name);
82 */
83 size = (offsetof(struct sockaddr_un, sun_path)
84 + strlen(name.sun_path) + 1);
85
86 if (bind(sock, (struct sockaddr *) &name, size) < 0) {
87 perror("bind");
88 close_socket(sock);
89 return -1;
90 }
91
92 if (listen(sock, 10) < 0) {
93 perror("listen");
94 close_socket(sock);
95 return -1;
96 }
97
98 return sock;
99}
100
101int connect_unix_socket(const char *filename)
102{
103 struct sockaddr_un name;
104 int sfd = -1;
105 size_t size;
106 struct stat fst;
107
108 // check if socket file exists...
109 if (stat(filename, &fst) != 0) {
110 if (verbose >= 2)
111 fprintf(stderr, "%s: stat '%s': %s\n", __func__, filename,
112 strerror(errno));
113 return -1;
114 }
115 // ... and if it is a unix domain socket
116 if (!S_ISSOCK(fst.st_mode)) {
117 if (verbose >= 2)
118 fprintf(stderr, "%s: File '%s' is not a socket!\n", __func__,
119 filename);
120 return -1;
121 }
122 // make a new socket
123 if ((sfd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
124 if (verbose >= 2)
125 fprintf(stderr, "%s: socket: %s\n", __func__, strerror(errno));
126 return -1;
127 }
128 // and connect to 'filename'
129 name.sun_family = AF_LOCAL;
130 strncpy(name.sun_path, filename, sizeof(name.sun_path));
131 name.sun_path[sizeof(name.sun_path) - 1] = 0;
132
133 size = (offsetof(struct sockaddr_un, sun_path)
134 + strlen(name.sun_path) + 1);
135
136 if (connect(sfd, (struct sockaddr *) &name, size) < 0) {
137 close_socket(sfd);
138 if (verbose >= 2)
139 fprintf(stderr, "%s: connect: %s\n", __func__,
140 strerror(errno));
141 return -1;
142 }
143
144 return sfd;
145}
146#endif
147
148int create_socket(uint16_t port)
149{
150 int sfd = -1;
151 int yes = 1;
152#ifdef WIN32
153 WSADATA wsa_data;
154 if (!wsa_init) {
155 if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
156 fprintf(stderr, "WSAStartup failed!\n");
157 ExitProcess(-1);
158 }
159 wsa_init = 1;
160 }
161#endif
162 struct sockaddr_in saddr;
163
164 if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
165 perror("socket()");
166 return -1;
167 }
168
169 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
170 perror("setsockopt()");
171 close_socket(sfd);
172 return -1;
173 }
174
175 memset((void *) &saddr, 0, sizeof(saddr));
176 saddr.sin_family = AF_INET;
177 saddr.sin_addr.s_addr = htonl(INADDR_ANY);
178 saddr.sin_port = htons(port);
179
180 if (0 > bind(sfd, (struct sockaddr *) &saddr, sizeof(saddr))) {
181 perror("bind()");
182 close_socket(sfd);
183 return -1;
184 }
185
186 if (listen(sfd, 1) == -1) {
187 perror("listen()");
188 close_socket(sfd);
189 return -1;
190 }
191
192 return sfd;
193}
194
195#if defined(WIN32) || defined(__CYGWIN__)
196int connect_socket(const char *addr, uint16_t port)
197{
198 int sfd = -1;
199 int yes = 1;
200 struct hostent *hp;
201 struct sockaddr_in saddr;
202#ifdef WIN32
203 WSADATA wsa_data;
204 if (!wsa_init) {
205 if (WSAStartup(MAKEWORD(2,2), &wsa_data) != ERROR_SUCCESS) {
206 fprintf(stderr, "WSAStartup failed!\n");
207 ExitProcess(-1);
208 }
209 wsa_init = 1;
210 }
211#endif
212
213 if (!addr) {
214 errno = EINVAL;
215 return -1;
216 }
217
218 if ((hp = gethostbyname(addr)) == NULL) {
219 if (verbose >= 2)
220 fprintf(stderr, "%s: unknown host '%s'\n", __func__, addr);
221 return -1;
222 }
223
224 if (!hp->h_addr) {
225 if (verbose >= 2)
226 fprintf(stderr, "%s: gethostbyname returned NULL address!\n",
227 __func__);
228 return -1;
229 }
230
231 if (0 > (sfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))) {
232 perror("socket()");
233 return -1;
234 }
235
236 if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(int)) == -1) {
237 perror("setsockopt()");
238 close_socket(sfd);
239 return -1;
240 }
241
242 memset((void *) &saddr, 0, sizeof(saddr));
243 saddr.sin_family = AF_INET;
244 saddr.sin_addr.s_addr = *(uint32_t *) hp->h_addr;
245 saddr.sin_port = htons(port);
246
247 if (connect(sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
248 perror("connect");
249 close_socket(sfd);
250 return -2;
251 }
252
253 return sfd;
254}
255#endif /* WIN32 || __CYGWIN__ */
256
257int check_fd(int fd, fd_mode fdm, unsigned int timeout)
258{
259 fd_set fds;
260 int sret;
261 int eagain;
262 struct timeval to;
263 struct timeval *pto;
264
265 if (fd <= 0) {
266 if (verbose >= 2)
267 fprintf(stderr, "ERROR: invalid fd in check_fd %d\n", fd);
268 return -1;
269 }
270
271 FD_ZERO(&fds);
272 FD_SET(fd, &fds);
273
274 if (timeout > 0) {
275 to.tv_sec = (time_t) (timeout / 1000);
276 to.tv_usec = (time_t) ((timeout - (to.tv_sec * 1000)) * 1000);
277 pto = &to;
278 } else {
279 pto = NULL;
280 }
281
282 sret = -1;
283
284 do {
285 eagain = 0;
286 switch (fdm) {
287 case FDM_READ:
288 sret = select(fd + 1, &fds, NULL, NULL, pto);
289 break;
290 case FDM_WRITE:
291 sret = select(fd + 1, NULL, &fds, NULL, pto);
292 break;
293 case FDM_EXCEPT:
294 sret = select(fd + 1, NULL, NULL, &fds, pto);
295 break;
296 default:
297 return -1;
298 }
299
300 if (sret < 0) {
301 switch (errno) {
302 case EINTR:
303 // interrupt signal in select
304 if (verbose >= 2)
305 fprintf(stderr, "%s: EINTR\n", __func__);
306 eagain = 1;
307 break;
308 case EAGAIN:
309 if (verbose >= 2)
310 fprintf(stderr, "%s: EAGAIN\n", __func__);
311 break;
312 default:
313 if (verbose >= 2)
314 fprintf(stderr, "%s: select failed: %s\n", __func__,
315 strerror(errno));
316 return -1;
317 }
318 }
319 } while (eagain);
320
321 return sret;
322}
323
324int close_socket(int fd) {
325#ifdef WIN32
326 return closesocket(fd);
327#else
328 return close(fd);
329#endif
330}
331
332int recv_buf(int fd, void *data, size_t length)
333{
334 return recv_buf_timeout(fd, data, length, 0, RECV_TIMEOUT);
335}
336
337int peek_buf(int fd, void *data, size_t length)
338{
339 return recv_buf_timeout(fd, data, length, MSG_PEEK, RECV_TIMEOUT);
340}
341
342int recv_buf_timeout(int fd, void *data, size_t length, int flags,
343 unsigned int timeout)
344{
345 int res;
346 int result;
347
348 // check if data is available
349 res = check_fd(fd, FDM_READ, timeout);
350 if (res <= 0) {
351 return res;
352 }
353 // if we get here, there _is_ data available
354 result = recv(fd, data, length, flags);
355 if (res > 0 && result == 0) {
356 // but this is an error condition
357 if (verbose >= 3)
358 fprintf(stderr, "%s: fd=%d recv returned 0\n", __func__, fd);
359 return -EAGAIN;
360 }
361 if (result < 0) {
362 return -errno;
363 }
364 return result;
365}
366
367int send_buf(int fd, void *data, size_t length)
368{
369 return send(fd, data, length, 0);
370}