跳转到内容

User:Antigng-bot/fix (multithread)

维基百科,自由的百科全书

<source lang="c">

  1. include <stdio.h>
  2. include <string.h>
  3. include <malloc.h>
  4. include <process.h>
  5. include <windows.h>
  6. include "network.h"
  7. include "convert.h"

struct problemlist { char title[200]; struct problemlist *next; } ; struct editargv {

   int count;

char *title; char *newtext; }; char token[100]={0}; char cookie[200]={0}; char session[50]={0}; int cookielength=0; int sessionlength=0; int tokenlock=0; int threadnumber=0; int hastoken=0; int login(); struct problemlist *query(char *target,char *spacenum); void show(struct problemlist *head); int proceed(struct problemlist* p,struct problemlist **new,int depth); int proceedchild(char *title); int edit(struct editargv *p); int gettoken(); int sgets(char *a,char *b,int *c,int max); int tokenmanage(); int main() { struct problemlist *head; if(login()) return 1; _beginthread(tokenmanage,0,0); head=query(G2U("外部连接"),"0"); show(head); while(head) { proceed(head,&head,200); }

       hastoken=-1;

return 0; } int login() { /*该函数用于登录,登录成功会设置全局变量cookie。内容从略。

        */

}; int tokenmanage() { while(hastoken!=-1) { if(!hastoken) {printf("change token\n");gettoken();} Sleep(1); } return 0; } int gettoken() { const char *match2="tokens csrftoken=\""; char line[2000],*result; int i,j,flag=0,resultcount=0,length2; length2=strlen(match2); result=(char *)calloc(100*1024,1);

   get("https://zh.wikipedia.org/w/api.php?action=query&format=xml&meta=tokens",1,&result);

resultcount=0; while(result[resultcount]) { sgets(line,result,&resultcount,1000); i=0;

if(line[i]=='<') { flag=0; while(line[i]) { for(j=0;j<length2;j++) { if(line[i+j]!=match2[j]) break; } if(j==length2) { flag=1; break; } i++;

} if(flag) break; } } if(!flag) { printf("token not found\n"); free(result); return -3; } i=i+j;j=0; while(tokenlock>0); tokenlock--; while(line[i+j]!='+'&&line[i+j]!=0) { token[j]=line[i+j]; j++; } token[j]=0; strcat(token,"%2B%5C"); tokenlock++;

   free(result);

hastoken=1; return 0; } struct problemlist *query(char *target,char *spacenum) { char line[2000]={0},url[1000]={0},snd[1000]={0},ecd[200]={0},title[200]={0},sroffset[100]={0},*result; const char *match="title=\"",*nextmatch="<continue sroffset=\""; const int length=strlen(match),nextlength=strlen(nextmatch); int i=0,j=0,k=0,l=0,next=0,count=0,resultlength=0;

struct problemlist *pre,*temp,*head=0; result=(char *)calloc(1024*1024,1); strcpy(url,"https://zh.wikipedia.org/w/api.php?action=query&list=search&format=xml&srlimit=500&srsearch="); URLEncode(target,strlen(target),ecd,200); strcat(url,ecd); strcat(url,"&srnamespace="); strcat(url,spacenum); do {

strcpy(snd,url); if(next) { strcat(snd,"&sroffset="); strcat(snd,sroffset); }

       get(snd,1,&result);

resultlength=0; do { sgets(line,result,&resultlength,1500); }while(line[0]!='<'&&result[resultlength]); next=0; do { i=0; while(line[i]) { for(j=0;j<nextlength;j++) { if(line[i+j]!=nextmatch[j]) break; } if(j==nextlength) {

for(k=0;line[i+j+k]!='\"'&&line[i+j+k]!=0;k++) { sroffset[k]=line[i+j+k]; } sroffset[k]=0; if(line[i+j+k]=='\"') next=1; i=i+j+k;j=0;k=0; continue;

} else i=i+j; for(j=0;j<length;j++) { if(line[i+j]!=match[j]) break; } if(j==length) {

for(k=0,l=0;line[i+j+k]!='\"'&&line[i+j+k]!=0;) { if(line[i+j+k]=='&') {

if(line[i+j+k+1]=='#'&&line[i+j+k+2]=='0'&&line[i+j+k+3]=='3'&&line[i+j+k+4]=='9'&&line[i+j+k+5]==';') { title[l]='\; l++; title[l]=0; k+=6; continue; } else if(line[i+j+k+1]=='a'&&line[i+j+k+2]=='m'&&line[i+j+k+3]=='p'&&line[i+j+k+4]==';') { title[l]='&'; l++; title[l]=0; k+=5; continue; } else if(line[i+j+k+1]=='q'&&line[i+j+k+2]=='u'&&line[i+j+k+3]=='o'&&line[i+j+k+4]=='t') { title[l]='\"'; l++; title[l]=0; k+=6; continue; } } title[l]=line[i+j+k]; l++;k++; } title[l]=0; if(line[i+j+k]=='\"') { if(!head) { pre=temp=(struct problemlist *)malloc(sizeof(struct problemlist)); head=temp; } else { pre=temp; temp=(struct problemlist *)malloc(sizeof(struct problemlist)); pre->next=temp; } strcpy(temp->title,title); temp->next=0; i=i+j+k;j=0;k=0; continue; } } i++; } sgets(line,result,&resultlength,1500); }while(result[resultlength]);

    resultlength=0;

count++; }while(next); free(result); return head; }

void show(struct problemlist *head) {

  FILE *f;
  f=fopen("b.txt","w+");
  while(head)
  {
    fprintf(f,"%s\n",head->title);

head=head->next;

  } 
  fclose(f);

}

int proceed(struct problemlist* p,struct problemlist **new,int depth) { struct problemlist *pre,*head; char threadpool[250][300]; int count=0; if(!p) return -1;

head=p; for(count=0;count< depth&&head;count++,pre=head,head=head->next,free(pre)) { strcpy(threadpool[count],head->title); while(!hastoken)

              {
                   Sleep(100);
               }

_beginthread(proceedchild,0,threadpool[count]);

               threadnumber++;

} *new=head; printf("waiting for threads\n"); while(threadnumber) { Sleep(50); } return 0; } int proceedchild(char *title) { int i=0,j,cl,flag,status=0,todo=0,resultlength; char c[1000],line[2000],tt[500],*newtext,ch,*result; char *match=G2U("外部连接"),*replace=G2U("外部链接"); const int length=strlen(match),rpl=strlen(replace); struct editargv point; newtext=(char *)malloc(1024*1024); result=(char *)calloc(1024*1024,1); strcpy(c,"https://zh.wikipedia.org/w/index.php?action=raw&title="); URLEncode(title,strlen(title),tt,500); strcat(c,tt); get(c,0,&result); resultlength=0; flag=0; while(result[resultlength])

   {
 	  ch=result[resultlength];

resultlength++;

 	  if(ch=='\r')
 	  {
 	  	if(flag==0) flag=1;
 	  	 else if(flag==2) flag=3;
 	  	

}

if(ch=='\n') { if(flag==1) flag=2; else if(flag==3) { flag=4; break; } } if(ch!='\n'&&ch!='\r') flag=0; } if(flag!=4) { free(newtext); free(match); free(replace); free(result); threadnumber--; return -1; }

 status=0;todo=0;cl=0;newtext[cl]=0;

while(result[resultlength]) {

sgets(line,result,&resultlength,1500); i=0; while(line[i]) { if(line[i]==match[0]) { for(j=0;j<length;j++) { if(line[i+j]!=match[j]) break; }

if(j==length) { newtext[cl]=0; strcat(newtext,replace); todo=1; cl+=rpl; i=i+j; j=0; continue;

} }

newtext[cl]=line[i]; i++; cl++;newtext[cl]=0;

} } newtext[cl]=0;

   resultlength=0;

if(todo) { point.newtext=newtext;

         point.title=tt;

point.count=0; edit(&point); }

free(newtext); free(match); free(replace); free(result); threadnumber--;

   return 0;

} int edit(struct editargv *p) { const char *invalid1="notoken",*invalid2="badtoken"; const int length1=strlen(invalid1),length2=strlen(invalid2); char *ntxt,*url,*result; int resultlength=0,i=0,error=0,count=0,find; ntxt=(char *)malloc(1024*1024); URLEncode(p->newtext,strlen(p->newtext),ntxt,1024*1024); url=(char *)malloc(1024*1024); strcpy(url,"title="); strcat(url,p->title); strcat(url,"&text="); strcat(url,ntxt); free(ntxt); strcat(url,"&summary=multithreadtest%20with%20token%20check%20enabled&format=xml&bot=1&minor=1&token="); find=strlen(url); do { result=(char*)calloc(10*1024,1); error=0;count++; while(!hastoken) { Sleep(100); } while(tokenlock<0); tokenlock++; url[find]=0; strcat(url,token); tokenlock--; post("https://zh.wikipedia.org/w/api.php?action=edit",url,1,&result); resultlength=0;error=0; while(result[resultlength]) { if(result[resultlength]==invalid1[0]) { for(i=0;i<length1;i++) { if(result[resultlength+i]!=invalid1[i]) break; } if(i==length1) {error=1;break;} } if(result[resultlength]==invalid2[0]) { for(i=0;i<length2;i++) { if(result[resultlength+i]!=invalid2[i]) break; } if(i==length2) {error=1;break;} } resultlength++; } if(error) { while(tokenlock<0); tokenlock++; i=0; while(token[i]) { if(url[find+i]!=token[i]) break; i++; } if(token[i]==0) hastoken=0; tokenlock--; } free(result); }while(error&&count<10); free(url); return 0; }

int sgets(char *a,char *b,int *c,int limit) {

    int i=0;
   for(;b[*c],limit>0;)

{ if(b[*c]=='\n'){a[i]='\n';i++;(*c)++; break;} a[i]=b[*c]; (*c)++; i++; limit--; } a[i]=0; return 0; }