00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_TelnetTransport==1
00003
00004 #include "TelnetTransport.h"
00005 #include "TCPInterface.h"
00006 #include <stdio.h>
00007 #include <string.h>
00008 #include <stdarg.h>
00009 #include "LinuxStrings.h"
00010
00011
00012
00013 #define ECHO_INPUT
00014
00015 #ifdef _MSC_VER
00016 #pragma warning( push )
00017 #endif
00018
00019 TelnetTransport::TelnetTransport()
00020 {
00021 tcpInterface=0;
00022 sendSuffix=0;
00023 sendPrefix=0;
00024 }
00025 TelnetTransport::~TelnetTransport()
00026 {
00027 Stop();
00028 if (sendSuffix)
00029 rakFree_Ex(sendSuffix, __FILE__, __LINE__ );
00030 if (sendPrefix)
00031 rakFree_Ex(sendPrefix, __FILE__, __LINE__ );
00032 }
00033 bool TelnetTransport::Start(unsigned short port, bool serverMode)
00034 {
00035 (void) serverMode;
00036 AutoAllocate();
00037 RakAssert(serverMode);
00038 return tcpInterface->Start(port, 64);
00039 }
00040 void TelnetTransport::Stop(void)
00041 {
00042 if (tcpInterface==0) return;
00043 tcpInterface->Stop();
00044 unsigned i;
00045 for (i=0; i < remoteClients.Size(); i++)
00046 RakNet::OP_DELETE(remoteClients[i], __FILE__, __LINE__);
00047 remoteClients.Clear(false, __FILE__, __LINE__);
00048 RakNet::OP_DELETE(tcpInterface, __FILE__, __LINE__);
00049 tcpInterface=0;
00050 }
00051 void TelnetTransport::Send( SystemAddress systemAddress, const char *data,... )
00052 {
00053 if (tcpInterface==0) return;
00054
00055 if (data==0 || data[0]==0)
00056 return;
00057
00058 char text[REMOTE_MAX_TEXT_INPUT];
00059 size_t prefixLength;
00060 if (sendPrefix)
00061 {
00062 strcpy(text, sendPrefix);
00063 prefixLength = strlen(sendPrefix);
00064 }
00065 else
00066 {
00067 text[0]=0;
00068 prefixLength=0;
00069 }
00070 va_list ap;
00071 va_start(ap, data);
00072 _vsnprintf(text+prefixLength, REMOTE_MAX_TEXT_INPUT-prefixLength, data, ap);
00073 va_end(ap);
00074 text[REMOTE_MAX_TEXT_INPUT-1]=0;
00075
00076 if (sendSuffix)
00077 {
00078 size_t length = strlen(text);
00079 size_t availableChars = REMOTE_MAX_TEXT_INPUT-length-1;
00080 strncat(text, sendSuffix, availableChars);
00081 }
00082
00083 tcpInterface->Send(text, (unsigned int) strlen(text), systemAddress, false);
00084 }
00085 void TelnetTransport::CloseConnection( SystemAddress systemAddress )
00086 {
00087 tcpInterface->CloseConnection(systemAddress);
00088 }
00089 Packet* TelnetTransport::Receive( void )
00090 {
00091 if (tcpInterface==0) return 0;
00092 Packet *p = tcpInterface->Receive();
00093 if (p==0)
00094 return 0;
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 unsigned i;
00112 TelnetClient *remoteClient=0;
00113 for (i=0; i < remoteClients.Size(); i++)
00114 {
00115 if (remoteClients[i]->systemAddress==p->systemAddress)
00116 remoteClient=remoteClients[i];
00117 }
00118
00119 if (remoteClient==0)
00120 {
00121 tcpInterface->DeallocatePacket(p);
00122 return 0;
00123 }
00124
00125
00126 if (p->length==3 && p->data[0]==27 && p->data[1]==91 && p->data[2]==65)
00127 {
00128 if (remoteClient->lastSentTextInput[0])
00129 {
00130
00131 for (int i=0; remoteClient->textInput[i]; i++)
00132 remoteClient->textInput[i]=8;
00133 strcat(remoteClient->textInput, remoteClient->lastSentTextInput);
00134 tcpInterface->Send((const char *)remoteClient->textInput, strlen(remoteClient->textInput), p->systemAddress, false);
00135 strcpy(remoteClient->textInput,remoteClient->lastSentTextInput);
00136 remoteClient->cursorPosition=strlen(remoteClient->textInput);
00137 }
00138
00139 return 0;
00140 }
00141
00142
00143
00144
00145
00146 if (p->data[0]>=127 || p->data[0]==9 || p->data[0]==27)
00147 {
00148 tcpInterface->DeallocatePacket(p);
00149 return 0;
00150 }
00151
00152
00153
00154
00155
00156
00157 if (p->length==3 && p->data[0]==27 && p->data[1]==91 && p->data[2]>=65 && p->data[2]<=68)
00158 {
00159 tcpInterface->DeallocatePacket(p);
00160 return 0;
00161 }
00162
00163
00164
00165
00166 #ifdef ECHO_INPUT
00167 tcpInterface->Send((const char *)p->data, p->length, p->systemAddress, false);
00168 #endif
00169
00170 bool gotLine;
00171
00172 for (i=0; i < p->length; i++)
00173 {
00174
00175 #ifdef ECHO_INPUT
00176 if (p->data[i]==8)
00177 {
00178 char spaceThenBack[2];
00179 spaceThenBack[0]=' ';
00180 spaceThenBack[1]=8;
00181 tcpInterface->Send((const char *)spaceThenBack, 2, p->systemAddress, false);
00182 }
00183 #endif
00184
00185 gotLine=ReassembleLine(remoteClient, p->data[i]);
00186 if (gotLine && remoteClient->textInput[0])
00187 {
00188
00189 Packet *reassembledLine = (Packet*) rakMalloc_Ex(sizeof(Packet), __FILE__, __LINE__);
00190 reassembledLine->length=(unsigned int) strlen(remoteClient->textInput);
00191 memcpy(remoteClient->lastSentTextInput, remoteClient->textInput, reassembledLine->length+1);
00192 RakAssert(reassembledLine->length < REMOTE_MAX_TEXT_INPUT);
00193 reassembledLine->data= (unsigned char*) rakMalloc_Ex( reassembledLine->length+1, __FILE__, __LINE__ );
00194 memcpy(reassembledLine->data, remoteClient->textInput, reassembledLine->length);
00195 #ifdef _PRINTF_DEBUG
00196 memset(remoteClient->textInput, 0, REMOTE_MAX_TEXT_INPUT);
00197 #endif
00198 reassembledLine->data[reassembledLine->length]=0;
00199 reassembledLine->systemAddress=p->systemAddress;
00200 tcpInterface->DeallocatePacket(p);
00201 return reassembledLine;
00202 }
00203 }
00204
00205 tcpInterface->DeallocatePacket(p);
00206 return 0;
00207 }
00208 void TelnetTransport::DeallocatePacket( Packet *packet )
00209 {
00210 if (tcpInterface==0) return;
00211 rakFree_Ex(packet->data, __FILE__, __LINE__ );
00212 rakFree_Ex(packet, __FILE__, __LINE__ );
00213 }
00214 SystemAddress TelnetTransport::HasNewIncomingConnection(void)
00215 {
00216 unsigned i;
00217 SystemAddress newConnection;
00218 newConnection = tcpInterface->HasNewIncomingConnection();
00219
00220
00221 if (newConnection != UNASSIGNED_SYSTEM_ADDRESS)
00222 {
00223 unsigned char command[10];
00224
00225
00226 command[0]=255;
00227
00228 command[1]=251;
00229 command[2]=1;
00230 tcpInterface->Send((const char*)command, 3, newConnection, false);
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 TelnetClient *remoteClient=0;
00244 for (i=0; i < remoteClients.Size(); i++)
00245 {
00246 if (remoteClients[i]->systemAddress==newConnection)
00247 {
00248 remoteClient=remoteClients[i];
00249 remoteClient->cursorPosition=0;
00250 }
00251 }
00252
00253 if (remoteClient==0)
00254 {
00255 remoteClient=new TelnetClient;
00256 remoteClient->lastSentTextInput[0]=0;
00257 remoteClient->cursorPosition=0;
00258 remoteClient->systemAddress=newConnection;
00259 #ifdef _PRINTF_DEBUG
00260 memset(remoteClient->textInput, 0, REMOTE_MAX_TEXT_INPUT);
00261 #endif
00262 }
00263
00264 remoteClients.Insert(remoteClient, __FILE__, __LINE__);
00265 }
00266 return newConnection;
00267 }
00268 SystemAddress TelnetTransport::HasLostConnection(void)
00269 {
00270 SystemAddress systemAddress;
00271 unsigned i;
00272 systemAddress=tcpInterface->HasLostConnection();
00273 if (systemAddress!=UNASSIGNED_SYSTEM_ADDRESS)
00274 {
00275 for (i=0; i < remoteClients.Size(); i++)
00276 {
00277 if (remoteClients[i]->systemAddress==systemAddress)
00278 {
00279 RakNet::OP_DELETE(remoteClients[i], __FILE__, __LINE__);
00280 remoteClients[i]=remoteClients[remoteClients.Size()-1];
00281 remoteClients.RemoveFromEnd();
00282 }
00283 }
00284 }
00285 return systemAddress;
00286 }
00287 CommandParserInterface* TelnetTransport::GetCommandParser(void)
00288 {
00289 return 0;
00290 }
00291 void TelnetTransport::SetSendSuffix(const char *suffix)
00292 {
00293 if (sendSuffix)
00294 {
00295 rakFree_Ex(sendSuffix, __FILE__, __LINE__ );
00296 sendSuffix=0;
00297 }
00298 if (suffix)
00299 {
00300 sendSuffix = (char*) rakMalloc_Ex(strlen(suffix)+1, __FILE__, __LINE__);
00301 strcpy(sendSuffix, suffix);
00302 }
00303 }
00304 void TelnetTransport::SetSendPrefix(const char *prefix)
00305 {
00306 if (sendPrefix)
00307 {
00308 rakFree_Ex(sendPrefix, __FILE__, __LINE__ );
00309 sendPrefix=0;
00310 }
00311 if (prefix)
00312 {
00313 sendPrefix = (char*) rakMalloc_Ex(strlen(prefix)+1, __FILE__, __LINE__);
00314 strcpy(sendPrefix, prefix);
00315 }
00316 }
00317 void TelnetTransport::AutoAllocate(void)
00318 {
00319 if (tcpInterface==0)
00320 tcpInterface=new TCPInterface;
00321 }
00322 bool TelnetTransport::ReassembleLine(TelnetTransport::TelnetClient* remoteClient, unsigned char c)
00323 {
00324 if (c=='\n')
00325 {
00326 remoteClient->textInput[remoteClient->cursorPosition]=0;
00327 remoteClient->cursorPosition=0;
00328 #ifdef _PRINTF_DEBUG
00329 RAKNET_DEBUG_PRINTF("[Done] %s\n", remoteClient->textInput);
00330 #endif
00331 return true;
00332 }
00333 else if (c==8)
00334 {
00335 if (remoteClient->cursorPosition>0)
00336 {
00337 remoteClient->textInput[--remoteClient->cursorPosition]=0;
00338 #ifdef _PRINTF_DEBUG
00339 RAKNET_DEBUG_PRINTF("[Back] %s\n", remoteClient->textInput);
00340 #endif
00341 }
00342 }
00343 else if (c>=32 && c <127)
00344 {
00345 if (remoteClient->cursorPosition < REMOTE_MAX_TEXT_INPUT)
00346 {
00347 remoteClient->textInput[remoteClient->cursorPosition++]=c;
00348 #ifdef _PRINTF_DEBUG
00349 RAKNET_DEBUG_PRINTF("[Norm] %s\n", remoteClient->textInput);
00350 #endif
00351 }
00352 }
00353 return false;
00354 }
00355
00356 #ifdef _MSC_VER
00357 #pragma warning( pop )
00358 #endif
00359
00360 #endif // _RAKNET_SUPPORT_*