merge from libretro
[pcsx_rearmed.git] / socket.c
... / ...
CommitLineData
1/* Pcsx - Pc Psx Emulator
2 * Copyright (C) 1999-2003 Pcsx Team
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses>.
16 */
17
18#ifdef _WIN32
19#include <winsock2.h>
20#endif
21
22#include "psxcommon.h"
23#include "socket.h"
24
25#ifndef _WIN32
26#include <sys/socket.h>
27#include <sys/ioctl.h>
28#include <arpa/inet.h>
29#include <netinet/in.h>
30#include <unistd.h>
31#include <fcntl.h>
32#endif
33
34static int server_socket = 0;
35static int client_socket = 0;
36
37static char tbuf[513];
38static int ptr = 0;
39
40#define PORT_NUMBER 12345
41
42int StartServer() {
43 struct in_addr localhostaddr;
44 struct sockaddr_in localsocketaddr;
45
46#ifdef _WIN32
47 WSADATA wsaData;
48
49 if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
50 return -1;
51#endif
52
53 server_socket = socket(AF_INET, SOCK_STREAM, 0);
54
55#ifdef _WIN32
56 if (server_socket == INVALID_SOCKET)
57 return -1;
58#else
59 if (server_socket == -1)
60 return -1;
61#endif
62
63 SetsNonblock();
64
65 memset((void *)&localhostaddr, 0, sizeof(localhostaddr));
66 memset(&localsocketaddr, 0, sizeof(struct sockaddr_in));
67
68#ifdef _WIN32
69 localhostaddr.S_un.S_addr = htonl(INADDR_ANY);
70#else
71 localhostaddr.s_addr = htonl(INADDR_ANY);
72#endif
73 localsocketaddr.sin_family = AF_INET;
74 localsocketaddr.sin_addr = localhostaddr;
75 localsocketaddr.sin_port = htons(PORT_NUMBER);
76
77 if (bind(server_socket, (struct sockaddr *) &localsocketaddr, sizeof(localsocketaddr)) < 0)
78 return -1;
79
80 if (listen(server_socket, 1) != 0)
81 return -1;
82
83 return 0;
84}
85
86void StopServer() {
87#ifdef _WIN32
88 shutdown(server_socket, SD_BOTH);
89 closesocket(server_socket);
90 WSACleanup();
91#else
92 shutdown(server_socket, SHUT_RDWR);
93 close(server_socket);
94#endif
95}
96
97void GetClient() {
98 int new_socket;
99 char hello[256];
100
101 new_socket = accept(server_socket, 0, 0);
102
103#ifdef _WIN32
104 if (new_socket == INVALID_SOCKET)
105 return;
106#else
107 if (new_socket == -1)
108 return;
109#endif
110 if (client_socket)
111 CloseClient();
112 client_socket = new_socket;
113
114#ifndef _WIN32
115 {
116 int flags;
117 flags = fcntl(client_socket, F_GETFL, 0);
118 fcntl(client_socket, F_SETFL, flags | O_NONBLOCK);
119 }
120#endif
121
122 sprintf(hello, "000 PCSX Version %s - Debug console\r\n", PACKAGE_VERSION);
123 WriteSocket(hello, strlen(hello));
124 ptr = 0;
125}
126
127void CloseClient() {
128 if (client_socket) {
129#ifdef _WIN32
130 shutdown(client_socket, SD_BOTH);
131 closesocket(client_socket);
132#else
133 shutdown(client_socket, SHUT_RDWR);
134 close(client_socket);
135#endif
136 client_socket = 0;
137 }
138}
139
140int HasClient() {
141 return client_socket ? 1 : 0;
142}
143
144int ReadSocket(char * buffer, int len) {
145 int r;
146 char * endl;
147
148 if (!client_socket)
149 return -1;
150
151 r = recv(client_socket, tbuf + ptr, 512 - ptr, 0);
152
153 if (r == 0) {
154 client_socket = 0;
155 if (!ptr)
156 return 0;
157 }
158#ifdef _WIN32
159 if (r == SOCKET_ERROR)
160#else
161 if (r == -1)
162#endif
163 {
164 if (ptr == 0)
165 return -1;
166 r = 0;
167 }
168 ptr += r;
169 tbuf[ptr] = 0;
170
171 endl = strstr(tbuf, "\r\n");
172
173 if (endl) {
174 r = endl - tbuf;
175 strncpy(buffer, tbuf, r);
176
177 r += 2;
178 memmove(tbuf, tbuf + r, 512 - r);
179 ptr -= r;
180 memset(tbuf + r, 0, 512 - r);
181 r -= 2;
182
183 } else {
184 r = 0;
185 }
186
187 buffer[r] = 0;
188
189 return r;
190}
191
192int RawReadSocket(char * buffer, int len) {
193 int r;
194 int mlen = len < ptr ? len : ptr;
195
196 if (!client_socket)
197 return -1;
198
199 if (ptr) {
200 memcpy(buffer, tbuf, mlen);
201 ptr -= mlen;
202 memmove(tbuf, tbuf + mlen, 512 - mlen);
203 }
204
205 if (len - mlen)
206 r = recv(client_socket, buffer + mlen, len - mlen, 0);
207
208 if (r == 0) {
209 client_socket = 0;
210 if (!ptr)
211 return 0;
212 }
213#ifdef _WIN32
214 if (r == SOCKET_ERROR)
215#else
216 if (r == -1)
217#endif
218 {
219 if (ptr == 0)
220 return -1;
221 r = 0;
222 }
223
224 r += mlen;
225
226 return r;
227}
228
229void WriteSocket(char * buffer, int len) {
230 if (!client_socket)
231 return;
232
233 send(client_socket, buffer, len, 0);
234}
235
236void SetsBlock() {
237#ifdef _WIN32
238 u_long b = 0;
239 ioctlsocket(server_socket, FIONBIO, &b);
240#else
241 int flags = fcntl(server_socket, F_GETFL, 0);
242 fcntl(server_socket, F_SETFL, flags & ~O_NONBLOCK);
243#endif
244}
245
246void SetsNonblock() {
247#ifdef _WIN32
248 u_long b = 1;
249 ioctlsocket(server_socket, FIONBIO, &b);
250#else
251 int flags = fcntl(server_socket, F_GETFL, 0);
252 fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
253#endif
254}