免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: duanjigang
打印 上一主题 下一主题

源码阅读第一期:axel和wget [复制链接]

论坛徽章:
0
181 [报告]
发表于 2011-10-12 17:28 |只看该作者
本帖最后由 wangzhen11aaa 于 2011-10-12 18:12 编辑

  1. 1225   url = alloca_array (char *, nurl + 1);/*alloca有多少个url地址,就分配几个指针*/
  2. 1226   for (i = 0; i < nurl; i++, optind++)
  3. 1227     {   
  4. 1228       char *rewritten = rewrite_shorthand_url (argv[optind]);
  5. 1229       if (rewritten)
  6. 1230         url[i] = rewritten;
  7. 1231       else
  8. 1232         url[i] = xstrdup (argv[optind]);
  9. 1233     }
  10. 1234   url[i] = NULL;
  11. /*这里返回后,url指向的就是实际意义上的http://www.google.com 或者 ftp://xxx.xxx.xxx:23端口,这里函数的作用是判断哪一种协议。*/
复制代码

  1. 1237   log_init (opt.lfilename, append_to_log); /*打开设定的日志文件,准备写*/
复制代码

  1. opt.output_document /*有输出打印到的文件*/
复制代码

  1. 1330   for (t = url; *t; t++)
  2. 1331     {
  3. 1332       char *filename = NULL, *redirected_URL = NULL;
  4. 1333       int dt, url_err;
  5. 1337       struct iri *iri = iri_new ();   /*这个数据结构储存检查要获取编码格式,文件编码格式,是否这url是用utf8编码,这里是分配一个新的1、_______--------->*/
  6. 1338       struct url *url_parsed;
  7. 1339
  8. 1340       set_uri_encoding (iri, opt.locale, true);
  9. 1341       url_parsed = url_parse (*t, &url_err, iri, true); 2、________----------->
  10.       
  11. 1、________--------------->
  12. 302 struct iri *
  13. 303 iri_new (void)
  14. 304 {
  15. 305   struct iri *i = xmalloc (sizeof *i);  /*分配一个空间*/
  16. 306   i->uri_encoding = opt.encoding_remote ? xstrdup (opt.encoding_remote) : NULL; /*是否有远程编码格式没有就初始化为NULL*/
  17. 307   i->content_encoding = NULL; /*内容编码为NULL*/
  18. 308   i->orig_url = NULL;    /*url也是0*/
  19. 309   i->utf8_encode = opt.enable_iri;  /*
  20. 310   return i;
  21. 311 }
  22. <------------_______________
复制代码

  1. 1340       set_uri_encoding (iri, opt.locale, true); /*检查是否被设置编码,如果没有,就有本地编码进行初始化*/
复制代码

  1. 2、______________---------->
  2. [code]
  3. /*url 解析*/
  4. 1341       url_parsed = url_parse (*t, &url_err, iri, true); /*t为 url, &url_err (int*类型),iri储存编码格式.bool 常量 ture*/
  5. 函数作用是解析一个url地址,返回一个新的url地址如果成功。否则就返回NULL或者error。
  6. 此函数中调用了url_scheme()又一次判断,地址类型,这里略去不分析*/

  7. 698   if (iri && iri->utf8_encode)
  8. 699     {
  9. 700       iri->utf8_encode = remote_to_utf8 (iri, iri->orig_url ? iri->orig_url : url, (co     nst char **) &new_url);  /*new_url 强制转化为 const char **类型 *这个函数作用是:如果发现远处的编码格式不是utf-8格式,那么就将其转化成utf-8格式 *new中保存这个转化后的地址。调用的外部函数/
  10. 701       if (!iri->utf8_encode)
  11. 702         new_url = NULL;  
  12. 703       else
  13. 704         iri->orig_url = xstrdup (url); /*将源地址同化*/
  14. 705     }
复制代码

  1.            src/url.c*/
  2. 708   if (percent_encode)
  3. 709     url_encoded = reencode_escapes (new_url ? new_url : url); /*用utf-8格式将url进行格式化*/
  4. 713   p = url_encoded;   
  5. 718   p += strlen (supported_schemes[scheme].leading_string);  /*计算http://的长度*/
  6. 719   uname_b = p;  /*算出真正url的地址,是转化后的*/
  7. 720   p = url_skip_credentials (p);  /*去掉不规则的结束符比如 @ # 等。
  8. 721   uname_e = p;  /*指向结束地址*/
  9.                 scheme://host[:port][/path][;params][?query][#fragment]  
  10. 格式
  11. 731   path_b     = path_e     = NULL;
  12. 732   params_b   = params_e   = NULL;
  13. 733   query_b    = query_e    = NULL;
  14. 734   fragment_b = fragment_e = NULL;
  15. 739   seps = init_seps (scheme); /*加入分隔字符,比如ftp 有参数,http和https有请求字符和片段 2、__________------------>*/
  16. 741   host_b = p;
复制代码

  1. 2、__-------------->
  2. 620 static const char *
  3. 621 init_seps (enum url_scheme scheme)
  4. 622 {
  5. 623   static char seps[8] = ":/";  /*固定的开始是:/字符
  6. 624   char *p = seps + 2;  
  7. 625   int flags = supported_schemes[scheme].flags; /这里看这个scheme支持的格式*/
  8. 626
  9. 627   if (flags & scm_has_params)  判断*/
  10. 628     *p++ = ';';  
  11. 629   if (flags & scm_has_query)
  12. 630     *p++ = '?';
  13. 631   if (flags & scm_has_fragment)
  14. 632     *p++ = '#';
  15. 633   *p = '\0';
  16. 634   return seps;  /*返回格式*/
  17. 635 }
复制代码

  1. <--------------____________
  2. src/url.c*/
  3. 741   host_b = p; /*
  4. 742
  5. 743   if (*p == '[')
  6. 744     {
  7. 745       /* Handle IPv6 address inside square brackets.  Ideally we'd
  8. 746          just look for the terminating ']', but rfc2732 mandates
  9. 747          rejecting invalid IPv6 addresses.  */
  10. 748
  11. 749       /* The address begins after '['. */
  12. 750       host_b = p + 1;
  13. 751       host_e = strchr (host_b, ']');  /*ipv6格式*/
  14. 752
  15. 753       if (!host_e)
  16. 754         {
  17. 755           error_code = PE_UNTERMINATED_IPV6_ADDRESS;
  18. 756           goto error;
  19. 757         }
  20. /*不说ipv6先*/
  21. /*后面的一些判断很简单*/
  22. 798   port = scheme_default_port (scheme); /*根据scheme的default_prot来初始化port*/

  23. 799   if (*p == ':')  /*来确定端口,并赋给port_b和port_e;
  24. 800     {
  25. 801       const char *port_b, *port_e, *pp;
  26. 802
  27. 803       /* scheme://host:port/tralala */
  28. 804       /*              ^             */  
  29. 805       ++p;
  30. 806       port_b = p;
  31. 807       p = strpbrk_or_eos (p, seps);
  32. 808       port_e = p;
  33. /*比较简单*/
  34. /*获得含有第一个字符串的指针返回,过程中还有赋值操作,这是按照顺序依次来赋值的*/
  35. 837 #define GET_URL_PART(sepchar, var) do {                         \
  36. 838   if (*p == sepchar)                                            \
  37. 839     var##_b = ++p, var##_e = p = strpbrk_or_eos (p, seps);      \
  38. 840   ++seps;                                                       \
  39. 841 } while (0)

  40. 843   GET_URL_PART ('/', path);
  41. 844   if (supported_schemes[scheme].flags & scm_has_params)
  42. 845     GET_URL_PART (';', params);
  43. 846   if (supported_schemes[scheme].flags & scm_has_query)

  44. 866   u = xnew0 (struct url);      
  45. 867   u->scheme = scheme;         
  46. 868   u->host   = strdupdelim (host_b, host_e);
  47. 869   u->port   = port;
  48. 870   u->user   = user;
  49. 871   u->passwd = passwd;
  50. 873   u->path = strdupdelim (path_b, path_e);
  51. 874   path_modified = path_simplify (scheme, u->path); /*矫正后的path*/
  52. 875   split_path (u->path, &u->dir, &u->file);  /*将路径和文件分别存储,并且用格式化编码*/
  53. 876  
  54. 877   host_modified = lowercase_str (u->host);  /*将主机名称格式化成小写*/

  55. /*将url结构对应初始化*/

  56. 847     GET_URL_PART ('?', query);
  57. 848   if (supported_schemes[scheme].flags & scm_has_fragment)
  58. 849     GET_URL_PART ('#', fragment);
  59. 883   if (strchr (u->host, '%'))  /*将主机名也格式化*/
  60. 884     {
  61. 885       url_unescape (u->host);
  62. 886       host_modified = true;
  63. 887
  64. 888       /* Apply IDNA regardless of iri->utf8_encode status */
  65. 889       if (opt.enable_iri && iri)  
  66. 890         {
  67. 891           char *new = idn_encode (iri, u->host);/*参有IDNAN格式格式化,如果没有采用utf-8格式,那么就用ascii码格式*/
  68. 892           if (new)
  69. 893             {
  70. 894               xfree (u->host);
  71. 895               u->host = new;
  72. 896               host_modified = true;
  73. 897             }
  74. 898         }
  75. 899     }
  76. 剩下就是其他的格式化*/
  77. return u;
  78. 这是我最想看到的*/
复制代码

论坛徽章:
0
182 [报告]
发表于 2011-10-12 18:23 |只看该作者
本帖最后由 wangzhen11aaa 于 2011-10-12 20:37 编辑

  1. 回到main.c函数
  2. 1343       if (!url_parsed)  /*当然如果没有输入错的话,肯定是不为NULL的*/
  3. 1344         {
  4. 1345           char *error = url_error (*t, url_err);
  5. 1346           logprintf (LOG_NOTQUIET, "%s: %s.\n",*t, error);
  6. 1347           xfree (error);
  7. 1348           inform_exit_status (URLERROR);
  8. 1349         }
  9. 1350       else  /*进入这里*/
  10. 1351         {
  11. 1352           if ((opt.recursive || opt.page_requisites)  /*如果递归&&使用代理或者不是FTP协议*/
  12. 1353               && (url_scheme (*t) != SCHEME_FTP || url_uses_proxy (url_parsed)))
  13. 1354             {
  14. 1355               int old_follow_ftp = opt.follow_ftp;  
  15. 1356
  16. 1357               /* Turn opt.follow_ftp on in case of recursive FTP retrieval      */
  17. 1358               if (url_scheme (*t) == SCHEME_FTP)  /*如果协议是SCHEME_FTP*/
  18. 1359                 opt.follow_ftp = 1;  /* 开启递归fpt*/
  19. 1360
  20. 1361               retrieve_tree (url_parsed, NULL); /*1、_________------------->
  21. 1362
  22. 1363               opt.follow_ftp = old_follow_ftp;  /*将其初始化为可以递归*/
  23. 1364             }
  24. 1365           else
  25. 1366           {
  26. 1367             retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL,
  27. 1368                           &dt, opt.recursive, iri, true); /*如果不递归*/
  28. 1369           }
复制代码

  1. 1、___________--------->
  2. 190 uerr_t
  3. 191 retrieve_tree (struct url *start_url_parsed, struct iri *pi)
  4. 192 {
  5. 193   uerr_t status = RETROK;
  6. 194
  7. 195   
  8. 196   struct url_queue *queue;  /*因为是递归,所以要使用队列来保证实现====>
  9.              68 struct url_queue {
  10.              69   struct queue_element *head; ======>
  11.              70   struct queue_element *tail;
  12.              71   int count, maxcount;
  13.               72 };
  14.                                             
  15. */
  16. +++++++++++++++++=========>
  17. /*其中为各个的值,url参数*/
  18. 56 struct queue_element {
  19. 57   const char *url;              /* the URL to download */
  20. 58   const char *referer;          /* the referring document */
  21. 59   int depth;                    /* the depth */
  22. 60   bool html_allowed;            /* whether the document is allowed to
  23. 61                                    be treated as HTML. */
  24. 62   struct iri *iri;                /* sXXXav */
  25. 63   bool css_allowed;             /* whether the document is allowed to
  26. 64                                    be treated as CSS. */
  27. 65   struct queue_element *next;   /* next element in queue */
  28. 66 };
  29. */   
  30. 197
  31.           /*url地址,我们不想让它进入队列,因为它们已经在队列中。这里我们还没有下载*/
  32. 200   struct hash_table *blacklist;  /*=======>将已经进入队列的,放入hash表中*/
  33. 202   struct iri *i = iri_new ();
复制代码

  1. 156 struct hash_table {
  2. 157   hashfun_t hash_function;  
  3. 158   testfun_t test_function;
  4. 159   
  5. 160   struct cell *cells;           /* contiguous array of cells. 连续的数组单元*/
  6. 161   int size;                     /* size of the array. 数组的大小*/
  7. 162      
  8. 163   int count;                    /* number of occupied entries. 已经被占的大小*/
  9. 164   int resize_threshold;         /* after size exceeds this number of
  10. 165                                    entries, resize the table.   如果超过,重置大小*/
  11. 166   int prime_offset;             /* the offset of the current prime in
  12. 167                                    the prime table.  在hash表中的偏移地址*/
  13. 168 };
  14. /*单元内存放索引值和数值*/
  15. 148 struct cell {
  16. 149   void *key;
  17. 150   void *value;
  18. 151 };
复制代码

  1. <----------___________
  2. /src/recur.c
  3. 213     set_uri_encoding (i, opt.locale, true); /*设置编码*/

  4. 216   queue = url_queue_new ();  2、__________----------->
  5. 217   blacklist = make_string_hash_table (0); 3、_____________---------->
  6. 218   

  7. 221   url_enqueue (queue, i, xstrdup (start_url_parsed->url), NULL, 0, true,
  8. 222                false);         4、_____________-------------->
  9. 223   string_set_add (blacklist, start_url_parsed->url);

复制代码

  1. 2、____________----------->
  2. 76 static struct url_queue *
  3. 77 url_queue_new (void)
  4. 78 {
  5. 79   struct url_queue *queue = xnew0 (struct url_queue);/*分配前测试堆栈大小,如果正常就返回一个数据结构*/
  6. 80   return queue;
  7. 81 }
复制代码

  1. 3、________________--------------->
  2. 665 struct hash_table *
  3. 666 make_string_hash_table (int items)
  4. 667 {
  5. 668   return hash_table_new (items, hash_string, cmp_string);5、__________-------->
  6. 669 }
复制代码

  1. 5、_____------>
  2. 272 struct hash_table *
  3. 273 hash_table_new (int items,
  4. 274                 unsigned long (*hash_function) (const void *), /*调用hash_string(const void *)函数 6、__________------------->*/
  5. 275                 int (*test_function) (const void *, const void *)) /*调用typedef int (*testfun_t) (const void *, const void *);7、_______---------> */
  6. 276 {
  7. 277   int size;
  8. 278   struct hash_table *ht = xnew (struct hash_table); /*分配一个新的hash_table的值*/
  9. 279
  10. 280   ht->hash_function = hash_function ? hash_function : hash_pointer; /*如果hash_fuction为NULL,那么就用hash_pointer()函数*/
  11. 281   ht->test_function = test_function ? test_function : cmp_pointer;
  12. 282
  13.   
  14. 285   ht->prime_offset = 0;
  15. 286
  16. 289   size = 1 + items / HASH_MAX_FULLNESS;  /*#define HASH_MAX_FULLNESS 0.75。
  17. 290   size = prime_size (size, &ht->prime_offset);  /*返回一个给定的值,一开始是0,还是指针是指向0的。8、_____----->*/
  18. 291   ht->size = size;                     /*存储在hash_table中的对应位置*/
  19. 292   ht->resize_threshold = size * HASH_MAX_FULLNESS;
  20. 294
  21. 295   ht->cells = xnew_array (struct cell, ht->size); /*分配一个sizeof(struct cell) * ht->size大小.
  22. 296                            /*将ht->cell设置成 0xffffffff最大值*/
  23. 299   memset (ht->cells, INVALID_PTR_CHAR, size * sizeof (struct cell));
  24. 300
  25. 301   ht->count = 0;  /*ht->count 没有被其他占用*/
  26. 302
  27. 303   return ht;
复制代码

  1. 6、____________-------------->
  2. 642 hash_string (const void *key)  /*hash函数,将地址用以下计算方式获得一个unsigned int*/
  3. 643 {
  4. 644   const char *p = key;  /*地址*/
  5. 645   unsigned int h = *p;
  6. 646
  7. 647   if (h)
  8. 648     for (p += 1; *p != '\0'; p++)
  9. 649       h = (h << 5) - h + *p;  /*hash方程计算hash值*/
  10. 650
  11. 651   return h;
  12. 652 }
复制代码

  1. 8、______________------------->
  2. 215 static int
  3. 216 prime_size (int size, int *prime_offset)
  4. 217 {
  5. 218   static const int primes[] = {  /*hash 表*/
  6. 219     13, 19, 29, 41, 59, 79, 107, 149, 197, 263, 347, 457, 599, 787, 1031,
  7. 220     1361, 1777, 2333, 3037, 3967, 5167, 6719, 8737, 11369, 14783,
  8. 221     19219, 24989, 32491, 42257, 54941, 71429, 92861, 120721, 156941,
  9. 222     204047, 265271, 344857, 448321, 582821, 757693, 985003, 1280519,
  10. 223     1664681, 2164111, 2813353, 3657361, 4754591, 6180989, 8035301,
  11. 224     10445899, 13579681, 17653589, 22949669, 29834603, 38784989,
  12. 225     50420551, 65546729, 85210757, 110774011, 144006217, 187208107,
  13. 226     243370577, 316381771, 411296309, 534685237, 695090819, 903618083,
  14. 227     1174703521, 1527114613, 1837299131, 2147483647
  15. 228   };
  16. 229   size_t i;
  17. 230
  18. 231   for (i = *prime_offset; i < countof (primes); i++)
  19. 232     if (primes[i] >= size)
  20. 233       {
  21. 239         *prime_offset = i + 1;
  22. 240         return primes[i]; /*返回的是个规定的值*/
  23. 241       }
  24. 242  abort();
  25. }
复制代码

论坛徽章:
0
183 [报告]
发表于 2011-10-12 20:23 |只看该作者
GOOD GOOD STUDY DAY DAY UP

论坛徽章:
0
184 [报告]
发表于 2011-10-12 21:26 |只看该作者
本帖最后由 wangzhen11aaa 于 2011-10-12 21:33 编辑

  1. 在main.c中
  2. 如果没有递归
  3. 1365           else
  4. 1366           {
  5. 1367             retrieve_url (url_parsed, *t, &filename, &redirected_URL, NULL,
  6. 1368                           &dt, opt.recursive, iri, true); /*1、____--------->/src/retr.c*/
  7. 1369           }
  8. 1、__________--------->
  9. 655 uerr_t
  10. 656 retrieve_url (struct url * orig_parsed, const char *origurl, char **file,
  11. 657               char **newloc, const char *refurl, int *dt, bool recursive,
  12. 658               struct iri *iri, bool register_status)
  13. 659 {
  14. 660   uerr_t result;   /*一系列错误*/
  15. 661   char *url;
  16. 662   bool location_changed;
  17. 663   bool iri_fallbacked = 0;
  18. 664   int dummy;
  19. 665   char *mynewloc, *proxy;
  20. 666   struct url *u = orig_parsed, *proxy_url;
  21. 667   int up_error_code;            /* url parse error code */
  22. 668   char *local_file;
  23. 669   int redirection_count = 0;
  24. 670
  25. 671   bool post_data_suspended = false;
  26. 672   char *saved_post_data = NULL;
  27. 673   char *saved_post_file_name = NULL;
  28. 674
  29. 675   /* If dt is NULL, use local storage.  */
  30. 676   if (!dt)
  31. 677     {
  32. 678       dt = &dummy;
  33. 679       dummy = 0;
  34. 680     }
  35. 681   url = xstrdup (origurl);  /*url初始化 t */
  36. 682   if (newloc)   /*一开始就是NULL,如果有其他值,*newloc 为NULL*/
  37. 683     *newloc = NULL;
  38. 684   if (file)  
  39. 685     *file = NULL;         /* file不为零,那么其指向初始化为NULL*/
  40. 686
  41. 687   if (!refurl)   
  42. 688     refurl = opt.referer; /*如果不递归,这个refter可以指向些东西,现在还不清楚*/
  43. 689
  44. 690  redirected:               /*重定向,这里就是爬虫的效果吧*/
  45. 693   result = NOCONERROR;        /*先初始化一个错误*/
  46. 694   mynewloc = NULL;         
  47. 695   local_file = NULL;
  48. 696   proxy_url = NULL;
  49. 697
  50. 698   proxy = getproxy (u);  /*检测host这个是不是代理。2、_________------------->*/
  51. 699   if (proxy)               /*如果这个是proxy*/
  52. 700     {
  53. 701       struct iri *pi = iri_new ();   
  54. 702       set_uri_encoding (pi, opt.locale, true);
  55. 703       pi->utf8_encode = false;  
  56. 704
  57. 705       /* Parse the proxy URL.  */
  58. 706       proxy_url = url_parse (proxy, &up_error_code, NULL, true);
  59. 707       if (!proxy_url)  /*如果设置的时候,代理的地址为NULL*/
  60. 708         {
  61. 709           char *error = url_error (proxy, up_error_code);
  62. 710           logprintf (LOG_NOTQUIET, _("Error parsing proxy URL %s: %s.\n"),
  63. 711                      proxy, error);
  64. 712           xfree (url);
  65. 713           xfree (error);
  66. 714           RESTORE_POST_DATA;
  67. 715           result = PROXERR;
  68. 716           goto bail;
  69. 717         }
  70. 718       if (proxy_url->scheme != SCHEME_HTTP && proxy_url->scheme != u->scheme) /*各种错误情况*/
  71. 719         {
  72. 720           logprintf (LOG_NOTQUIET, _("Error in proxy URL %s: Must be HTTP.\n"), proxy);
  73. 721           url_free (proxy_url);
  74. 722           xfree (url);
  75. 723           RESTORE_POST_DATA;
  76. 2、__________-------->
  77. 1155 static char *
  78. 1156 getproxy (struct url *u)
  79. 1157 {
  80. 1158   char *proxy = NULL;
  81. 1159   char *rewritten_url;         
  82. 1160   static char rewritten_storage[1024];
  83. 1161  
  84. 1162   if (!opt.use_proxy)
  85. 1163     return NULL;
  86. 1164   if (no_proxy_match (u->host, (const char **)opt.no_proxy)) /*是否这个主机是代理3、_____----->*/
  87. 1165     return NULL;
  88. 1166  
  89. 1167   switch (u->scheme) /*通过格式来判断是哪种代理*/
  90. 1168     {
  91. 1169     case SCHEME_HTTP:
  92. 1170       proxy = opt.http_proxy ? opt.http_proxy : getenv ("http_proxy");
  93. 1171       break;  
  94. 1172 #ifdef HAVE_SSL
  95. 1173     case SCHEME_HTTPS:
  96. 1174       proxy = opt.https_proxy ? opt.https_proxy : getenv ("https_proxy");
  97. 1175       break;
  98. 1176 #endif
  99. 1177     case SCHEME_FTP:           
  100. 1178       proxy = opt.ftp_proxy ? opt.ftp_proxy : getenv ("ftp_proxy");
  101. 1179       break;
  102. 1180     case SCHEME_INVALID:
  103. 1181       break;
  104. 1182     }
  105. 1183   if (!proxy || !*proxy)
  106. 1184     return NULL;
  107. 1185
  108. 1186   /* Handle shorthands.  `rewritten_storage' is a kludge to allow
  109. 1187      getproxy() to return static storage. */
  110. 1188   rewritten_url = rewrite_shorthand_url (proxy);
  111. 1189   if (rewritten_url)
  112. 1190     {
  113. 1191       strncpy (rewritten_storage, rewritten_url, sizeof (rewritten_storage)     );
  114. 1192       rewritten_storage[sizeof (rewritten_storage) - 1] = '\0';
  115. 1193       proxy = rewritten_storage;
  116. 1194     }
  117. 1195
  118. 1196   return proxy;
  119. 1197 }
  120. 1198
复制代码

  1. 3、__________-------------->

  2. 1212 static bool
  3. 1213 no_proxy_match (const char *host, const char **no_proxy)
  4. 1214 {
  5. 1215   if (!no_proxy)
  6. 1216     return false;
  7. 1217   else
  8. 1218     return sufmatch (no_proxy, host); /*这个函数是比较字符,因为代理也是网站(字符)*/
  9. 1219 }
复制代码

  1. <---------------------____________________/src/retr.c */
  2. 729   if (u->scheme == SCHEME_HTTP
  3. 730 #ifdef HAVE_SSL
  4. 731       || u->scheme == SCHEME_HTTPS
  5. 732 #endif
  6. 733       || (proxy_url && proxy_url->scheme == SCHEME_HTTP))
  7. 734     {
  8. 735       result = http_loop (u, orig_parsed, &mynewloc, &local_file, refurl, dt,
  9. 736                           proxy_url, iri); /*4、____------->这里是不断的检索直到真正的主机*/
  10. 737     }
复制代码

  1. 4、____________-------->
  2. 2607 uerr_t
  3. 2608 http_loop (struct url *u, struct url *original_url, char **newloc,
  4. 2609            char **local_file, const char *referer, int *dt, struct url *pro     xy,                       
  5. 2610            struct iri *iri)
  6. 2611 {
  7. 2612   int count;
  8. 2613   bool got_head = false;         /* used for time-stamping and filename det     ection */
  9. 2614   bool time_came_from_head = false;
  10. 2615   bool got_name = false;
  11. 2616   char *tms;
  12. 2617   const char *tmrate;
  13. 2618   uerr_t err, ret = TRYLIMEXC;
  14. 2619   time_t tmr = -1;               /* remote time-stamp */
  15. 2620   struct http_stat hstat;        /* HTTP status */
  16. 2621   struct_stat st;
  17. 2622   bool send_head_first = true;
  18. 2623   char *file_name;
  19. 2624   bool force_full_retrieve = false;
  20. . . . . .一些检测,忽略*/
  21. 2639   if (opt.cookies)
  22. 2640     load_cookies (); 5、______________---------->
复制代码

  1. 3484 static void
  2. 3485 load_cookies (void)
  3. 3486 {
  4. 3487   if (!wget_cookie_jar)
  5. 3488     wget_cookie_jar = cookie_jar_new ();  /*分配一个struct cookie_jar结构6、________---->*/
  6. 3489   if (opt.cookies_input && !cookies_loaded_p)
  7. 3490     {
  8. 3491       cookie_jar_load (wget_cookie_jar, opt.cookies_input); /*7、________-------->src/cookies.c*/
  9. 3492       cookies_loaded_p = true;
  10. 3493     }
  11. 3494 }
复制代码

  1. 6、________________------------------->
  2. 84 struct cookie_jar *
  3.   85 cookie_jar_new (void)
  4.   86 {
  5.   87   struct cookie_jar *jar = xnew (struct cookie_jar); /*分配一个==========>*/
  6.   88   jar->chains = make_nocase_string_hash_table (0);  /*链入hash_table中*/
  7.   89   jar->cookie_count = 0;
  8.   90   return jar;
  9.   91 }     
复制代码

  1. ===================>
  2. 73 struct cookie_jar {
  3.   74   /* Cookie chains indexed by domain.  */
  4.   75   struct hash_table *chains;
  5.   76
  6.   77   int cookie_count;             /* number of cookies in the jar. */
  7.   78 };   
  8.             /* hash_table同上*/
  9. 也是进入hash_table值
复制代码

  1. 1134 void
  2. 1135 cookie_jar_load (struct cookie_jar *jar, const char *file)
  3. 1136 {
  4. 1137   char *line;
  5. 1138   FILE *fp = fopen (file, "r");
  6. 1139   if (!fp)
  7. 1140     {
  8. 1141       logprintf (LOG_NOTQUIET, _("Cannot open cookies file %s: %s\n"),
  9. 1142                  quote (file), strerror (errno));
  10. 1143       return;
  11. 1144     }
  12. 1145   cookies_now = time (NULL);
  13. 1146
  14. 1147   for (; ((line = read_whole_line (fp)) != NULL); xfree (line))
  15. 1148     {
  16. 1149       struct cookie *cookie;
  17. 1150       char *p = line;
  18. 1151
  19. 1152       double expiry;
  20. 1153       int port;
  21. 1154
  22. 1155       char *domain_b  = NULL, *domain_e  = NULL;
  23. 1156       char *domflag_b = NULL, *domflag_e = NULL;
  24. 1157       char *path_b    = NULL, *path_e    = NULL;
  25. . . . . . . .
  26. 将cookie文件中的行,然后下面是赋值*/
  27. 1187       cookie = cookie_new ();
  28. 1188
  29. 1189       cookie->attr    = strdupdelim (name_b, name_e);
  30. 1190       cookie->value   = strdupdelim (value_b, value_e);
  31. 1191       cookie->path    = strdupdelim (path_b, path_e);
  32. 1192       cookie->secure  = BOUNDED_EQUAL (secure_b, secure_e, "TRUE");
  33. 1198       cookie->domain_exact = !BOUNDED_EQUAL (domflag_b, domflag_e, "TRUE")
  34. 1202       port = domain_port (domain_b, domain_e, (const char **)&domain_e);
  35. 1203       if (port)
  36. 1204         cookie->port = port;
  37. . . . . . .
复制代码

  1. 末尾介绍一些这个struct cookie结构*/
  2. 93 struct cookie {
  3.   94   char *domain;                 /* domain of the cookie  ,cookie的主体*/
  4.   95   int port;                     /* port number  端口号*/
  5.   96   char *path;                   /* path prefix of the cookie :cookie路径 */
  6.   97   
  7.   98   unsigned discard_requested :1; /* whether cookie was created to
  8.   99                                    request discarding another
  9. 100                                    cookie.  :是否响应一个cookie会丢弃另一个*/
  10. 101
  11. 102   unsigned secure :1;           /* whether cookie should be
  12. 103                                    transmitted over non-https
  13. 104                                    connections.  : 是否cookie是否在非http协议下传播*/
  14. 105   unsigned domain_exact :1;     /* whether DOMAIN must match as a
  15. 106                                    whole. */
  16. 107
  17. 108   unsigned permanent :1;        /* whether the cookie should outlive
  18. 109                                    the session. cookie是否在对话外存活*/
  19. 110   time_t expiry_time;           /* time when the cookie expires, 0
  20. 111                                    means undetermined.  */
  21. 112
  22. 113   char *attr;                   /* cookie attribute name */
  23. 114   char *value;                  /* cookie attribute value */
  24. 115
  25. 116   struct cookie *next;          /* used for chaining of cookies in the
  26. 117                                    same domain. */
  27. 118 };
复制代码

论坛徽章:
0
185 [报告]
发表于 2011-10-12 22:04 |只看该作者
本帖最后由 wangzhen11aaa 于 2011-10-13 08:55 编辑

  1. <------------_____________
  2. 回到src/cookie.c文件
  3. 1134 void
  4. 1135 cookie_jar_load (struct cookie_jar *jar, const char *file)
  5. . . . . . .
  6. 1211       expiry = (double)cookies_now - 1;  /*是个时间*/
  7. 1215       *expires_e = '\0';
  8. 1216       sscanf (expires_b, "%lf", &expiry); /*将时间初始化为expires_b*/
  9. /*........这里有些是检测时间是否出现了错误*/
  10. 1233       store_cookie (jar, cookie);  /*1、___________----------->
复制代码

  1. 1、____________------------->
  2. 206 static void
  3. 207 store_cookie (struct cookie_jar *jar, struct cookie *cookie) /*jar中存储的是hash_table的数组和cookie数目*/
  4. 208 {
  5. 209   struct cookie *chain_head;
  6. 210   char *chain_key;
  7. 211                 
  8. 212   if (hash_table_get_pair (jar->chains, cookie->domain,
  9. 213                            &chain_key, &chain_head)) 2、________---------->
  10. 214     {
  11.         
  12. 218       struct cookie *prev;
  13. 219       struct cookie *victim = find_matching_cookie (jar, cookie, &prev);
  14. 220
  15. 221       if (victim)
  16. 222         {
  17. 223           /* Remove VICTIM from the chain.  COOKIE will be placed at
  18. 224              the head. */
  19. 225           if (prev)
  20. 226             {
  21. 227               prev->next = victim->next;
  22. 228               cookie->next = chain_head;
  23. 229             }
  24. 230           else
  25. 235               cookie->next = victim->next;
  26. 236             }
  27. 237           delete_cookie (victim);
  28. 238           --jar->cookie_count;
  29. 239           DEBUGP (("Deleted old cookie (to be replaced.)\n"));
  30. 240         }
  31. 241       else
  32. 242         cookie->next = chain_head;
  33. 243     }
  34. 244   else
  35. 251       cookie->next = NULL;
  36. 252       chain_key = xstrdup (cookie->domain);
  37. 253     }
  38. 254
  39. 255   hash_table_put (jar->chains, chain_key, cookie);
  40. 256   ++jar->cookie_count;
  41. 257
  42. 258   IF_DEBUG
  43. 259     {
  44. 260       time_t exptime = cookie->expiry_time;
  45. 261       DEBUGP (("\nStored cookie %s %d%s %s <%s> <%s> [expiry %s] %s %s\n",
  46. 262                cookie->domain, cookie->port,
  47. 263                cookie->port == PORT_ANY ? " (ANY)" : "",
  48. 264                cookie->path,
  49. 265                cookie->permanent ? "permanent" : "session",
  50. 266                cookie->secure ? "secure" : "insecure",
  51. 267                cookie->expiry_time ? datetime_str (exptime) : "none",
  52. 268                cookie->attr, cookie->value));
  53. 269     }
  54. 270 }
复制代码

  1. 2、_______________----------->
  2. 353 int
  3. 354 hash_table_get_pair (const struct hash_table *ht, const void *lookup_key,
  4. 355                      void *orig_key, void *value)
  5. 356 {  
  6. 357   struct cell *c = find_cell (ht, lookup_key); 3、__________--------->
  7. 358   if (CELL_OCCUPIED (c))
  8. 359     {
  9. 360       if (orig_key)
  10. 361         *(void **)orig_key = c->key;
  11. 362       if (value)
  12. 363         *(void **)value = c->value;
  13. 364       return 1;
  14. 365     }  
  15. 366   else
  16. 367     return 0;
  17. 368 }
复制代码

  1. 3、_____________----------->
  2. 319 static inline struct cell *
  3. 320 find_cell (const struct hash_table *ht, const void *key)
  4. 321 {
  5. 322   struct cell *cells = ht->cells;
  6. 323   int size = ht->size;
  7. 324   struct cell *c = cells + HASH_POSITION (key, ht->hash_function, size);4、________--------->
  8. 325   testfun_t equals = ht->test_function; /*分配一个新函数指向,cmp_string()也是在初始化时决定,它为比较两个字符串是否相等*/
  9. 326
  10. 327   FOREACH_OCCUPIED_ADJACENT (c, cells, size)  /*5、_____----->
  11. 328     if (equals (key, c->key))  /*这个函数,如果返回0,说明两个不相等;*/
  12. 329       break;    /*这里的break语句是因为前面的FOREACH_xxxx这是个for的语句*/
  13. 330   return c;
  14. 331 }
复制代码

  1. 4、______________------------>
  2. 204 #define HASH_POSITION(key, hashfun, size) ((hashfun) (key) % size)
  3. /*这个函数hashfun是在分配jar时     
  4. wget_cookie_jar = cookie_jar_new ();时初始化的.
  5. /*这里初始化*/  return hash_table_new (items,hash_string_nocase , string_cmp_nocase);

  6. 在函数中:
  7. [code]
  8. 272 struct hash_table *
  9. 273 hash_table_new (int items,
  10. 274                 unsigned long (*hash_function) (const void *),
  11. 275                 int (*test_function) (const void *, const void *))
  12. 280   ht->hash_function = hash_function ? hash_function : hash_pointer;
  13. 281   ht->test_function = test_function ? test_function : cmp_pointer;
复制代码
这个函数hash_sting_nocawe和hash_string一样,下面是比较*/

  1. 679 static unsigned long
  2. 680 hash_string_nocase (const void *key)
  3. 681 {
  4. 682   const char *p = key;
  5. 683   unsigned int h = c_tolower (*p);
  6. 684
  7. 685   if (h)
  8. 686     for (p += 1; *p != '\0'; p++)
  9. 687       h = (h << 5) - h + c_tolower (*p);
  10. 688
  11. 689   return h;
  12. 690 }
复制代码

  1. 641 static unsigned long
  2. 642 hash_string (const void *key)
  3. 643 {
  4. 644   const char *p = key;
  5. 645   unsigned int h = *p;
  6. 646
  7. 647   if (h)
  8. 648     for (p += 1; *p != '\0'; p++)
  9. 649       h = (h << 5) - h + *p;
  10. 650
  11. 651   return h;
  12. 652 }
复制代码
所以hash值经过hashfunction()得到的结果是一样的*/

  1. 5、_____________---------------->
  2. 199 #define FOREACH_OCCUPIED_ADJACENT(c, cells, size)                                   \
  3. /*判断是否有cookie->domain占据*/
  4. 200   for (; CELL_OCCUPIED (c); c = NEXT_CELL (c, cells, size))
  5. /*CELL_OCCUPIED()宏定义返回为1,代表被有效值占据,无效值前面定义的是0xffffffff,这里看出不是返回一个有效值,要不就是最后返回的是0xffffffff*/

  6. 188 #define CELL_OCCUPIED(c) ((c)->key != INVALID_PTR)
  7. /*那么就使用下一个cells,如果下一个到达最高点,就折返*/
  8. 195 #define NEXT_CELL(c, cells, size) (c != cells + (size - 1) ? c + 1 : cells)
复制代码

论坛徽章:
1
午马
日期:2013-09-10 11:03:08
186 [报告]
发表于 2011-10-12 23:00 |只看该作者
axel的一个问题

while( 1 )
        {
                int option;
               
                option = getopt_long( argc, argv, "s:n:o:S::NqvhVaH:U:", axel_options, NULL );
                if( option == -1 )
                        break;
               
                switch( option )
                {
                case 'U':
                        strncpy( conf->user_agent, optarg, MAX_STRING);
                        break;
                case 'H':
                        strncpy( conf->add_header[cur_head++], optarg, MAX_STRING );
                        break;
                case 's':
                        if( !sscanf( optarg, "%i", &conf->max_speed ) )
                        {
                                print_help();
                                return( 1 );
                        }
                        break;
                case 'n':
                        if( !sscanf( optarg, "%i", &conf->num_connections ) )
                        {
                                print_help();
                                return( 1 );
                        }
                        break;
                case 'o':
                        strncpy( fn, optarg, MAX_STRING );
                        break;
                case 'S':
                        do_search = 1;
                        if( optarg != NULL )
                        if( !sscanf( optarg, "%i", &conf->search_top ) )
                        {
                                print_help();
                                return( 1 );
                        }
                        break;
                case 'a':
                        conf->alternate_output = 1;
                        break;
                case 'N':
                        *conf->http_proxy = 0;
                        break;
                case 'h':
                        print_help();
                        return( 0 );
                case 'v':
                        if( j == -1 )
                                j = 1;
                        else
                                j ++;
                        break;
                case 'V':
                        print_version();
                        return( 0 );
                case 'q':
                        close( 1 );
                        conf->verbose = -1;
                        if( open( "/dev/null", O_WRONLY ) != 1 )
                        {
                                fprintf( stderr, _("Can't redirect stdout to /dev/null.\n") );
                                return( 1 );
                        }
                        break;
                default:
                        print_help();
                        return( 1 );
                }
        }
这是main函数里面的,就是有点不懂while循环怎么结束,继续执行下面的语句,看到case 不是break就是直接return,这样while循环后面的就执行不了了吧,不懂,求解

论坛徽章:
1
午马
日期:2013-09-10 11:03:08
187 [报告]
发表于 2011-10-13 00:09 |只看该作者
还有就是对宏编译不是很熟悉
就是axel.h里面有个这个
#ifndef        NOGETOPTLONG
#define _GNU_SOURCE
#include <getopt.h>
#endif

在text.c里面有这个
#ifdef NOGETOPTLONG
#define getopt_long( a, b, c, d, e ) getopt( a, b, c )
#else
static struct option axel_options[] =
{
        /* name                        has_arg        flag        val */
        { "max-speed",                1,        NULL,        's' },
        { "num-connections",        1,        NULL,        'n' },
        { "output",                1,        NULL,        'o' },
        { "search",                2,        NULL,        'S' },
        { "no-proxy",                0,        NULL,        'N' },
        { "quiet",                0,        NULL,        'q' },
        { "verbose",                0,        NULL,        'v' },
        { "help",                0,        NULL,        'h' },
        { "version",                0,        NULL,        'V' },
        { "alternate",                0,        NULL,        'a' },
        { "header",                1,        NULL,        'H' },
        { "user-agent",                1,        NULL,        'U' },
        { NULL,                        0,        NULL,        0 }
};
#endif

看那个Makefile觉得 先是axel.h的先执行,由于没有定义NOGETOPTLONG所以#define GNU_SOURCE
与#include <getopt.h>,而在text.c中则判断失败直接else。觉得是否可以这样理解,他们的顺序 是否是按照我理解的那样的?求解

论坛徽章:
0
188 [报告]
发表于 2011-10-13 08:27 |只看该作者
提个建议,大哥们在分析代码时,能不能在开头就说明下分析的源代码在哪个项目哪个文件中。这样,看的人,即使不熟悉的人也立马能找到。毕竟分析源码时,不会把所有代码都贴出来。愚见。

论坛徽章:
0
189 [报告]
发表于 2011-10-13 08:29 |只看该作者
本帖最后由 wangzhen11aaa 于 2011-10-13 11:26 编辑



  1. 返回到
  2. hash_table_get_pair()
  3. 353 int
  4. 354 hash_table_get_pair (const struct hash_table *ht, const void *lookup_key,
  5. 355                      void *orig_key, void *value)
  6. 356 {
  7. 357   struct cell *c = find_cell (ht, lookup_key);
  8. 358   if (CELL_OCCUPIED (c))  /*如果返回的是那个和它相等的,说明被占据了*/
  9. 359     {  
  10. 360       if (orig_key)         
  11. 361         *(void **)orig_key = c->key;  /*那么给orig_key赋值*/
  12. 362       if (value)
  13. 363         *(void **)value = c->value;
  14. 364       return 1;  /*返回1*/
  15. 365     }
  16. 366   else
  17. 367     return 0;  /*否则,就返回0*/
  18. 368 }
复制代码

  1. <----------------_______________
  2. 返回到store_cookie()函数
  3. 206 static void
  4. 207 store_cookie (struct cookie_jar *jar, struct cookie *cookie)
  5. {
  6. 212   if (hash_table_get_pair (jar->chains, cookie->domain,
  7. 213                            &chain_key, &chain_head))  /*这里作判断是否被占据*/
  8. 214     {
  9. 218       struct cookie *prev;
  10. 219       struct cookie *victim = find_matching_cookie (jar, cookie, &prev); /*全面检查,如果端口,路径,主体都匹配,那么就把它替换1、___________----------_>*/
  11. 220
  12. 221       if (victim)
  13. 222         {
  14. 223           /* Remove VICTIM from the chain.  COOKIE will be placed at
  15. 224              the head. */
  16. 225           if (prev)
  17. 226             {
  18. 227               prev->next = victim->next;  /*如果找到,那么替换*/
  19. 228               cookie->next = chain_head;  /*这个chain_head是名字相等的第一个头指针*/
  20. 229             }
  21. 230           else
  22. 231             {
  23. 232               /* prev is NULL; apparently VICTIM was at the head of
  24. 233                  the chain.  This place will be taken by COOKIE, so
  25. 234                  all we need to do is:  */
  26. 235               cookie->next = victim->next; /*如果是空的,那么直接链入第一个头指针*/
  27. 236             }
  28. 237           delete_cookie (victim); /*删除那个受害者*/
  29. 238           --jar->cookie_count;  /*将cookie_count 减 1*/
  30. 239           DEBUGP (("Deleted old cookie (to be replaced.)\n"));
  31. 240         }
  32. 241       else
  33. 242         cookie->next = chain_head;  /*如果没有,那么就直接链入*/
  34. 243     }
  35. 244   else
  36. 245     {
  37. 251       cookie->next = NULL;
  38. 252       chain_key = xstrdup (cookie->domain);
  39. 253     }
  40. 254
  41. 255   hash_table_put (jar->chains, chain_key, cookie); /*根据cookie值,放入hash_table中*/
  42. 256   ++jar->cookie_count;  /*又加上一*/
  43. 257  /*判断是否出现错误*/
  44. 258   IF_DEBUG
  45. 259     {
  46. 260       time_t exptime = cookie->expiry_time;
  47. 261       DEBUGP (("\nStored cookie %s %d%s %s <%s> <%s> [expiry %s] %s %s\n",
  48. 262                cookie->domain, cookie->port,
  49. 263                cookie->port == PORT_ANY ? " (ANY)" : "",
  50. 264                cookie->path,
  51. 265                cookie->permanent ? "permanent" : "session",
  52. 266                cookie->secure ? "secure" : "insecure",
  53. 267                cookie->expiry_time ? datetime_str (exptime) : "none",
  54. 268                cookie->attr, cookie->value));
  55. 269     }
  56. 270 }

复制代码

  1. 172 static struct cookie *
  2. 173 find_matching_cookie (struct cookie_jar *jar, struct cookie *cookie,
  3. 174                       struct cookie **prevptr)
  4. 175 {
  5. 176   struct cookie *chain, *prev;
  6. 177
  7. 178   chain = hash_table_get (jar->chains, cookie->domain); /*根据主体名找到,名字相等的存储链表*/
  8. 179   if (!chain)  /*如果返回为链表的空指针*/
  9. 180     goto nomatch;  /*goto 没有匹配*/
  10. 181
  11. 182   prev = NULL;
  12. 183   for (; chain; prev = chain, chain = chain->next)  /*依次访问链表,来确定哪个和它全方面匹配*/
  13. 184     if (0 == strcmp (cookie->path, chain->path)
  14. 185         && 0 == strcmp (cookie->attr, chain->attr)
  15. 186         && cookie->port == chain->port)
  16. 187       {
  17. 188         *prevptr = prev;  /*如果找到,返回元素的前一个指针*/
  18. 189         return chain;  /*返回这个链表*/
  19. 190       }
  20. 191
  21. 192  nomatch:
  22. 193   *prevptr = NULL;  /*如果没有找到,就返回 NULL*/
  23. 194   return NULL;
  24. 195 }
  25. 196
复制代码

  1. 返回到store_cookie(jar, cookie)就完成了*/
  2. 1235     next:
  3. 1236       continue;
  4. 1237
  5. 1238     abort_cookie:
  6. 1239       delete_cookie (cookie);
  7. 1240     }
  8. 1241   fclose (fp);  /*关闭打开的存储cookie的文件*/
  9. 1242 }
复制代码

  1. <---------------------___________________
  2. wget-1.13/src/http.c" 3588 行
  3. 2647   xzero (hstat);  /*分配并全部初始化为0*/

  4. /*此处设置是否中断后,重新下载 - c*/
  5. 2736       /* Decide whether or not to restart.  */
  6. 2737       if (force_full_retrieve)
  7. 2738         hstat.restval = hstat.len;
  8. 2738         hstat.restval = hstat.len;
  9. 2739       else if (opt.always_rest
  10. 2740           && got_name
  11. 2741           && stat (hstat.local_file, &st) == 0
  12. 2742           && S_ISREG (st.st_mode))

  13. 2746         hstat.restval = st.st_size;
  14. 2747       else if (count > 1)  /*
  15. 2748         /* otherwise, continue where the previous try left off */
  16. 2749         hstat.restval = hstat.len;  /*大小由struct hstat.len记录*/
  17. 2750       else
  18. 2751         hstat.restval = 0;
  19.             2753       /* Decide whether to send the no-cache directive.  We send it in
  20. 2754          two cases:
  21. 2755            a) we're using a proxy, and we're past our first retrieval.
  22. 2756               Some proxies are notorious for caching incomplete data, so
  23. 2757               we require a fresh get.
  24. 2758            b) caching is explicitly inhibited. :决定是否发送no-cache指令,我们以两种方式发送:
  25.                   a. 正在使用代理。有些代理cache 不完整的数据,所以我们要最新的cache数据
  26.                    b.cache 完全不被允许 */

  27. 2765       /* Try fetching the document, or at least its head.  /*设法获得这个文件,至少是头部*/
  28. 2766       err = gethttp (u, &hstat, dt, proxy, iri, count); /*获得cache 的cookie值2、_____------->*/


  29. 这里开始初始化 (stat) =============>
  30. 我们越过去*/
复制代码

  1. /http.c*/
  2. 1567   if (u->scheme == SCHEME_HTTPS)
  3. 1568     {
  4. 1569       /* Initialize the SSL context.  After this has once been done,
  5. 1570          it becomes a no-op.  */
  6. 1571       if (!ssl_init ())  /*如果是HTTPS类型,初始化ssl ,这里面都是外部的函数进行初始化*/*/
  7.          . . . . . .
  8. /*准备发送请求*/
  9. 1595   req = request_new ();3、_______---------->
  10. 下面就是如何建立一个头部,省略了*/
  11. 查找一个主机的相关信息,为建立连接
  12. 663 struct address_list *
  13. 664 lookup_host (const char *host, int flags)
  14. /*这个函数很清楚主机字符串名转化成数字格式*/
  15. uint32_t addr_ipv4 = (uint32_t)inet_addr (host);

复制代码

  1. 152 static struct request *
  2. 153 request_new (void)
  3. 154 {
  4. 155   struct request *req = xnew0 (struct request); ==============>
  5. 156   req->hcapacity = 8;
  6. 157   req->headers = xnew_array (struct request_header, req->hcapacity); /*分配8个头部4、________----->*/
  7. 158   return req;
  8. 159 }
复制代码

  1. ===================>
  2. 136 struct request {  /*一个请求*/
  3. 137   const char *method;
  4. 138   char *arg;
  5. 139
  6. 140   struct request_header {  /*请求头部*/
  7. 141     char *name, *value;
  8. 142     enum rp release_policy;
  9. 143   } *headers;
  10. 144   int hcount, hcapacity;
  11. 145 };
复制代码
4、_________________------------->


[/code][code]
==============================>
1405 struct http_stat         /*存储http的信息*/
1406 {
1407   wgint len;                    /* received length ,接受到的长度 wgint_是64-bit的类型 */
1408   wgint contlen;                /* expected length ,希望的长度 */
1409   wgint restval;                /* the restart value   重启值*/
1410   int res;                      /* the result of last read 最后读的结果*/
1411   char *rderrmsg;               /* error message from read error  错误信息*/
1412   char *newloc;                 /* new location (redirection)  重定位*/
1413   char *remote_time;            /* remote time-stamp string  远端时间戳*/
1414   char *error;                  /* textual HTTP error   HTTP文本错误*/
1415   int statcode;                 /* status code  状态码*/
1416   char *message;                /* status message  状态信息*/
1417   wgint rd_size;                /* amount of data read from socket 在socket文件中的信息 */
1418   double dltime;                /* time it took to download the data 下载的时间*/
1419   const char *referer;          /* value of the referer header.  相关的头部*/
1420   char *local_file;             /* local file name.  本地文件名*/
1421   bool existence_checked;       /* true if we already checked for a file's
1422                                    existence after having begun to download
1423                                    (needed in gethttp for when connection is
1424                                    interrupted/restarted.  当连接被中断时,是否检查已下载的文件*/
1425   bool timestamp_checked;       /* true if pre-download time-stamping checks
1426                                  * have already been performed 检查时间戳值*/
1427   char *orig_file_name;         /* name of file to compare for time-stamping
1428                                  * (might be != local_file if -K is set) 要检查时间戳的文件名*/
1429   wgint orig_file_size;         /* size of file to compare for time-stamping    要检查的时间戳长度  */
1430   time_t orig_file_tstamp;      /* time-stamp of file to compare for
1431                                  * time-stamping  */
1432 };

论坛徽章:
0
190 [报告]
发表于 2011-10-13 09:24 |只看该作者
axel的一个问题

while( 1 )
        {
                int option;
               
                option = getopt_long( argc, argv, "s:n:S::N ...
xbjpkpk 发表于 2011-10-12 23:00



    option==-1时表示解析命令行参数完成,这时从while的循环中break掉,继续执行后面的语句,这是语法基础

switch case 中break是从switch 中跳出,还处于while循环之中,return 的话 整个函数返回,axel退出。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP