User:Antigng-bot/network

维基百科,自由的百科全书
#include <winsock2.h>
#include <process.h>
#include <stdio.h>
#include <string.h>
#include "mem.h"
#include "network.h"
#include "auth.h"
#pragma comment (lib,"ws2_32.lib")
BUCKET buckpool=0;
int bucknum=0;
WSADATA wsadata;
CRITICAL_SECTION mcs;
static int buckfree(BUCKET p)
{
	EnterCriticalSection(&mcs);
	if(bucknum<BUCKMAX)
	{
		p->next=buckpool;
		bucknum++;
		buckpool=p;
		LeaveCriticalSection(&mcs);
		return 0;
	}
	else
	{
		LeaveCriticalSection(&mcs);
		s_free(p);
		return 0;
	}
}
int buckini(int count)
{
	int i=0;
	BUCKET p;
	InitializeCriticalSection(&mcs);
	buckpool=0;
	bucknum=0;
	for(i=0;i<count&&i<BUCKMAX;i++)
	{
		p=(BUCKET)s_malloc(sizeof(struct bucket));
		buckfree(p);
	}
	WSAStartup(MAKEWORD(2,2),&wsadata);
	return 0;
}
int buckdestroy()
{
	BUCKET p;
	EnterCriticalSection(&mcs);
	while(buckpool)
	{
		p=buckpool->next;
		s_free(buckpool);
		buckpool=p;
	}
	bucknum=0;
	LeaveCriticalSection(&mcs);
	WSACleanup();
	return 0;
}
static BUCKET buckalloc()
{
	BUCKET p;
	EnterCriticalSection(&mcs);
	if(bucknum>0)
	{
		bucknum--;
		p=buckpool;
		buckpool=buckpool->next;
		LeaveCriticalSection(&mcs);
		p->next=0;
		return p;
	}
	else
	{
		bucknum=0;
		LeaveCriticalSection(&mcs);
		p=(BUCKET)s_malloc(sizeof(struct bucket));
		p->next=0;
		return p;
	}
}

static int buckbatchfree(BUCKET start,BUCKET end,int length)
{
	BUCKET p;
	EnterCriticalSection(&mcs);
	if(bucknum<BUCKMAX&&end)
	{
		end->next=buckpool;
		buckpool=start;
		bucknum+=length;
		LeaveCriticalSection(&mcs);
		return 0;
	}
	else
	{
		LeaveCriticalSection(&mcs);
		p=start;
		while(p)
		{
			start=p->next;
			s_free(p);
			p=start;
		}
	}
	return 0;
}
const DWORD rcvlimit=1000*TIMEOUT;
static SOCKET prepare_socket(unsigned short port)
{
	struct sockaddr_in addr;
	SOCKET s=socket(AF_INET,SOCK_STREAM,0);
	if(s==INVALID_SOCKET) return INVALID_SOCKET;
	if(setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(const char *)&rcvlimit,sizeof(rcvlimit))==SOCKET_ERROR)
	{
		closesocket(s);
		return INVALID_SOCKET;
	}
	addr.sin_family=AF_INET;
	addr.sin_port=htons(port);
	addr.sin_addr.s_addr=inet_addr("127.0.0.1");
	if(connect(s,(SOCKADDR *)&addr,sizeof(addr))==SOCKET_ERROR)
	{
		closesocket(s);
		return INVALID_SOCKET;
	}
	return s;
}
static int recv_till_close(SOCKET s,HTTP res)
{
	int sst=0;
	int flag=0;
	BUCKET b=buckalloc();
	char *g=b->content;
	for(;;)
	{
		sst=recv(s,g,BUFFERMAX,0);
		if(sst>0)
		{
			g[sst]=0;
			hputs(g,BUFFERMAX,res);
			flag=1;
		}
		else if(sst<0)
		{
			flag=0;
			break;
		}
		else break;
	}
	buckfree(b);
	return flag;
}
int get(const char *url,unsigned short port,int lg, HTTP result)
{
	int err;
	SOCKET s;
	char req[8192];
	int requestlength;
	if(lg)
	{
		AcquireSRWLockShared(&rwcs);
		requestlength=sprintf(req,
			"GET %s HTTP/1.0\r\n"
			"Host:127.0.0.1\r\n"
			"User-agent:Antigng-bot/0.0\r\n"
			"Cookie:%s\r\n"
			"\r\n",
			url,session);
		ReleaseSRWLockShared(&rwcs);
	}
	else
	{
		requestlength=sprintf(req,
			"GET %s HTTP/1.0\r\n"
			"Host:127.0.0.1\r\n"
			"User-agent:Antigng-bot/0.0\r\n"
			"\r\n",
			url,lg?"\r\n":"");
	}
	s=prepare_socket(port);
	if(s==INVALID_SOCKET)
	{
		return -1;
	}
	err=send(s,req,requestlength,0);
	if(err<0)
	{
		shutdown(s,SD_BOTH);
		closesocket(s);
		return -2;
	}
	err=!recv_till_close(s,result);
	hrewind(result);
	shutdown(s,SD_BOTH);
	closesocket(s);
	return err?-3:0;
}

