コード例 #1
0
int CNetWork::TalkWithUser_Req_Function(int sclient)
{
	printf("please follow this format, \"username,......\" \n");
	char szText[1024] = {0};
	scanf_s("%s", szText, 1024);

	char szContent[1024] = {0};
	char szUserName[32] = {0};
	g_Common.mystrchr(szText, ',', szUserName, szContent);

	Header hd;
	memset(&hd, 0, sizeof(Header));
	CreateHeader(&hd, TALK_WITH_USER_REQ, strlen(szContent)+sizeof(TalkWithUser), WU_SERVER_ID);

	Net_Send(sclient, (char*)&hd, sizeof(hd), 0);

	TalkWithUser twu;
	memset(&twu, 0, sizeof(TalkWithUser));
	twu.usLen = strlen(szContent);
	memcpy(twu.szFromUser, g_szUserName, 32);
	memcpy(twu.szToUser, szUserName, 32);
	char* szData = (char*)malloc(twu.usLen + sizeof(TalkWithUser));
	memcpy(szData, &twu, sizeof(TalkWithUser));
	memcpy(szData+sizeof(TalkWithUser), szContent, twu.usLen);

	Net_Send(sclient, szData, sizeof(TalkWithUser)+twu.usLen, 0);

	free(szData);

	return 0;
}
コード例 #2
0
ファイル: net.c プロジェクト: jjhuff/nrf24l01p_lib
void Net_Process() {
    if(_rx_packet.header.type == EMPTY) {
        return;
    }

    // Atomically copy any received packet so we can process it while still having interrupts enabled
    packet pkt;
    cli();
    memcpy(&pkt, &_rx_packet, sizeof(packet));
    _rx_packet.header.type = EMPTY;
    sei();

    switch (pkt.header.type) {
        case PING_REQ:
            //printf("Process: PING_REQ from %0x\n", pkt.header.from[0]);
            {
                ping_resp resp;
                resp.header.type = PING_RESP;
                Net_Send(pkt.header.from, &resp, sizeof(resp));
            }
            break;
        case PING_RESP:
            //printf("Process: PING_RESP from %0x\n", pkt.header.from[0]);
            if (_handlers->ping_resp) {
                (*_handlers->ping_resp)(pkt.header.from);
            }
            break;
        default:
            printf("Process: type:%d\n", pkt.header.type);
            break;
    }
}
コード例 #3
0
int CNetWork::TalkWithUser_Req_Function_CP(int sclient)
{
	printf("please follow this format, \"username,......\" \n");
	char szText[1024] = {0};
	scanf_s("%s", szText, 1024);

	char szContent[1024] = {0};
	char szUserName[32] = {0};
	g_Common.mystrchr(szText, ',', szUserName, szContent);

	char* szData = (char*)malloc(sizeof(Header) + sizeof(TalkWithUser)+strlen(szContent));
	Header* pHeader = (Header*)szData;
	CreateHeader(pHeader, TALK_WITH_USER_REQ, strlen(szContent)+sizeof(TalkWithUser), WU_SERVER_ID);
	TalkWithUser* pTalkWithUser = (TalkWithUser*)(szData+sizeof(Header));
	memcpy(pTalkWithUser->szFromUser, g_szUserName, 32);
	memcpy(pTalkWithUser->szToUser, szUserName, 32);
	pTalkWithUser->usLen = strlen(szContent);
	//这句代码错误,因为pTalkWithUser是TalkWithUser类型的指针,如果内存拷贝超出TalkWithUser的长度则拷贝失败
	//memcpy(pTalkWithUser+sizeof(TalkWithUser), szContent, strlen(szContent));
	memcpy(szData+sizeof(Header)+sizeof(TalkWithUser), szContent, strlen(szContent));
	Net_Send(sclient, szData, sizeof(Header)+sizeof(TalkWithUser)+strlen(szContent), 0);
	free(szData);

	return 0;
}
コード例 #4
0
int CNetWork::GetUserList_Req_Function_CP(int sclient)
{
	Header hd;
	CreateHeader(&hd, GET_USER_LIST_REQ, 0, WU_SERVER_ID);

	Net_Send(sclient, (char*)&hd, sizeof(hd), 0);

	return 0;
}
コード例 #5
0
int CNetWork::Keep_Alive_Req_Function(int sclient)
{
	Header hd;
	memset(&hd, 0, sizeof(Header));
	CreateHeader(&hd, KEEP_ALIVE_REQ, sizeof(KeepAliveReq), WU_SERVER_ID);

	Net_Send(sclient, (char*)&hd, sizeof(hd), 0);

	KeepAliveReq kar;
	memset(&kar, 0, sizeof(KeepAliveReq));
	kar.usAliveSeq = g_usAliveSeq;

	Net_Send(sclient, (char*)&kar, sizeof(KeepAliveReq), 0);

	if(g_usAliveSeq > 10000)
		g_usAliveSeq = 0;
	g_usAliveSeq++;

	return 0;
}
コード例 #6
0
int CNetWork::Login_Req_Function(int sclient)
{
	char szPassWord[32] = {0};
	printf("UserName:"******"%s", g_szUserName, 32);
	//getchar();
	printf("PassWord:"******"%s", szPassWord, 32);

	Header hd;
	CreateHeader(&hd, LOGIN_REQ, sizeof(LoginReq), WU_SERVER_ID);

	Net_Send(sclient, (char*)&hd, sizeof(hd), 0);

	LoginReq lr;
	memset(&lr, 0, sizeof(LoginReq));
	memcpy(lr.szUserName, g_szUserName, 32);
	memcpy(lr.szPassWord, szPassWord, 32);

	Net_Send(sclient, (char*)&lr, sizeof(LoginReq), 0);

	return 0;
}
コード例 #7
0
ファイル: inout.c プロジェクト: Unvanquished/daemonmap
void Broadcast_Setup( const char *dest ){
	address_t address;
	char sMsg[1024];

	Net_Setup();
	Net_StringToAddress( dest, &address );
	brdcst_socket = Net_Connect( &address, 0 );
	if ( brdcst_socket ) {
		// send in a header
		sprintf( sMsg, "<?xml version=\"1.0\"?><q3map_feedback version=\"" Q3MAP_STREAM_VERSION "\">" );
		NMSG_Clear( &msg );
		NMSG_WriteString( &msg, sMsg );
		Net_Send( brdcst_socket, &msg );
	}
}
コード例 #8
0
int CNetWork::Keep_Alive_Req_Function_CP(int sclient)
{
	char* szData = (char*)malloc(sizeof(Header) + sizeof(KeepAliveReq));
	Header* pHeader = (Header*)szData;
	CreateHeader(pHeader, KEEP_ALIVE_REQ, sizeof(KeepAliveReq), WU_SERVER_ID);
	KeepAliveReq* pKeepAliveReq = (KeepAliveReq*)(szData+sizeof(Header));
	pKeepAliveReq->usAliveSeq = g_usAliveSeq;
	Net_Send(sclient, szData, sizeof(Header) + sizeof(KeepAliveReq), 0);
	free(szData);

	if(g_usAliveSeq > 10000)
		g_usAliveSeq = 0;
	g_usAliveSeq++;

	return 0;
}
コード例 #9
0
int CNetWork::Login_Req_Function_CP(int sclient)
{
	char szPassWord[32] = {0};
	printf("UserName:"******"%s", g_szUserName, 32);
	//getchar();
	printf("PassWord:"******"%s", szPassWord, 32);

	char* szData = (char*)malloc(sizeof(Header) + sizeof(LoginReq));
	Header* pHeader = (Header*)szData;
	CreateHeader(pHeader, LOGIN_REQ, sizeof(LoginReq), WU_SERVER_ID);
	LoginReq* pLoginReq = (LoginReq*)(szData+sizeof(Header));
	memcpy(pLoginReq->szUserName, g_szUserName, 32);
	memcpy(pLoginReq->szPassWord, szPassWord, 32);
	Net_Send(sclient, szData, sizeof(Header) + sizeof(LoginReq), 0);
	free(szData);

	return 0;
}
コード例 #10
0
ファイル: net.c プロジェクト: jjhuff/nrf24l01p_lib
void Net_SendPing(net_address addr) {
    ping_req pkt;
    pkt.header.type = PING_REQ;
    Net_Send(addr, &pkt, sizeof(pkt));
}
コード例 #11
0
ファイル: imapnoti.c プロジェクト: ProfessorKaos64/ftequake
static qboolean IMAP_ThinkCon(imap_con_t *imap)	//false means drop the connection.
{
	char *ending;
	int len;

	//get the buffer, stick it in our read holder
	if (imap->readlen+32 >= imap->readbuffersize || !imap->readbuffer)
	{
		len = imap->readbuffersize;
		if (!imap->readbuffer)
			imap->readbuffersize = 256;
		else
			imap->readbuffersize*=2;

		ending = malloc(imap->readbuffersize);
		if (!ending)
		{
			Con_Printf("Memory is low\n");
			return false;
		}
		if (imap->readbuffer)
		{
			memcpy(ending, imap->readbuffer, len);
			free(imap->readbuffer);
		}
		imap->readbuffer = ending;
	}

	len = Net_Recv(imap->socket, imap->readbuffer+imap->readlen, imap->readbuffersize-imap->readlen-1);
	if (len>0)
	{
		imap->readlen+=len;
		imap->readbuffer[imap->readlen] = '\0';
	}

	if (imap->readlen>0)
	{
		ending = strstr(imap->readbuffer, "\r\n");

		if (ending)	//pollable text.
		{
			*ending = '\0';
//			Con_Printf("%s\n", imap->readbuffer);

			ending+=2;
			if (imap->state == IMAP_WAITINGFORINITIALRESPONCE)
			{
				//can be one of two things.
				if (!strncmp(imap->readbuffer, "* OK", 4))
				{
					IMAP_EmitCommand(imap, va("LOGIN %s %s", imap->username, imap->password));
					imap->state = IMAP_AUTHING;
				}
				else if (!strncmp(imap->readbuffer, "* PREAUTH", 9))
				{
					Con_Printf("Logged on to %s\n", imap->server);
					IMAP_EmitCommand(imap, "SELECT INBOX");
					imap->state = IMAP_AUTHED;
					imap->lastnoop = Sys_Milliseconds();
				}
				else
				{
					Con_Printf("Unexpected response from IMAP server\n");
					return false;
				}
			}
			else if (imap->state == IMAP_AUTHING)
			{
				if (!strncmp(imap->readbuffer, "* OK", 4))
				{
					Con_Printf("Logged on to %s\n", imap->server);
					IMAP_EmitCommand(imap, "SELECT INBOX");
					imap->state = IMAP_AUTHED;
					imap->lastnoop = Sys_Milliseconds();
				}
				else
				{
					Con_Printf("Unexpected response from IMAP server\n");
					return false;
				}
			}
			else if (imap->state == IMAP_AUTHED)
			{
				char *num;
				num = imap->readbuffer;
				if (!strncmp(imap->readbuffer, "* SEARCH ", 8))	//we only ever search for recent messages. So we fetch them and get sender and subject.
				{
					char *s;
					s = imap->readbuffer+8;
					num = NULL;
					while(*s)
					{
						s++;
						num = s;
						while (*s >= '0' && *s <= '9')
							s++;

						IMAP_EmitCommand(imap, va("FETCH %i ENVELOPE", atoi(num)));	//envelope so that it's all one line.
					}
				}
				else if (imap->readbuffer[0] == '*' && imap->readbuffer[1] == ' ')
				{
					num = imap->readbuffer+2;
					while(*num >= '0' && *num <= '9')
					{
						num++;
					}
					if (!strcmp(num, " RECENT"))
					{
						if (atoi(imap->readbuffer+2) > 0)
						{
							IMAP_EmitCommand(imap, "SEARCH RECENT");
						}
					}
					else if (!strncmp(num, " FETCH (ENVELOPE (", 18))
					{
						char from[256];
						char subject[256];
						char date[256];

						num += 18;

						num = STR_Parse(num, date, sizeof(date), "");
						num = STR_Parse(num, subject, sizeof(subject), "");
//						Con_Printf("Date/Time: %s\n", date);

						num = IMAP_AddressStructure(num, from, sizeof(from));


						if ((rand() & 3) == 3)
						{
							if (rand()&1)
								Con_Printf("\n^2New spam has arrived\n");
							else
								Con_Printf("\n^2You have new spam\n");
						}
						else if (rand()&1)
							Con_Printf("\n^2New mail has arrived\n");
						else
							Con_Printf("\n^2You have new mail\n");

						Con_Printf("Subject: %s\n", subject);
						Con_Printf("From: %s\n", from);

						SCR_CenterPrint(va("NEW MAIL HAS ARRIVED\n\nTo: %s@%s\nFrom: %s\nSubject: %s", imap->username, imap->server, from, subject));

						//throw the rest away.
					}
				}
			}
			else
			{
				Con_Printf("Bad client state\n");
				return false;
			}
			imap->readlen -= ending - imap->readbuffer;
			memmove(imap->readbuffer, ending, strlen(ending)+1);
		}
	}
	if (imap->drop)
		return false;

	if (imap->state == IMAP_AUTHED)
	{
		if (imap->lastnoop + imap_checkfrequency < Sys_Milliseconds())
		{	//we need to keep the connection reasonably active

			IMAP_EmitCommand(imap, "SELECT INBOX");	//this causes the recent flags to be reset. This is the only way I found.
			imap->lastnoop = Sys_Milliseconds();
		}
	}

	if (imap->sendlen)
	{
		len = Net_Send(imap->socket, imap->sendbuffer, imap->sendlen);
		if (len>0)
		{
			imap->sendlen-=len;
			memmove(imap->sendbuffer, imap->sendbuffer+len, imap->sendlen+1);
		}
	}
	return true;
}
コード例 #12
0
ファイル: inout.c プロジェクト: clbr/netradiant
// send a node down the stream, add it to the document
void xml_SendNode (xmlNodePtr node)
{
  xmlBufferPtr xml_buf;
  char xmlbuf[MAX_NETMESSAGE]; // we have to copy content from the xmlBufferPtr into an aux buffer .. that sucks ..
  // this index loops through the node buffer
  int pos = 0;
  int size;

  xmlAddChild( doc->children, node );

  if (brdcst_socket)
  {
    xml_buf = xmlBufferCreate();
    xmlNodeDump( xml_buf, doc, node, 0, 0 );

    // the XML node might be too big to fit in a single network message
    // l_net library defines an upper limit of MAX_NETMESSAGE
    // there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe
    // if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages
    while (pos < (int)xml_buf->use)
    {
      // what size are we gonna send now?
      (xml_buf->use - pos < MAX_NETMESSAGE - 10) ? (size = xml_buf->use - pos) : (size = MAX_NETMESSAGE - 10);
      //++timo just a debug thing
      if (size == MAX_NETMESSAGE - 10)
        Sys_FPrintf (SYS_NOXML, "Got to split the buffer\n");
      memcpy( xmlbuf, xml_buf->content+pos, size);
      xmlbuf[size] = '\0';
      NMSG_Clear( &msg );
      NMSG_WriteString (&msg, xmlbuf );
      Net_Send(brdcst_socket, &msg );
      // now that the thing is sent prepare to loop again
      pos += size;
    }

#if 0
    // NOTE: the NMSG_WriteString is limited to MAX_NETMESSAGE
    // we will need to split into chunks
    // (we could also go lower level, in the end it's using send and receiv which are not size limited)
    //++timo FIXME: MAX_NETMESSAGE is not exactly the max size we can stick in the message
    //  there's some tweaking to do in l_net for that .. so let's give us a margin for now

    //++timo we need to handle the case of a buffer too big to fit in a single message
    // try without checks for now
    if (xml_buf->use > MAX_NETMESSAGE-10 )
    {
      // if we send that we are probably gonna break the stream at the other end..
      // and Error will call right there
      //Error( "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
      Sys_FPrintf (SYS_NOXML, "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
      xml_buf->content[xml_buf->use]='\0'; //++timo this corrupts the buffer but we don't care it's for printing
      Sys_FPrintf (SYS_NOXML, xml_buf->content);

    }

    size = xml_buf->use;
    memcpy( xmlbuf, xml_buf->content, size );
    xmlbuf[size] = '\0';
    NMSG_Clear( &msg );
    NMSG_WriteString (&msg, xmlbuf );
    Net_Send(brdcst_socket, &msg );
#endif

    xmlBufferFree( xml_buf );
  }  
}
コード例 #13
0
ファイル: pop3noti.c プロジェクト: ProfessorKaos64/ftequake
static qboolean POP3_ThinkCon(pop3_con_t *pop3)	//false means drop the connection.
{
	char *ending;
	int len;

	if (pop3->state == POP3_NOTCONNECTED && !pop3->socket)
	{
		if (pop3->lastnoop + pop3_checkfrequency < Sys_Milliseconds())
		{	//we need to recreate the connection now.
			pop3->lastnoop = Sys_Milliseconds();
			POP3_CreateConnection(pop3->server, pop3->username, pop3->password);
		}

		return true;
	}

	//get the buffer, stick it in our read holder
	if (pop3->readlen+32 >= pop3->readbuffersize || !pop3->readbuffer)
	{
		len = pop3->readbuffersize;
		if (!pop3->readbuffer)
			pop3->readbuffersize = 256;
		else
			pop3->readbuffersize*=2;

		ending = malloc(pop3->readbuffersize);
		if (!ending)
		{
			Con_Printf("Memory is low\n");
			return false;
		}
		if (pop3->readbuffer)
		{
			memcpy(ending, pop3->readbuffer, len);
			free(pop3->readbuffer);
		}
		pop3->readbuffer = ending;
	}

	len = Net_Recv(pop3->socket, pop3->readbuffer+pop3->readlen, pop3->readbuffersize-pop3->readlen-1);
	if (len>0)
	{
		pop3->readlen+=len;
		pop3->readbuffer[pop3->readlen] = '\0';
	}

	if (pop3->readlen>0)
	{
		ending = strstr(pop3->readbuffer, "\r\n");

		if (ending)	//pollable text.
		{
			*ending = '\0';
//			Con_Printf("^2%s\n", pop3->readbuffer);

			ending+=2;
			if (pop3->state == POP3_WAITINGFORINITIALRESPONCE)
			{
				if (!strncmp(pop3->readbuffer, "+OK", 3))
				{
					char *angle1;
					char *angle2 = NULL;
					angle1 = strchr(pop3->readbuffer, '<');
					if (angle1)
					{
						angle2 = strchr(angle1+1, '>');
					}
					if (angle2)
					{	//just in case
						angle2[1] = '\0';

						POP3_EmitCommand(pop3, va("APOP %s %s", pop3->username, MD5_GetPop3APOPString(angle1, pop3->password)));
						pop3->state = POP3_AUTHING2;
					}
					else
					{
						POP3_EmitCommand(pop3, va("USER %s", pop3->username));
						pop3->state = POP3_AUTHING;
					}
				}
				else
				{
					Con_Printf("Unexpected response from POP3 server\n");
					return false;	//some sort of error.
				}
			}
			else if (pop3->state == POP3_AUTHING)
			{
				if (!strncmp(pop3->readbuffer, "+OK", 3))
				{
					POP3_EmitCommand(pop3, va("PASS %s", pop3->password));
					pop3->state = POP3_AUTHING2;
				}
				else
				{
					Con_Printf("Unexpected response from POP3 server.\nCheck username/password\n");
					return false;	//some sort of error.
				}
			}
			else if (pop3->state == POP3_AUTHING2)
			{
				if (!strncmp(pop3->readbuffer, "+OK", 3))
				{
					POP3_EmitCommand(pop3, "UIDL");
					pop3->state = POP3_LISTING;
					pop3->lastnoop = Sys_Milliseconds();
				}
				else
				{
					Con_Printf("Unexpected response from POP3 server.\nCheck username/password\n");
					return false;
				}
			}
			else if (pop3->state == POP3_LISTING)
			{
				if (!strncmp(pop3->readbuffer, "-ERR", 4))
				{
					Con_Printf("Unexpected response from POP3 server.\nUIDL not supported?\n");
					return false;
				}
				else if (!strncmp(pop3->readbuffer, "+OK", 3))
				{
				}
				else if (!strncmp(pop3->readbuffer, ".", 1))	//we only ever search for recent messages. So we fetch them and get sender and subject.
				{
					if (!pop3->numtoretrieve)
					{
						pop3->state = POP3_QUITTING;
						POP3_EmitCommand(pop3, "QUIT");
					}
					else
					{
						pop3->state = POP3_RETRIEVING;
						POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve]));
					}
				}
				else
				{
					char *s;
					s = pop3->readbuffer;
					if (*s)
					{
						s++;
						while (*s >= '0' && *s <= '9')
							s++;
						while (*s == ' ')
							s++;
					}

					if (POP3_IsMessageUnique(s))
						if (pop3->numtoretrieve < sizeof(pop3->retrlist)/sizeof(pop3->retrlist[0]))
							pop3->retrlist[pop3->numtoretrieve++] = atoi(pop3->readbuffer);
				}
			}
			else if (pop3->state == POP3_RETRIEVING)
			{
				if (!strncmp(pop3->readbuffer, "+OK", 3))
				{
					pop3->msgsubject[0] = '\0';
					pop3->msgfrom[0] = '\0';

					pop3->state = POP3_HEADER;
				}
				else
				{	//erm... go for the next?
					if (!pop3->numtoretrieve)
					{
						pop3->state = POP3_QUITTING;
						POP3_EmitCommand(pop3, "QUIT");
					}
					else
						POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve]));
				}
			}
			else if (pop3->state == POP3_HEADER)
			{
				if (!strnicmp(pop3->readbuffer, "From: ", 6))
					strlcpy(pop3->msgfrom, pop3->readbuffer + 6, sizeof(pop3->msgfrom));
				else if (!strnicmp(pop3->readbuffer, "Subject: ", 9))
					strlcpy(pop3->msgsubject, pop3->readbuffer + 9, sizeof(pop3->msgsubject));
				else if (!strncmp(pop3->readbuffer, ".", 1))
				{
					Con_Printf("New message:\nFrom: %s\nSubject: %s\n", pop3->msgfrom, pop3->msgsubject);

					if (BUILTINISVALID(SCR_CenterPrint))
						SCR_CenterPrint(va("NEW MAIL HAS ARRIVED\n\nTo: %s@%s\nFrom: %s\nSubject: %s", pop3->username, pop3->server, pop3->msgfrom, pop3->msgsubject));

					if (!pop3->numtoretrieve)
					{
						pop3->state = POP3_QUITTING;
						POP3_EmitCommand(pop3, "QUIT");
					}
					else
					{
						pop3->state = POP3_RETRIEVING;
						POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve]));
					}
				}
				else if (!*pop3->readbuffer)
					pop3->state = POP3_BODY;
			}
			else if (pop3->state == POP3_BODY)
			{
				if (!strncmp(pop3->readbuffer, "..", 2))
				{
					//line of text, skipping first '.'
					Con_Printf("%s\n", pop3->readbuffer+1);
				}
				else if (!strncmp(pop3->readbuffer, ".", 1))
				{
					Con_Printf("New message:\nFrom: %s\nSubject: %s\n", pop3->msgfrom, pop3->msgsubject);
					if (BUILTINISVALID(SCR_CenterPrint))
						SCR_CenterPrint(va("NEW MAIL HAS ARRIVED\n\nTo: %s@%s\nFrom: %s\nSubject: %s", pop3->username, pop3->server, pop3->msgfrom, pop3->msgsubject));

					if (!pop3->numtoretrieve)
					{
						pop3->state = POP3_QUITTING;
						POP3_EmitCommand(pop3, "QUIT");
					}
					else
					{
						pop3->state = POP3_RETRIEVING;
						POP3_EmitCommand(pop3, va("RETR %i", pop3->retrlist[--pop3->numtoretrieve]));
					}
				}
				else
				{
					//normal line of text
					Con_Printf("%s\n", pop3->readbuffer);
				}
			}
			else if (pop3->state == POP3_QUITTING)
			{
				pop3->state = POP3_NOTCONNECTED;
				Net_Close(pop3->socket);
				pop3->lastnoop = Sys_Milliseconds();
				pop3->socket = 0;
				pop3->readlen = 0;
				pop3->sendlen = 0;
				return true;
			}
			else
			{
				Con_Printf("Bad client state\n");
				return false;
			}
			pop3->readlen -= ending - pop3->readbuffer;
			memmove(pop3->readbuffer, ending, strlen(ending)+1);
		}
	}
	if (pop3->drop)
		return false;

	if (pop3->sendlen)
	{
		len = Net_Send(pop3->socket, pop3->sendbuffer, pop3->sendlen);
		if (len>0)
		{
			pop3->sendlen-=len;
			memmove(pop3->sendbuffer, pop3->sendbuffer+len, pop3->sendlen+1);
		}
	}
	return true;
}