#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);
}