int post(const char *url,const char *content,unsigned short port,int lg, HTTP result)
{
	int err;
	SOCKET s;
	char *req;
	int requestlength;
	s=prepare_socket(port);
	if(s==INVALID_SOCKET)
	{
		return -1;
	}
	req=(char *)s_calloc(1024*1024,1);
	if(lg)
	{
		AcquireSRWLockShared(&rwcs);
		requestlength=sprintf(req,
			"POST %s HTTP/1.0\r\n"
			"Host:127.0.0.1\r\n"
			"User-agent:Antigng-bot/0.0\r\n"
			"Cookie:%s\r\n"
			"Content-type:application/x-www-form-urlencoded\r\n"
			"Content-length:%d\r\n"
			"\r\n"
			"%s\r\n"
			"\r\n",
			url,session,strlen(content),content);
		ReleaseSRWLockShared(&rwcs);
	}
	else
	{
		requestlength=sprintf(req,
			"POST %s HTTP/1.0\r\n"
			"Host:127.0.0.1\r\n"
			"User-agent:Antigng-bot/0.0\r\n"
			"Content-type:application/x-www-form-urlencoded\r\n"
			"Content-length:%d\r\n"
			"\r\n"
			"%s\r\n"
			"\r\n",
			url,strlen(content),content);
	}
	err=send(s,req,requestlength,0);
	s_free(req);
	if(err<0)
	{
		shutdown(s,SD_BOTH);
		closesocket(s);
		return -2;
	}
	err=!recv_till_close(s,result);
	hrewind(result);
	shutdown(s,SD_BOTH);
	closesocket(s);
	return err?-3:0;
}
static int smartsend(SOCKET s, HTTP content)
{
	const struct bucket *b_buffer;
	int err=0;
	int count;
	hrewind(content);
	for(count=0,b_buffer=content->buffer;count<content->buffnum;count++,b_buffer=b_buffer->next)
	{
		err=send(s,b_buffer->content,BUFFERMAX,0);
		if(err<0) return err;
	}
	err=send(s,b_buffer->content,content->last-content->tailtxt+1,0);
	return err;
}
int smartpost(const char *url,HTTP content,const char *aft,unsigned short port,int lg,struct http *result)
{
	int err;
	SOCKET s;
	char req[8192];
	int requestlength;
	if(lg)
	{
		AcquireSRWLockShared(&rwcs);
		requestlength=sprintf(req,
			"POST %s HTTP/1.0\r\n"
			"Host:127.0.0.1\r\n"
			"User-agent:Antigng-bot/0.0\r\n"
			"Cookie:%s\r\n"
			"Content-type:application/x-www-form-urlencoded\r\n"
			"Content-length:%d\r\n"
			"\r\n",
			url,session,(int)hlen(content)+(int)strlen(aft));
		ReleaseSRWLockShared(&rwcs);
	}
	else
	{
		requestlength=sprintf(req,
			"POST %s HTTP/1.0\r\n"
			"Host:127.0.0.1\r\n"
			"User-agent:Antigng-bot/0.0\r\n"
			"Content-type:application/x-www-form-urlencoded\r\n"
			"Content-length:%d\r\n"
			"\r\n",
			url,(int)hlen(content)+(int)strlen(aft));
	}
	s=prepare_socket(port);
	if(s==INVALID_SOCKET)
	{
		return -1;
	}
	err=send(s,req,requestlength,0);
	if(err<0)
	{
		shutdown(s,SD_BOTH);
		closesocket(s);
		return -2;
	}
	err=smartsend(s,content);
	if(err<0)
	{
		shutdown(s,SD_BOTH);
		closesocket(s);
		return -2;
	}
	err=send(s,aft,strlen(aft),0);
	if(err<0)
	{
		shutdown(s,SD_BOTH);
		closesocket(s);
		return -2;
	}
	err=send(s,"\r\n\r\n",4,0);
	if(err<0)
	{
		shutdown(s,SD_BOTH);
		closesocket(s);
		return -2;
	}
	err=!recv_till_close(s,result);
	WRITE(0,result);
	hrewind(result);
	shutdown(s,SD_BOTH);
	closesocket(s);
	return err?-3:0;
}
char SEQREAD(struct http *f)
{
	if(f->error) return 0;
	if(!f->cur)
	{
		f->error=1;
		return 0;
	}
	if(f->buff<f->buffnum)
	{
		char *ch=f->curtxt;
		if(ch<f->curlast)
		{
			f->curtxt++;
			return *ch;
		}
		else
 		{
			BUCKET cur=f->cur->next;
			if(cur)
			{
				f->cur=cur;
				f->curtxt=cur->content;
				f->curlast=f->curtxt+BUFFERMAX-1;
			}
			else f->error=1;
			f->buff++;
			return *ch;
		}
	}
	else
	{
		char *ch=f->curtxt;
		if(ch<f->last)
		{
			f->curtxt++;
			return *ch;
		}
		else
		{
			f->error=1;
			return *ch;
		}
	}
}


int FORWARD (struct http *f)
{
	if(f->error) return -1;
	if(f->buff<f->buffnum)
	{
		if(f->curtxt<f->curlast)
		{
			f->curtxt++;
			return 0;
		}
		else
 		{
			f->buff++;
			f->cur=f->cur->next;
			if(f->cur)
			{
				f->curtxt=f->cur->content;
				f->curlast=f->curtxt+BUFFERMAX-1;
			}
			return 0;
		}
	}
	else
	{
		if(f->curtxt<f->last)
		{
			f->curtxt++;
			return 0;
		}
		else
		{
			f->error=1;
			return 1;
		}
	}
}
int WRITE(char c,HTTP f)
{
	if(!f->buffer)
	{
		f->buffer=buckalloc();
		f->tail=f->cur=f->buffer;
		f->tailtxt=f->last=f->curtxt=f->cur->content;
		f->curlast=f->curtxt+BUFFERMAX-1;
	}
	else if(f->flag)
	{
		BUCKET b;
		f->flag=0;
		f->buff++;
		f->buffnum++;
		b=f->cur;
		b->next=buckalloc();
		b=b->next;
		f->tail=f->cur=b;
		f->tailtxt=f->last=f->curtxt=b->content;
		f->curlast=f->curtxt+BUFFERMAX-1;
	}
	else f->last++;
	*(f->curtxt)=c;
	if(f->curtxt==f->curlast)
	{
		f->flag=1;
	}
	f->curtxt++;
	return 0;
}
char READ(struct http *f)
{
	if(f->error) return 0;
	if(!f->cur)
	{
		f->error=1;
		return 0;
	}
	return *(f->curtxt);
}
int hgets(char *buffer,int size,struct http *f)
{
	int i=0;
	while(i<size&&!heof(f))
	{
		if((buffer[i]=hgetc(f))=='\n')
		{
			i++;
			break;
		}
		i++;
	}
	buffer[i]=0;
	return i;
}
HTTP hopen()
{
	return (struct http *)s_calloc(sizeof(struct http),1);
}
int hclose(HTTP f)
{
	if(!f->buffer) return 1;
	buckbatchfree(f->buffer,f->tail,f->buffnum+1);
	s_free(f);
	return 0;
}
int hputs(const char *content,int length,HTTP f)
{
	int count=0;
	int buf_remain=0;
	char *ptobuf=0;
	if(f->buffer)
	{
		ptobuf=f->curtxt;
		buf_remain=f->curlast-ptobuf+1;
		if(buf_remain>length)
		{
			while(count<length)
			{
				if(!(ptobuf[count]=content[count])) break;
				count++;
			}
			f->last=ptobuf+count-1;
			f->curtxt=ptobuf+count;
			return count;
		}
		else
		{
			while(count<buf_remain)
			{
				if(!(ptobuf[count]=content[count])) break;
				count++;
			}
			if(count<buf_remain)
			{
				f->last=ptobuf+count-1;
				f->curtxt=ptobuf+count;
				return count;
			}
			else
			{
				if(count==length)
				{
					f->last=ptobuf+count-1;
					f->curtxt=ptobuf+count;
					f->flag=1;
					return count;
				}
			}
		}
	}
	else if(!(length)||!(*content))
	{
		return 0;
	}
	{
		int basecount=count;
		BUCKET b=f->cur;
		for(;;)
		{
			if(!f->buffer)
			{
				b=f->buffer=buckalloc();
				ptobuf=b->content;
			}
			else
			{
				f->buff++;
				f->buffnum++;
				b->next=buckalloc();
				b=b->next;
				ptobuf=b->content;
			}
			buf_remain=BUFFERMAX;
			basecount=count;
			if(length-basecount<buf_remain)
			{
				while(count<length)
				{
					if(!(ptobuf[count-basecount]=content[count])) break;
					count++;
				}
				f->last=ptobuf+count-basecount-1;
				f->curtxt=ptobuf+count-basecount;
				f->tail=f->cur=b;
				f->tailtxt=b->content;
				f->curlast=b->content+BUFFERMAX-1;
				f->flag=0;
				break;
			}
			else
			{
				while(count-basecount<buf_remain)
				{
					if(!(ptobuf[count-basecount]=content[count])) break;
					count++;
				}
				if(count-basecount<buf_remain)
				{
					f->last=ptobuf+count-basecount-1;
					f->curtxt=ptobuf+count-basecount;
					f->tail=f->cur=b;
					f->tailtxt=b->content;
					f->curlast=b->content+BUFFERMAX-1;
					f->flag=0;
					break;
				}
				else
				{
					if(count==length)
					{
						f->last=ptobuf+count-basecount-1;
						f->curtxt=ptobuf+count-basecount;
						f->tail=f->cur=b;
						f->tailtxt=b->content;
						f->curlast=b->content+BUFFERMAX-1;
						f->flag=1;
						break;
					}
				}
			}
			f->tail=f->cur=b;
			f->tailtxt=b->content;
			f->curlast=b->content+BUFFERMAX-1;
		}
	}
	return count;
}

int hrewind(HTTP f)
{
	f->buff=0;
	f->error=0;
	f->cur=f->buffer;
	if(f->cur)
	{
		f->curtxt=f->cur->content;
		f->curlast=f->curtxt+BUFFERMAX-1;
	}
	return 0;
}
int hlen(HTTP f)
{
	if(!f->buffer) return 0;
	return (f->last-f->tailtxt+1)+f->buffnum*(BUFFERMAX);
}
int hcur(HTTP f)
{
	if(!f->buffer) return -1;
	return f->curtxt-f->cur->content+f->buff*BUFFERMAX;
}
int skipresponseheader(HTTP f,int enable)
{
	int flag=0;
	int signal=0;
	int counter=0;
	const char *set_cookie="set-cookie:";
	char cookie[512],attr[512];
	char ch=0;
	while(!heof(f))
	{
		ch=hgetc(f);
		if(ch=='\r')
		{
			if(flag==0)
			{
				flag=1;
			}
			else if(flag==2)
			{
				flag=3;
			}
			else
			{
				flag=0;
			}
		}
		else if(ch=='\n')
		{
			if(flag==1)
			{
				flag=2;
			}
			else if(flag==3)
			{
				flag=4;
				break;
			}
			else
			{
				flag=0;
			}
		} 
		else
		{
			if(flag==2)
			{
				if(enable)
				{
					counter=0;
					signal=1;
				}
			}
			flag=0;
		}
		switch(signal)
		{
		case 0:
			break;
		case 1:
			if((unsigned char)(ch-'A')<='Z'-'A')
			{
				ch+='a'-'A';
			}
			if(ch!=set_cookie[counter])
			{
				signal=0;
			}
			else
			{
				counter++;
				if(counter==11)
				{
					signal=2;
					counter=0;
				}
			}
			break;
		case 2:
			if(ch==';')
			{
				cookie[counter]=0;
				counter=0;
				signal=3;
			}
			else if(ch=='\r')
			{
				cookie[counter]=0;
				attr[0]=0;
				sessionmanage(cookie,attr);
				signal=0;
			}
			else if(counter>510)
			{
				signal=0;
			}
			else
			{
				cookie[counter++]=ch;
			}
			break;
		case 3:
			if(ch=='\r')
			{
				attr[counter]=0;
				sessionmanage(cookie,attr);
				signal=0;
			}
			else if(counter>510)
			{
				signal=0;
			}
			else
			{
				attr[counter++]=ch;
			}
			break;
		}
	}
	return (flag!=4);
}