don't rely on unsigned char on arm
[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 _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
34 static int server_socket = 0;
35 static int client_socket = 0;
36
37 static char tbuf[513];
38 static int ptr = 0;
39
40 #define PORT_NUMBER 12345
41
42 int 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
86 void 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
97 void 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
127 void 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
140 int HasClient() {
141     return client_socket ? 1 : 0;
142 }
143
144 int 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
192 int RawReadSocket(char * buffer, int len) {
193     int r = 0;
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
229 void WriteSocket(char * buffer, int len) {
230     if (!client_socket)
231         return;
232
233     send(client_socket, buffer, len, 0);
234 }
235
236 void 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
246 void 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 }