1 #include "../../include/freenet/fcpv2.h"
\r
8 #include <ws2tcpip.h>
\r
11 #include <netinet/in.h>
\r
14 /* XMEM doesn't play nice with strtok - should replace strtok with something else anyway
\r
21 bool FCPv2::m_wsastartup=false;
\r
29 if(m_wsastartup==false)
\r
32 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
37 // initialize socket to server
\r
40 // initialize buffers
\r
41 m_tempbuffer=new char[65535];
\r
53 delete [] m_tempbuffer;
\r
58 const bool FCPv2::Connect(const char *host, const int port)
\r
60 // disconnect socket to server if it is currently open
\r
67 struct sockaddr_storage m_serveraddr;
\r
69 std::ostringstream portstring;
\r
70 addrinfo hint,*result,*current;
\r
74 memset(&hint,0,sizeof(addrinfo));
\r
75 hint.ai_socktype=SOCK_STREAM;
\r
76 rval=getaddrinfo(host,portstring.str().c_str(),&hint,&result);
\r
78 // erase any data in buffers
\r
79 m_sendbuffer.clear();
\r
80 m_receivebuffer.clear();
\r
84 for(current=result; current!=NULL && m_serversocket==-1; current=current->ai_next)
\r
86 memset(&m_serveraddr,0,sizeof(struct sockaddr_storage));
\r
88 m_serversocket=socket(current->ai_family,current->ai_socktype,current->ai_protocol);
\r
90 if(m_serversocket!=-1)
\r
92 rval=connect(m_serversocket,current->ai_addr,current->ai_addrlen);
\r
100 freeaddrinfo(result);
\r
114 const bool FCPv2::Disconnect()
\r
119 closesocket(m_serversocket);
\r
121 close(m_serversocket);
\r
128 int FCPv2::FindOnReceiveBuffer(const char *text)
\r
131 std::vector<char>::size_type i,j;
\r
132 size_t tlen=strlen(text);
\r
134 if(m_receivebuffer.size()>=tlen)
\r
136 for(i=0; i<=m_receivebuffer.size()-tlen; i++)
\r
139 for(j=0; j<tlen; j++)
\r
141 if(m_receivebuffer[i+j]!=text[j])
\r
157 FCPMessage FCPv2::ReceiveMessage()
\r
167 FCPMessage message;
\r
169 // there is data on the receive buffer
\r
170 if(m_receivebuffer.size()>0)
\r
173 // find Data on a line by itself following AllData
\r
174 if(FindOnReceiveBuffer("AllData\n")==0)
\r
176 endmessage=FindOnReceiveBuffer("\nData\n");
\r
183 // otherwise this is a regular message - search for EndMessage
\r
186 endmessage=FindOnReceiveBuffer("EndMessage\n");
\r
190 // continue if we found "EndMessage\n" or "Data\n"
\r
193 // total length of message (including ending \n)
\r
194 len=endmessage+endlen;
\r
196 // allocate space for message
\r
197 buffer=new char[len+1];
\r
199 // copy message from receive buffer to message buffer
\r
200 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,buffer);
\r
203 // remove from receive buffer
\r
204 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
206 // set buffer position
\r
209 // find message name
\r
210 buffpos=strtok(buffer,"\n");
\r
211 message.SetName(buffer);
\r
217 buffpos=strtok(NULL,"=");
\r
219 // continue if we aren't at the end of a regular message, or at Data for an AllData message
\r
220 if(strncmp(buffpos,"EndMessage\n",11)!=0 && strncmp(buffpos,"Data\n",5)!=0) //!(strncmp(message->MessageName,"AllData",7)==0 && strncmp(buffpos,"Data\n",5)==0))
\r
225 buffpos=strtok(NULL,"\n");
\r
227 if(prevpos && buffpos)
\r
229 message[prevpos]=buffpos;
\r
239 }while(buffpos!=0);
\r
249 const long FCPv2::ReceiveRaw(char *data, long &datalen)
\r
252 if(m_receivebuffer.size()>0 && datalen>0)
\r
254 if(datalen>m_receivebuffer.size())
\r
256 len=m_receivebuffer.size();
\r
263 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);
\r
265 // erase bytes from receive buffer
\r
266 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
273 void FCPv2::SendBufferedText(const char *text)
\r
276 for(i=0; i<strlen(text); i++)
\r
278 m_sendbuffer.push_back(text[i]);
\r
282 void FCPv2::SendBufferedRaw(const char *data, const long len)
\r
285 for(i=0; i<len; i++)
\r
287 m_sendbuffer.push_back(data[i]);
\r
291 const int FCPv2::SendMessage(const char *messagename, const int fieldcount, ...)
\r
296 std::vector<char>::size_type bytecount=0;
\r
298 std::vector<char>::size_type startlen;
\r
300 startlen=m_sendbuffer.size();
\r
302 SendBufferedText(messagename);
\r
303 SendBufferedText("\n");
\r
305 va_start(args,fieldcount);
\r
307 for(i=0; i<fieldcount; i++)
\r
309 field=va_arg(args,const char *);
\r
310 val=va_arg(args,const char *);
\r
312 SendBufferedText(field);
\r
313 SendBufferedText("=");
\r
314 SendBufferedText(val);
\r
315 SendBufferedText("\n");
\r
318 SendBufferedText("EndMessage\n");
\r
320 bytecount=m_sendbuffer.size()-startlen;
\r
327 const int FCPv2::SendMessage(FCPMessage &message)
\r
329 std::vector<char>::size_type bytecount=0;
\r
330 std::vector<char>::size_type startlen;
\r
331 FCPMessage::iterator i;
\r
333 startlen=m_sendbuffer.size();
\r
335 if(message.GetName()!="")
\r
337 SendBufferedText(message.GetName().c_str());
\r
338 SendBufferedText("\n");
\r
340 for(i=message.begin(); i!=message.end(); i++)
\r
342 SendBufferedText((*i).first.c_str());
\r
343 SendBufferedText("=");
\r
344 SendBufferedText((*i).second.c_str());
\r
345 SendBufferedText("\n");
\r
348 SendBufferedText("EndMessage\n");
\r
351 bytecount=m_sendbuffer.size()-startlen;
\r
357 const int FCPv2::SendRaw(const char *data, const int datalen)
\r
359 int bytecount=datalen;
\r
363 SendBufferedRaw(data,datalen);
\r
370 void FCPv2::SocketReceive()
\r
374 len=recv(m_serversocket,m_tempbuffer,65535,0);
\r
379 m_receivebuffer.resize(m_receivebuffer.size()+len);
\r
380 std::copy(m_tempbuffer,&m_tempbuffer[len],m_receivebuffer.end()-len);
\r
383 // there was an error or server closed connection - disconnect socket
\r
390 void FCPv2::SocketSend()
\r
393 if(m_sendbuffer.size()>0)
\r
395 len=send(m_serversocket,&m_sendbuffer[0],m_sendbuffer.size(),0);
\r
398 // move remaining data in buffer to beginning of buffer (erase the bytes we just sent)
\r
399 m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);
\r
401 // there was an error with send - disconnect socket
\r
410 const bool FCPv2::Update(const long waittime)
\r
415 m_timeval.tv_sec=waittime;
\r
416 m_timeval.tv_usec=0;
\r
418 FD_ZERO(&m_readfs);
\r
419 FD_ZERO(&m_writefs);
\r
421 FD_SET(m_serversocket,&m_readfs);
\r
423 if(m_sendbuffer.size()>0)
\r
425 FD_SET(m_serversocket,&m_writefs);
\r
428 select(m_serversocket+1,&m_readfs,&m_writefs,0,&m_timeval);
\r
430 if(FD_ISSET(m_serversocket,&m_readfs))
\r
434 if(Connected() && FD_ISSET(m_serversocket,&m_writefs))
\r