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,*current;
\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 for(current=result; current!=NULL && m_serversocket==-1; current=current->ai_next)
\r
85 memset(&m_serveraddr,0,sizeof(struct sockaddr_storage));
\r
87 m_serversocket=socket(current->ai_family,current->ai_socktype,current->ai_protocol);
\r
89 if(m_serversocket!=-1)
\r
91 rval=connect(m_serversocket,current->ai_addr,current->ai_addrlen);
\r
99 freeaddrinfo(result);
\r
113 const bool FCPv2::Disconnect()
\r
118 closesocket(m_serversocket);
\r
120 close(m_serversocket);
\r
127 int FCPv2::FindOnReceiveBuffer(const char *text)
\r
130 std::vector<char>::size_type i,j;
\r
131 size_t tlen=strlen(text);
\r
133 if(m_receivebuffer.size()>=tlen)
\r
135 for(i=0; i<=m_receivebuffer.size()-tlen; i++)
\r
138 for(j=0; j<tlen; j++)
\r
140 if(m_receivebuffer[i+j]!=text[j])
\r
156 FCPMessage FCPv2::ReceiveMessage()
\r
166 FCPMessage message;
\r
168 // there is data on the receive buffer
\r
169 if(m_receivebuffer.size()>0)
\r
172 // find Data on a line by itself following AllData
\r
173 if(FindOnReceiveBuffer("AllData\n")==0)
\r
175 endmessage=FindOnReceiveBuffer("\nData\n");
\r
182 // otherwise this is a regular message - search for EndMessage
\r
185 endmessage=FindOnReceiveBuffer("EndMessage\n");
\r
189 // continue if we found "EndMessage\n" or "Data\n"
\r
192 // total length of message (including ending \n)
\r
193 len=endmessage+endlen;
\r
195 // allocate space for message
\r
196 buffer=new char[len+1];
\r
198 // copy message from receive buffer to message buffer
\r
199 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,buffer);
\r
202 // remove from receive buffer
\r
203 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
205 // set buffer position
\r
208 // find message name
\r
209 buffpos=strtok(buffer,"\n");
\r
210 message.SetName(buffer);
\r
216 buffpos=strtok(NULL,"=");
\r
218 // continue if we aren't at the end of a regular message, or at Data for an AllData message
\r
219 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
224 buffpos=strtok(NULL,"\n");
\r
226 if(prevpos && buffpos)
\r
228 message[prevpos]=buffpos;
\r
238 }while(buffpos!=0);
\r
248 const long FCPv2::ReceiveRaw(char *data, long &datalen)
\r
251 if(m_receivebuffer.size()>0 && datalen>0)
\r
253 if(datalen>m_receivebuffer.size())
\r
255 len=m_receivebuffer.size();
\r
262 std::copy(m_receivebuffer.begin(),m_receivebuffer.begin()+len,data);
\r
264 // erase bytes from receive buffer
\r
265 m_receivebuffer.erase(m_receivebuffer.begin(),m_receivebuffer.begin()+len);
\r
272 void FCPv2::SendBufferedText(const char *text)
\r
275 for(i=0; i<strlen(text); i++)
\r
277 m_sendbuffer.push_back(text[i]);
\r
281 void FCPv2::SendBufferedRaw(const char *data, const long len)
\r
284 for(i=0; i<len; i++)
\r
286 m_sendbuffer.push_back(data[i]);
\r
290 const int FCPv2::SendMessage(const char *messagename, const int fieldcount, ...)
\r
295 std::vector<char>::size_type bytecount=0;
\r
297 std::vector<char>::size_type startlen;
\r
299 startlen=m_sendbuffer.size();
\r
301 SendBufferedText(messagename);
\r
302 SendBufferedText("\n");
\r
304 va_start(args,fieldcount);
\r
306 for(i=0; i<fieldcount; i++)
\r
308 field=va_arg(args,const char *);
\r
309 val=va_arg(args,const char *);
\r
311 SendBufferedText(field);
\r
312 SendBufferedText("=");
\r
313 SendBufferedText(val);
\r
314 SendBufferedText("\n");
\r
317 SendBufferedText("EndMessage\n");
\r
319 bytecount=m_sendbuffer.size()-startlen;
\r
326 const int FCPv2::SendMessage(FCPMessage &message)
\r
328 std::vector<char>::size_type bytecount=0;
\r
329 std::vector<char>::size_type startlen;
\r
330 FCPMessage::iterator i;
\r
332 startlen=m_sendbuffer.size();
\r
334 if(message.GetName()!="")
\r
336 SendBufferedText(message.GetName().c_str());
\r
337 SendBufferedText("\n");
\r
339 for(i=message.begin(); i!=message.end(); i++)
\r
341 SendBufferedText((*i).first.c_str());
\r
342 SendBufferedText("=");
\r
343 SendBufferedText((*i).second.c_str());
\r
344 SendBufferedText("\n");
\r
347 SendBufferedText("EndMessage\n");
\r
350 bytecount=m_sendbuffer.size()-startlen;
\r
356 const int FCPv2::SendRaw(const char *data, const int datalen)
\r
358 int bytecount=datalen;
\r
362 SendBufferedRaw(data,datalen);
\r
369 void FCPv2::SocketReceive()
\r
373 len=recv(m_serversocket,m_tempbuffer,65535,0);
\r
378 m_receivebuffer.resize(m_receivebuffer.size()+len);
\r
379 std::copy(m_tempbuffer,&m_tempbuffer[len],m_receivebuffer.end()-len);
\r
382 // there was an error or server closed connection - disconnect socket
\r
389 void FCPv2::SocketSend()
\r
392 if(m_sendbuffer.size()>0)
\r
394 len=send(m_serversocket,&m_sendbuffer[0],m_sendbuffer.size(),0);
\r
397 // move remaining data in buffer to beginning of buffer (erase the bytes we just sent)
\r
398 m_sendbuffer.erase(m_sendbuffer.begin(),m_sendbuffer.begin()+len);
\r
400 // there was an error with send - disconnect socket
\r
409 const bool FCPv2::Update(const long waittime)
\r
414 m_timeval.tv_sec=waittime;
\r
415 m_timeval.tv_usec=0;
\r
417 FD_ZERO(&m_readfs);
\r
418 FD_ZERO(&m_writefs);
\r
420 FD_SET(m_serversocket,&m_readfs);
\r
422 if(m_sendbuffer.size()>0)
\r
424 FD_SET(m_serversocket,&m_writefs);
\r
427 select(m_serversocket+1,&m_readfs,&m_writefs,0,&m_timeval);
\r
429 if(FD_ISSET(m_serversocket,&m_readfs))
\r
433 if(Connected() && FD_ISSET(m_serversocket,&m_writefs))
\r