1 #include "../../include/freenet/fcpv2.h"
\r
7 #include <ws2tcpip.h>
\r
10 #include <netinet/in.h>
\r
13 /* XMEM doesn't play nice with strtok - should replace strtok with something else anyway
\r
20 bool FCPv2::m_wsastartup=false;
\r
28 if(m_wsastartup==false)
\r
31 WSAStartup(MAKEWORD(2,2),&wsadata);
\r
36 // initialize socket to server
\r
39 // initialize buffers
\r
40 m_tempbuffer=new char[65535];
\r
52 delete [] m_tempbuffer;
\r
57 const bool FCPv2::Connect(const char *host, const int port)
\r
59 // disconnect socket to server if it is currently open
\r
66 struct sockaddr_storage m_serveraddr;
\r
68 std::ostringstream portstring;
\r
69 addrinfo hint,*result;
\r
73 memset(&hint,0,sizeof(addrinfo));
\r
74 hint.ai_socktype=SOCK_STREAM;
\r
75 rval=getaddrinfo(host,portstring.str().c_str(),&hint,&result);
\r
77 // erase any data in buffers
\r
78 m_sendbuffer.clear();
\r
79 m_receivebuffer.clear();
\r
83 memset(&m_serveraddr,0,sizeof(struct sockaddr_storage));
\r
85 m_serversocket=socket(result->ai_family,result->ai_socktype,result->ai_protocol);
\r
87 if(m_serversocket!=-1)
\r
89 rval=connect(m_serversocket,result->ai_addr,result->ai_addrlen);
\r
96 freeaddrinfo(result);
\r
110 const bool FCPv2::Disconnect()
\r
115 closesocket(m_serversocket);
\r
117 close(m_serversocket);
\r
124 int FCPv2::FindOnReceiveBuffer(const char *text)
\r
128 size_t tlen=strlen(text);
\r
130 if(m_receivebuffer.size()>=tlen)
\r
132 for(i=0; i<=m_receivebuffer.size()-tlen; i++)
\r
135 for(j=0; j<tlen; j++)
\r
137 if(m_receivebuffer[i+j]!=text[j])
\r
153 FCPMessage FCPv2::ReceiveMessage()
\r
163 FCPMessage message;
\r
165 // there is data on the receive buffer
\r
166 if(m_receivebuffer.size()>0)
\r
169 // find Data on a line by itself following AllData
\r
170 if(FindOnReceiveBuffer("AllData\n")==0)
\r
172 endmessage=FindOnReceiveBuffer("\nData\n");
\r
179 // otherwise this is a regular message - search for EndMessage
\r
182 endmessage=FindOnReceiveBuffer("EndMessage\n");
\r
186 // continue if we found "EndMessage\n" or "Data\n"
\r
189 // total length of message (including ending \n)
\r
190 len=endmessage+endlen;
\r
192 // allocate space for message
\r
193 buffer=new char[len+1];
\r
195 // copy message from receive buffer to message buffer
\r
196 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,buffer);
\r
199 // remove from receive buffer
\r
200 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
202 // set buffer position
\r
205 // find message name
\r
206 buffpos=strtok(buffer,"\n");
\r
207 message.SetName(buffer);
\r
213 buffpos=strtok(NULL,"=");
\r
215 // continue if we aren't at the end of a regular message, or at Data for an AllData message
\r
216 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
221 buffpos=strtok(NULL,"\n");
\r
223 if(prevpos && buffpos)
\r
225 message[prevpos]=buffpos;
\r
235 }while(buffpos!=0);
\r
245 const long FCPv2::ReceiveRaw(char *data, long &datalen)
\r
248 if(m_receivebuffer.size()>0 && datalen>0)
\r
250 if(datalen>m_receivebuffer.size())
\r
252 len=m_receivebuffer.size();
\r
259 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);
\r
261 // erase bytes from receive buffer
\r
262 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
269 void FCPv2::SendBufferedText(const char *text)
\r
272 for(i=0; i<strlen(text); i++)
\r
274 m_sendbuffer.push_back(text[i]);
\r
278 void FCPv2::SendBufferedRaw(const char *data, const long len)
\r
281 for(i=0; i<len; i++)
\r
283 m_sendbuffer.push_back(data[i]);
\r
287 const int FCPv2::SendMessage(const char *messagename, const int fieldcount, ...)
\r
296 startlen=m_sendbuffer.size();
\r
298 SendBufferedText(messagename);
\r
299 SendBufferedText("\n");
\r
301 va_start(args,fieldcount);
\r
303 for(i=0; i<fieldcount; i++)
\r
305 field=va_arg(args,const char *);
\r
306 val=va_arg(args,const char *);
\r
308 SendBufferedText(field);
\r
309 SendBufferedText("=");
\r
310 SendBufferedText(val);
\r
311 SendBufferedText("\n");
\r
314 SendBufferedText("EndMessage\n");
\r
316 bytecount=m_sendbuffer.size()-startlen;
\r
323 const int FCPv2::SendMessage(FCPMessage &message)
\r
327 FCPMessage::iterator i;
\r
329 startlen=m_sendbuffer.size();
\r
331 if(message.GetName()!="")
\r
333 SendBufferedText(message.GetName().c_str());
\r
334 SendBufferedText("\n");
\r
336 for(i=message.begin(); i!=message.end(); i++)
\r
338 SendBufferedText((*i).first.c_str());
\r
339 SendBufferedText("=");
\r
340 SendBufferedText((*i).second.c_str());
\r
341 SendBufferedText("\n");
\r
344 SendBufferedText("EndMessage\n");
\r
347 bytecount=m_sendbuffer.size()-startlen;
\r
353 const int FCPv2::SendRaw(const char *data, const int datalen)
\r
355 int bytecount=datalen;
\r
359 SendBufferedRaw(data,datalen);
\r
366 void FCPv2::SocketReceive()
\r
370 len=recv(m_serversocket,m_tempbuffer,65535,0);
\r
375 m_receivebuffer.resize(m_receivebuffer.size()+len);
\r
376 std::copy(m_tempbuffer,&m_tempbuffer[len],m_receivebuffer.end()-len);
\r
379 // there was an error or server closed connection - disconnect socket
\r
386 void FCPv2::SocketSend()
\r
389 if(m_sendbuffer.size()>0)
\r
391 len=send(m_serversocket,&m_sendbuffer[0],m_sendbuffer.size(),0);
\r
394 // move remaining data in buffer to beginning of buffer (erase the bytes we just sent)
\r
395 m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);
\r
397 // there was an error with send - disconnect socket
\r
406 const bool FCPv2::Update(const long waittime)
\r
411 m_timeval.tv_sec=waittime;
\r
412 m_timeval.tv_usec=0;
\r
414 FD_ZERO(&m_readfs);
\r
415 FD_ZERO(&m_writefs);
\r
417 FD_SET(m_serversocket,&m_readfs);
\r
419 if(m_sendbuffer.size()>0)
\r
421 FD_SET(m_serversocket,&m_writefs);
\r
424 select(m_serversocket+1,&m_readfs,&m_writefs,0,&m_timeval);
\r
426 if(FD_ISSET(m_serversocket,&m_readfs))
\r
430 if(Connected() && FD_ISSET(m_serversocket,&m_writefs))
\r