cdrom: change pause timing again
[pcsx_rearmed.git] / libpcsxcore / socket.c
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 NO_SOCKET
19
20 int StartServer() { return 0;}
21 void StopServer() {}
22 void GetClient() {}
23 void CloseClient() {}
24 int HasClient() { return 0;}
25 int ReadSocket(char * buffer, int len) { return 0;}
26 int RawReadSocket(char * buffer, int len) { return 0;}
27 void WriteSocket(char * buffer, int len) {}
28
29 void SetsBlock() {}
30 void SetsNonblock() {}
31
32 #else // NO_SOCKET
33
34 #ifdef _WIN32
35 #include <winsock2.h>
36 #endif
37
38 #include "psxcommon.h"
39 #include "socket.h"
40
41 #ifndef _WIN32
42 #include <sys/socket.h>
43 #include <sys/ioctl.h>
44 #include <arpa/inet.h>
45 #include <netinet/in.h>
46 #include <unistd.h>
47 #include <fcntl.h>
48 #endif
49
50 static int server_socket = 0;
51 static int client_socket = 0;
52
53 static char tbuf[513];
54 static int ptr = 0;
55
56 #define PORT_NUMBER 12345
57
58 int StartServer() {
59     struct in_addr localhostaddr;
60     struct sockaddr_in localsocketaddr;
61
62 #ifdef _WIN32
63     WSADATA wsaData;
64
65     if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
66         return -1;
67 #endif
68
69     server_socket = socket(AF_INET, SOCK_STREAM, 0);
70
71 #ifdef _WIN32
72     if (server_socket == INVALID_SOCKET)
73         return -1;
74 #else
75     if (server_socket == -1)
76         return -1;
77 #endif
78
79     SetsNonblock();
80
81     memset((void *)&localhostaddr, 0, sizeof(localhostaddr));
82     memset(&localsocketaddr, 0, sizeof(struct sockaddr_in));
83
84 #ifdef _WIN32
85     localhostaddr.S_un.S_addr = htonl(INADDR_ANY);
86 #else
87     localhostaddr.s_addr = htonl(INADDR_ANY);
88 #endif
89     localsocketaddr.sin_family = AF_INET;
90     localsocketaddr.sin_addr = localhostaddr;
91     localsocketaddr.sin_port = htons(PORT_NUMBER);
92
93     if (bind(server_socket, (struct sockaddr *) &localsocketaddr, sizeof(localsocketaddr)) < 0)
94         return -1;
95
96     if (listen(server_socket, 1) != 0)
97         return -1;
98
99     return 0;
100 }
101
102 void StopServer() {
103 #ifdef _WIN32
104     shutdown(server_socket, SD_BOTH);
105     closesocket(server_socket);
106     WSACleanup();
107 #else
108     shutdown(server_socket, SHUT_RDWR);
109     close(server_socket);
110 #endif
111 }
112
113 void GetClient() {
114     int new_socket;
115     char hello[256];
116
117     new_socket = accept(server_socket, 0, 0);
118     
119 #ifdef _WIN32
120     if (new_socket == INVALID_SOCKET)
121         return;
122 #else
123     if (new_socket == -1)
124         return;
125 #endif
126     if (client_socket)
127         CloseClient();
128     client_socket = new_socket;
129
130 #ifndef _WIN32
131     {
132         int flags;
133         flags = fcntl(client_socket, F_GETFL, 0);
134         fcntl(client_socket, F_SETFL, flags | O_NONBLOCK);
135     }
136 #endif
137
138     sprintf(hello, "000 PCSX Version %s - Debug console\r\n", PCSX_VERSION);
139     WriteSocket(hello, strlen(hello));
140     ptr = 0;
141 }
142
143 void CloseClient() {
144     if (client_socket) {
145 #ifdef _WIN32
146         shutdown(client_socket, SD_BOTH);
147         closesocket(client_socket);
148 #else
149         shutdown(client_socket, SHUT_RDWR);
150         close(client_socket);
151 #endif
152         client_socket = 0;
153     }
154 }
155
156 int HasClient() {
157     return client_socket ? 1 : 0;
158 }
159
160 int ReadSocket(char * buffer, int len) {
161     int r;
162     char * endl;
163
164     if (!client_socket)
165         return -1;
166
167     r = recv(client_socket, tbuf + ptr, 512 - ptr, 0);
168
169     if (r == 0) {
170         client_socket = 0;
171         if (!ptr)
172             return 0;
173     }
174 #ifdef _WIN32
175     if (r == SOCKET_ERROR)
176 #else
177     if (r == -1)
178 #endif
179     {
180         if (ptr == 0)
181             return -1;
182         r = 0;
183     }
184     ptr += r;
185     tbuf[ptr] = 0;
186
187     endl = strstr(tbuf, "\r\n");
188
189     if (endl) {
190         r = endl - tbuf;
191         strncpy(buffer, tbuf, r);
192
193         r += 2;
194         memmove(tbuf, tbuf + r, 512 - r);
195         ptr -= r;
196         memset(tbuf + r, 0, 512 - r);
197         r -= 2;
198
199     } else {
200         r = 0;
201     }
202
203     buffer[r] = 0;
204
205     return r;
206 }
207
208 int RawReadSocket(char * buffer, int len) {
209     int r = 0;
210     int mlen = len < ptr ? len : ptr;
211
212     if (!client_socket)
213         return -1;
214
215     if (ptr) {
216         memcpy(buffer, tbuf, mlen);
217         ptr -= mlen;
218         memmove(tbuf, tbuf + mlen, 512 - mlen);
219     }
220
221     if (len - mlen)
222         r = recv(client_socket, buffer + mlen, len - mlen, 0);
223
224     if (r == 0) {
225         client_socket = 0;
226         if (!ptr)
227             return 0;
228     }
229 #ifdef _WIN32
230     if (r == SOCKET_ERROR)
231 #else
232     if (r == -1)
233 #endif
234     {
235         if (ptr == 0)
236             return -1;
237         r = 0;
238     }
239
240     r += mlen;
241
242     return r;
243 }
244
245 void WriteSocket(char * buffer, int len) {
246     if (!client_socket)
247         return;
248
249     send(client_socket, buffer, len, 0);
250 }
251
252 void SetsBlock() {
253 #ifdef _WIN32
254     u_long b = 0;
255     ioctlsocket(server_socket, FIONBIO, &b);
256 #else
257     int flags = fcntl(server_socket, F_GETFL, 0);
258     fcntl(server_socket, F_SETFL, flags & ~O_NONBLOCK);
259 #endif
260 }
261
262 void SetsNonblock() {
263 #ifdef _WIN32
264     u_long b = 1;
265     ioctlsocket(server_socket, FIONBIO, &b);
266 #else
267     int flags = fcntl(server_socket, F_GETFL, 0);
268     fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
269 #endif
270 }
271 #endif // NO_SOCKET