`
psychopath
  • 浏览: 1829 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

c正则的一个应用

阅读更多
下面代码是linux下c正则的一个应用。程序可通过代理privoxy->tor下载代理,默认的代理是127.0.0.1:8118。
所以在编译后运行前,请先保证tor正在运行中,否则无法下载到代理。一般情况下一次能下载到2000个左右的代理。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <regex.h>

#define NM 10

static int proxy_save_count = 0;
static int reg_num;
static unsigned short through_proxy_port = 8118;
static char code[10];
static char *through_proxy_ip = "127.0.0.1";
static regex_t **pregs;

void die(int i, char *message, char *str)
{
  if(str != NULL){  	
    printf(message, str);
    exit(i);
  }else{
    printf(message);
    exit(i);
  }
}


int write_all(int sockfd, char *buf, int *len)
{
  int total = 0, bytesleft = *len, n;

  while(total < *len) {
    n = write(sockfd, buf + total, bytesleft);
    if (n == -1) 
       break;
    total += n;
    bytesleft -= n;
  }
  *len = total;

  return n == -1 ? -1 : 0;
} 

void to_lower(char *p)
{
  while(*p){
    if(isalpha(*p) && isupper(*p))
      *p = tolower(*p);
    p++;
  }
}

int parse_http_header(int sockfd, long *bytes)
{
  char buf[100], key[30], value[70], ch, *pb = buf;
  int n, i = 0, j = 0;
  
  memset(key, 0, sizeof(key));
  memset(value, 0, sizeof(value));
  while((n = read(sockfd, &ch, 1)) == 1){
    if(ch == '\n'){
      if(i == 0)
        break;
      i = 0;
    }else if(ch != '\r'){
      pb[i++] = ch;
    }else{
      pb[i] = '\0';
      //printf("%s\n", buf);
      if(j++ == 0){
        if(!strstr(buf, "HTTP/1.") || !strstr(buf, "200")){
          printf("%s\n", buf);
          return -1;
        }
      }else{
        if(sscanf(buf, "%[^:]: %[^\n]", key, value ) == 2){
          to_lower(key);
          if(strcmp("content-length", key) == 0){
            *bytes = atol(value);
          }
        }
      }
    }
  }
  if(n == -1){
    fprintf(stderr, "read() error\n");
    return -2;
  }

  return 0;
}

int with_content_length(int sockfd, long bytes, char **recv)
{
  char buf[1024];
  int n, len = sizeof(buf);

  if((*recv = (char *)malloc(bytes+1)) == NULL)
    die(-1, "Memory allocation failed!\n", NULL);

  memset(*recv, 0, bytes+1);
  while((n = read(sockfd, buf, len-1)) > 0){
    buf[n] = '\0';
    strcat(*recv, buf);
  }
  if(n == -1){
    fprintf(stderr, "read() error\n");
    return 1;
  }

  close(sockfd);
  return 0; 
}

int without_content_length(int sockfd, char **recv)
{
  char buf[1024];
  int n, len = sizeof(buf); 
  int i = 0, total = 0;
 
  while((n = read(sockfd, buf, len-1)) > 0){
    total += n;
    buf[n] = '\0';
    if(i++ == 0){
      if((*recv = (char *)malloc(total+1)) == NULL)
        die(-1, "Memory allocation failed!\n", NULL);
      strcpy(*recv, buf);
    }else{
      if((*recv = (char *)realloc(*recv, total+1)) == NULL)
        die(-1, "Memory reallocation failed!\n", NULL);
      strcat(*recv, buf);
    }
  }
  if(n == -1){
    fprintf(stderr, "read() error\n");
    return 1;
  }

  close(sockfd);
  return 0;
}

int get_http_body(char *send,  char **recv)
{
  int sockfd, n, i = 0, len = strlen(send);  
  struct sockaddr_in sa;  
  struct hostent *he;
  long bytes = 0;  

  if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
    fprintf(stderr, "socket() falied\n");
    return 1;
  } 
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = inet_addr(through_proxy_ip);
  sa.sin_port = htons(through_proxy_port);

  if(connect(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1){
    fprintf(stderr, "connect() failed\n");
    return 2;
  }
  if(write_all(sockfd, send, &len) == -1){
    fprintf(stderr, "write() error\n");
    return 3;
  }
  if((parse_http_header(sockfd, &bytes)) < 0)
    return 4;
  if(bytes > 0){
    if(with_content_length(sockfd, bytes, recv))
      return 5;
  }else{
    if(without_content_length(sockfd,  recv))
      return 6;
  }
  
  return 0;
}

int sub_string(int start, int end, char *src, char **dst)
{
  int i = start, j = 0;

  if((*dst = (char *)malloc(sizeof(char)*(end-start+1))) == NULL)
    die(-1, "Memory allocation failed!\n", NULL);
  while(i < end)
    (*dst)[j++] = src[i++];
  (*dst)[j] ='\0';
   
  return 0 ;
}

int get_index(char *p)
{
  int i;
  
  for(i = 0; i < 10; i++){
    if(code[i] == *p)
      break; 
  }
 
  return i;
}

void get_code(char *p)
{
  int i, j;

  memset(code, 0, sizeof(code));
  for(i = 0; i < 39; i += 4){
    j = atoi(p + i + 2);
    code[j]= p[i];
  } 
}

void print_port(char *port, FILE *fp)
{
  char ptr[11], *ch = NULL, delims[] = "+";
  int i; 

  memset(ptr, 0, sizeof(ptr));
  strcpy(ptr, port);
        
  ch = strtok(ptr, delims);
  while(ch != NULL){
    i = get_index(ch);
    if(i < 10)
      fprintf(fp, "%d", i);
    else
      printf("Can't not decode port\n");
    ch = strtok(NULL, delims);
  }
  fprintf(fp, "\n");
}

int parse_http_body(char *str, FILE *fp, int eflags, int i, int j, int n, int k, int flag)
{
  char *ip = NULL, *port = NULL, ch = *str;
  regmatch_t pm[NM];
  const size_t nm = NM;

  if(n > NM){
    while(*str && regexec(pregs[k], str, nm, pm, eflags) == 0){
      sub_string(pm[i].rm_so, pm[i].rm_eo, str, &ip);
      if(flag){
        get_code(ip);
        *str = 0;
      }else{
        proxy_save_count++;
        fprintf(fp, "%s\n", ip); 
        str = &str[pm[j].rm_eo];
      }
      free(ip);
    }
    if(flag)
      *str = ch;
  }else{
    while(*str && regexec(pregs[k], str, nm, pm, eflags) == 0){
      sub_string(pm[i].rm_so, pm[i].rm_eo, str, &ip);
      sub_string(pm[n].rm_so, pm[n].rm_eo, str, &port);
      if(flag){
        proxy_save_count++;
        fprintf(fp, "%s:", ip);
        print_port(port, fp);
      }else{
        proxy_save_count++;
        fprintf(fp, "%s:%s\n", ip, port);
      }
      free(ip);
      free(port);
      str = &str[pm[j].rm_eo];
    }
  }
 
  return 0;
}


int print_proxys(char *url, int *keys, FILE *fp, int eflags)
{
  char host[30], send[512], *data = NULL;
  int i, j, n;

  memset(host, 0, sizeof(host));
  memset(send, 0, sizeof(send));
  if(sscanf(url, "http://%[^/]", host) != 1){
    printf("Can't not parse url\n");
    return 1;
  }
  sprintf(send, "GET %s HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: deflate\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nKeep-Alive: 115\r\nProxy-Connection: keep-alive\r\n\r\n", url, host);
 
  //printf("%s\n", send);
  if(get_http_body(send, &data) != 0)
    return 2;

  if(keys[1] < 0){
    if(keys[0] > reg_num-1 || keys[0] < 0)
      return 2;
    parse_http_body(data, fp, eflags, 0, 2, 11, keys[0], 0);
  }else{
    if(keys[0] > reg_num-1 || keys[0] < 0 || keys[1] > reg_num-1 || keys[1] < 0)
      return 3; 
    parse_http_body(data, fp, eflags, 0, 1, 11, keys[0], 1);
    parse_http_body(data, fp, eflags, 1, 3, 3, keys[1], 1) ;
  }
  free(data);

  return 0;
}

int compile_regexs(char **regexs, int cflags)
{
  int i;

  if((pregs = (regex_t **)malloc(sizeof(regex_t *)*reg_num)) == NULL)
    die(-1, "Memory allocation failed!\n", NULL);

  for(i = 0; i < reg_num; i++){
    if((pregs[i] = (regex_t *)malloc(sizeof(regex_t))) == NULL)
      die(-1, "Memory allocation failed!\n", NULL);
    if(regcomp(pregs[i], regexs[i], cflags) != 0){
      fprintf(stderr, "regcomp() failed\n");
      return (i+1);
    }
  }

   return 0;
}

void free_regs(void)
{
  int i;

  for(i = 0; i < reg_num; i++)
    regfree(pregs[i]);
  free(pregs);

}

int main()
{
  char *file = "proxy.txt";
  FILE *fp = NULL;
  int num, i, keys[2];  
  int eflags = 0, cflags = REG_EXTENDED|REG_NEWLINE;

  if((fp = fopen(file, "w")) == NULL)
    die(-1, "Failed to create the file %s\n", file);
  
  char *regexs[] = {"([0-9]{1,3}\\.){3}([0-9]{1,3}:[0-9]{1,5})",                   
                   "([a-z]=[0-9];){10}",
                   "(([0-9]{1,3}\\.){3}[0-9]{1,3})[^\\+]+((\\+[a-z]){1,5})",
                   };
  reg_num = sizeof(regexs)/sizeof(char *);
  if(compile_regexs(regexs, cflags) != 0)
    return 1;

  char *urls[] = {"http://www.samair.ru/proxy/type-01.htm",
                  "http://www.samair.ru/proxy/type-02.htm",
                  "http://www.samair.ru/proxy/type-03.htm",
                  "http://www.samair.ru/proxy/type-04.htm",
                  "http://www.samair.ru/proxy/type-05.htm",
                  "http://www.samair.ru/proxy/type-06.htm",
                  "http://www.samair.ru/proxy/type-07.htm",
                  "http://www.samair.ru/proxy/type-08.htm",
                  "http://www.samair.ru/proxy/type-09.htm",
                  "http://www.samair.ru/proxy/type-10.htm",
                  "http://www.samair.ru/proxy/type-11.htm",
                  "http://www.samair.ru/proxy/type-12.htm",
                  "http://www.samair.ru/proxy/type-13.htm",
                  "http://www.samair.ru/proxy/type-14.htm",
                  "http://www.samair.ru/proxy/type-15.htm",
                  "http://www.samair.ru/proxy/type-16.htm",
                  "http://www.samair.ru/proxy/type-17.htm",
                  "http://www.samair.ru/proxy/type-18.htm",
                  "http://www.samair.ru/proxy/type-19.htm",
                  "http://www.samair.ru/proxy/type-20.htm",
                 };

  num = sizeof(urls)/sizeof(char *);
  printf("Proxy downloading is processing...\n");
  for(i = 0; i < num; i++){
    if(i < 10){
      keys[0] = 1; keys[1] = 2;
    }else{
      keys[0] = 0; keys[1] = -1;
    }   
    print_proxys(urls[i], keys, fp, eflags);
  }
  if(proxy_save_count > 0)
    printf("Now we have downloaded %d proxys, saved in the file %s\n", proxy_save_count, file);
  else
    printf("Oops, no proxy saved!\n");
  fclose(fp);
  free_regs();
  return 0;  
}



分享到:
评论
2 楼 psychopath 2011-06-29  
楼上,多来我的BLOG玩玩吧
1 楼 johnson444 2011-06-22  
写得不错~

相关推荐

    C语言正则表达式使用详解

    ### C语言正则表达式使用详解 #### 一、引言 正则表达式作为一种强大的文本处理工具,在数据检索和高级编程中应用广泛。对于C语言开发者而言,虽然标准的C语言本身并不直接支持正则表达式的操作,但是可以通过相关...

    C语言正则表达式详解 regcomp() regexec() regfree()详解1

    Perl-Compatible Regular Expression(PCRE)库是一个广泛使用的选项,它为C和C++程序员提供了处理正则表达式的能力。在C语言中,PCRE库提供了几个关键函数,包括`regcomp()`、`regexec()`和`regfree()`,用于编译、...

    正则表达式(regex)C语言源码,超强查找/替换算法

    Henry Spencer的regex library是一个经典的正则表达式库,由C语言编写,设计目的是为了提供一个高效且灵活的正则表达式引擎。它支持多种正则表达式语法,包括基本的字符匹配、量词、分组、预查以及更多的高级特性。...

    Linux下的C语言正则表达式

    ### Linux下的C语言正则表达式使用详解 #### 引言 正则表达式作为一种强大的文本处理工具,广泛应用于各种编程语言中。对于C语言来说,尽管标准库并不直接支持正则表达式的操作,但可以通过引入第三方库来实现这一...

    正则表达式在C语言中的应用

    下面是一个简单的C语言示例程序,演示如何使用正则表达式查找文件: ```c #include #include int main(int argc, char *argv[]) { if (argc != 3) { printf("Usage: ./regex &lt;regex&gt; &lt;filename&gt;\n"); return ...

    C语言实现正则表达式检测

    这里我们将深入探讨如何在C语言中实现正则表达式的检测,基于提供的"ValidateLib.c"和"Validate.h"文件,我们可以推断这是一个自定义的正则表达式验证库。 首先,让我们理解正则表达式的概念。正则表达式(Regular ...

    正则表达式 到 nfa dfa

    NFA特别适用于构造复杂的正则表达式,因为它可以更直观地表示某些表达式,如`a*`,在NFA中只需一个状态就可以表示。 3. **DFA(确定性有限状态自动机)**: DFA与NFA类似,但每个状态下只有一个明确的转移,对于...

    关于正则表达式的应用(正则表达式)

    例如,"a+|z+"能匹配包含连续一个或多个a或z的字符串。 4. 方括号表达式(Character Class):[abc]表示匹配'a'、'b'或'c'。如果第一个字符是'^',则匹配不在括号内的字符。方括号内还可以使用字符类别,如`\d`匹配...

    正则表达式及其应用简介.txt

    正则表达式在多种编程语言中都有广泛的应用,下面分别介绍在 JavaScript、Java 和 C 语言中的应用。 - **JavaScript**: - 使用 `RegExp` 对象进行正则表达式的创建和匹配。 - 示例代码: ```javascript ...

    C正则表达式库

    在C语言环境中,GUN(GNU)提供了一个官方的正则表达式库,这使得C程序员可以方便地在他们的应用程序中利用正则表达式的强大功能。本篇文章将详细探讨GUN C的正则表达式库,包括其核心组件`regex.c`和`regex.h`,...

    OK_REEC正则表达式(C语言)

    REEC是一个精简,高效的C语言正则表达式引擎,它使得C语言开发中支持正则表达式,目前已经进化到了1.2.0版本,可以说无论从功能上,还是效率都到达了很好的应用水平,该引擎除支持常用的正则标准之外,还有一些原创...

    实验4 正则表达式及其应用.pdf

    正则表达式的语法复杂而强大,它包括字符类(如`[abc]`匹配"a"、"b"或"c"中的任意一个)、数量词(如`a{1,3}`表示匹配1到3个"a")、特殊字符(如`\d`匹配任意数字)、锚点(如`^`和`$`分别表示字符串的开始和结束)...

    c语言正则表达式pcre

    C语言正则表达式PCRE(Perl Compatible Regular Expressions)是一种强大的文本模式匹配库,它在C编程中广泛用于处理字符串和数据的模式查找。PCRE库提供了与Perl语言正则表达式语法相兼容的功能,使得C程序员可以...

    正则表达式的高级应用

    例如,`/s$/` 创建了一个匹配以"s"结尾的字符串的正则表达式。 - **特殊字符**:在正则表达式中,一些字符有特殊含义,如`$`匹配字符串的结尾,`\n`匹配换行符,而`\d`匹配数字等。如果想要匹配这些特殊字符本身,...

    C语言正则表达式操作示例

    C语言正则表达式操作示例 正则表达式是一种强大的字符串匹配工具,它广泛应用于数据处理、文本分析、网络爬虫等领域。C语言作为编程语言的基础,自然也需要支持正则表达式的操作。本文将详细介绍C语言中正则表达式...

    pcre-3.4.tar_c语言正则表达_简洁版_

    总结来说,PCRE-3.4是一个轻量级、易移植的C语言正则表达式库,适用于嵌入式系统。它提供了核心的正则表达式功能,结合`pcre_compile`和`pcre_exec`等关键函数,可以方便地在C程序中实现复杂的文本处理任务。通过...

    C语言兼容的正则表达式(有实例)

    PCRE是一个流行的正则表达式库,它提供与Perl语言兼容的正则表达式功能,因此可以在C语言程序中使用丰富的正则表达式语法。 标题“C语言兼容的正则表达式(有实例)”表明我们将讨论如何在C语言中利用PCRE库实现正则...

    C语言正则表达式[参照].pdf

    C语言正则表达式主要涉及三个关键步骤:编译、匹配和释放。 1. **编译正则表达式**: 使用`regcomp()`函数来编译正则表达式字符串。这个函数接受三个参数:一个`regex_t`结构体指针用于存储编译后的结果,一个包含...

    如安在C语言中巧用正则表达式(linux).docx

    为了提高效率,在将一个字符串与正则表达式进行比较之前,首先要用 `regcomp()` 函数对它进行编译,将其转化为 `regex_t` 结构。`regcomp()` 函数的原型为: ```c int regcomp(regex_t *preg, const char *regex, ...

Global site tag (gtag.js) - Google Analytics