DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* $Id $ */ 00020 00021 00022 #include "config.h" 00023 00024 #if C_MODEM 00025 00026 /*****************************************************************************/ 00027 // C++ SDLnet wrapper 00028 00029 #include "misc_util.h" 00030 00031 struct _TCPsocketX { 00032 int ready; 00033 #ifdef NATIVESOCKETS 00034 SOCKET channel; 00035 #endif 00036 IPaddress remoteAddress; 00037 IPaddress localAddress; 00038 int sflag; 00039 }; 00040 00041 Bit32u Netwrapper_GetCapabilities() 00042 { 00043 Bit32u retval=0; 00044 retval = CAPWORD; 00045 return retval; 00046 } 00047 00048 #ifdef NATIVESOCKETS 00049 TCPClientSocket::TCPClientSocket(int platformsocket) { 00050 sendbuffer=0; 00051 nativetcpstruct = new Bit8u[sizeof(struct _TCPsocketX)]; 00052 00053 mysock = (TCPsocket)nativetcpstruct; 00054 isopen = false; 00055 if(!SDLNetInited) { 00056 if(SDLNet_Init()==-1) { 00057 LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); 00058 return; 00059 } 00060 SDLNetInited = true; 00061 } 00062 // fill the SDL socket manually 00063 ((struct _TCPsocketX*)nativetcpstruct)->ready=0; 00064 ((struct _TCPsocketX*)nativetcpstruct)->sflag=0; 00065 ((struct _TCPsocketX*)nativetcpstruct)->channel=(SOCKET) platformsocket; 00066 sockaddr_in sa; 00067 #ifdef OS2 00068 int sz; 00069 #else 00070 socklen_t sz; 00071 #endif 00072 sz=sizeof(sa); 00073 if(getpeername(platformsocket, (sockaddr *)(&sa), &sz)==0) { 00074 ((struct _TCPsocketX*)nativetcpstruct)-> 00075 remoteAddress.host=/*ntohl(*/sa.sin_addr.s_addr;//); 00076 ((struct _TCPsocketX*)nativetcpstruct)-> 00077 remoteAddress.port=/*ntohs(*/sa.sin_port;//); 00078 } 00079 else { 00080 mysock=0; 00081 return; 00082 } 00083 sz=sizeof(sa); 00084 if(getsockname(platformsocket, (sockaddr *)(&sa), &sz)==0) { 00085 ((struct _TCPsocketX*)nativetcpstruct)-> 00086 localAddress.host=/*ntohl(*/sa.sin_addr.s_addr;//); 00087 ((struct _TCPsocketX*)nativetcpstruct)-> 00088 localAddress.port=/*ntohs(*/sa.sin_port;//); 00089 } 00090 else { 00091 mysock=0; 00092 return; 00093 } 00094 if(mysock!=0) { 00095 listensocketset = SDLNet_AllocSocketSet(1); 00096 if(!listensocketset) return; 00097 SDLNet_TCP_AddSocket(listensocketset, mysock); 00098 isopen=true; 00099 return; 00100 } 00101 mysock=0; 00102 return; 00103 } 00104 #endif // NATIVESOCKETS 00105 00106 TCPClientSocket::TCPClientSocket(TCPsocket source) { 00107 #ifdef NATIVESOCKETS 00108 nativetcpstruct=0; 00109 #endif 00110 sendbuffer=0; 00111 isopen = false; 00112 if(!SDLNetInited) { 00113 if(SDLNet_Init()==-1) { 00114 LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); 00115 return; 00116 } 00117 SDLNetInited = true; 00118 } 00119 00120 mysock=0; 00121 listensocketset=0; 00122 if(source!=0) { 00123 mysock = source; 00124 listensocketset = SDLNet_AllocSocketSet(1); 00125 if(!listensocketset) return; 00126 SDLNet_TCP_AddSocket(listensocketset, source); 00127 00128 isopen=true; 00129 } 00130 } 00131 TCPClientSocket::TCPClientSocket(const char* destination, Bit16u port) { 00132 #ifdef NATIVESOCKETS 00133 nativetcpstruct=0; 00134 #endif 00135 sendbuffer=0; 00136 isopen = false; 00137 if(!SDLNetInited) { 00138 if(SDLNet_Init()==-1) { 00139 LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); 00140 return; 00141 } 00142 SDLNetInited = true; 00143 } 00144 mysock=0; 00145 listensocketset=0; 00146 00147 IPaddress openip; 00148 //Ancient versions of SDL_net had this as char*. People still appear to be using this one. 00149 if (!SDLNet_ResolveHost(&openip,const_cast<char*>(destination),port)) { 00150 listensocketset = SDLNet_AllocSocketSet(1); 00151 if(!listensocketset) return; 00152 mysock = SDLNet_TCP_Open(&openip); 00153 if(!mysock) return; 00154 SDLNet_TCP_AddSocket(listensocketset, mysock); 00155 isopen=true; 00156 } 00157 } 00158 00159 TCPClientSocket::~TCPClientSocket() { 00160 00161 if(sendbuffer) delete [] sendbuffer; 00162 #ifdef NATIVESOCKETS 00163 if(nativetcpstruct) delete [] nativetcpstruct; 00164 else 00165 #endif 00166 if(mysock) { 00167 if(listensocketset) SDLNet_TCP_DelSocket(listensocketset,mysock); 00168 SDLNet_TCP_Close(mysock); 00169 } 00170 00171 if(listensocketset) SDLNet_FreeSocketSet(listensocketset); 00172 } 00173 bool TCPClientSocket::GetRemoteAddressString(Bit8u* buffer) { 00174 IPaddress* remote_ip; 00175 Bit8u b1, b2, b3, b4; 00176 remote_ip=SDLNet_TCP_GetPeerAddress(mysock); 00177 if(!remote_ip) return false; 00178 b4=remote_ip->host>>24; 00179 b3=(remote_ip->host>>16)&0xff; 00180 b2=(remote_ip->host>>8)&0xff; 00181 b1=remote_ip->host&0xff; 00182 sprintf((char*)buffer,"%u.%u.%u.%u",b1,b2,b3,b4); 00183 return true; 00184 } 00185 00186 bool TCPClientSocket::ReceiveArray(Bit8u* data, Bitu* size) { 00187 if(SDLNet_CheckSockets(listensocketset,0)) 00188 { 00189 Bits retval = SDLNet_TCP_Recv(mysock, data, (int)(*size)); 00190 if(retval<1) { 00191 isopen=false; 00192 *size=0; 00193 return false; 00194 } else { 00195 *size=(Bitu)retval; 00196 return true; 00197 } 00198 } 00199 else { 00200 *size=0; 00201 return true; 00202 } 00203 } 00204 00205 00206 Bits TCPClientSocket::GetcharNonBlock() { 00207 // return: 00208 // -1: no data 00209 // -2: socket closed 00210 // 0..255: data 00211 if(SDLNet_CheckSockets(listensocketset,0)) 00212 { 00213 Bitu retval =0; 00214 if(SDLNet_TCP_Recv(mysock, &retval, 1)!=1) { 00215 isopen=false; 00216 return -2; 00217 } else return (Bits)retval; 00218 } 00219 else return -1; 00220 } 00221 bool TCPClientSocket::Putchar(Bit8u data) { 00222 if(SDLNet_TCP_Send(mysock, &data, 1)!=1) { 00223 isopen=false; 00224 return false; 00225 } 00226 return true; 00227 } 00228 00229 bool TCPClientSocket::SendArray(Bit8u* data, Bitu bufsize) { 00230 if((Bitu)SDLNet_TCP_Send(mysock, data, (int)bufsize) != bufsize) { 00231 isopen=false; 00232 return false; 00233 } 00234 return true; 00235 } 00236 00237 bool TCPClientSocket::SendByteBuffered(Bit8u data) { 00238 00239 if(sendbufferindex==(sendbuffersize-1)) { 00240 // buffer is full, get rid of it 00241 sendbuffer[sendbufferindex]=data; 00242 sendbufferindex=0; 00243 00244 if((Bitu)SDLNet_TCP_Send(mysock, sendbuffer, (int)sendbuffersize) != sendbuffersize) { 00245 isopen=false; 00246 return false; 00247 } 00248 } else { 00249 sendbuffer[sendbufferindex]=data; 00250 sendbufferindex++; 00251 } 00252 return true; 00253 } 00254 /* 00255 bool TCPClientSocket::SendArrayBuffered(Bit8u* data, Bitu bufsize) { 00256 00257 Bitu bytes 00258 while( 00259 00260 // first case, buffer already full 00261 if(sendbufferindex==(sendbuffersize-1)) { 00262 // buffer is full, get rid of it 00263 sendbuffer[sendbufferindex]=data; 00264 sendbufferindex=0; 00265 00266 if(SDLNet_TCP_Send(mysock, sendbuffer, sendbuffersize)!=sendbuffersize) { 00267 isopen=false; 00268 return false; 00269 } 00270 } 00271 } 00272 */ 00273 void TCPClientSocket::FlushBuffer() { 00274 if(sendbufferindex) { 00275 if((Bitu)SDLNet_TCP_Send(mysock, sendbuffer, 00276 (int)sendbufferindex) != sendbufferindex) { 00277 isopen=false; 00278 return; 00279 } 00280 sendbufferindex=0; 00281 } 00282 } 00283 00284 void TCPClientSocket::SetSendBufferSize(Bitu bufsize) { 00285 if(sendbuffer) delete [] sendbuffer; 00286 sendbuffer = new Bit8u[bufsize]; 00287 sendbuffersize=bufsize; 00288 sendbufferindex=0; 00289 } 00290 00291 00292 TCPServerSocket::TCPServerSocket(Bit16u port) 00293 { 00294 isopen = false; 00295 mysock = 0; 00296 if(!SDLNetInited) { 00297 if(SDLNet_Init()==-1) { 00298 LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError()); 00299 return; 00300 } 00301 SDLNetInited = true; 00302 } 00303 if (port) { 00304 IPaddress listen_ip; 00305 SDLNet_ResolveHost(&listen_ip, NULL, port); 00306 mysock=SDLNet_TCP_Open(&listen_ip); 00307 if(!mysock) return; 00308 } 00309 else return; 00310 isopen = true; 00311 } 00312 00313 TCPServerSocket::~TCPServerSocket() { 00314 if(mysock) SDLNet_TCP_Close(mysock); 00315 } 00316 00317 TCPClientSocket* TCPServerSocket::Accept() { 00318 00319 TCPsocket new_tcpsock; 00320 00321 new_tcpsock=SDLNet_TCP_Accept(mysock); 00322 if(!new_tcpsock) { 00323 //printf("SDLNet_TCP_Accept: %s\n", SDLNet_GetError()); 00324 return 0; 00325 } 00326 00327 return new TCPClientSocket(new_tcpsock); 00328 } 00329 #endif // #if C_MODEM