使用 Visual Studio 编译 wget 为库文件

添加代码与预编译指令与上一篇使用 Visual Studio 编译 wget 为可执行文件一致,区别在于这回建的是静态库工程(编译为动态库过程类似:))

从wget的main函数开始读下来,发现问题不少,程序可能基于效率或者编码方便的因素,大量使用静态变量,导致在将其修改为静态库之后存在潜在危险。

需要修改的部分如下:

1、main.c文件,no_prefix函数:

static char *
no_prefix (
const char *s)
{
static char buffer[1024];
static char *p = buffer;
...
}

由于原程序使用指针p来指向尚未处理的数据,no_prefix函数调用一次p指针向后移动一段距离,直到buffer的末尾。

因为原有wget程序一次运行完成之后即退出,这段代码不会出问题,但在做为函数调用进行多次下载的时候,指针p没有移动到buffer的开头,就导致了缓冲区溢出问题。

只需在一次下载结束之后对其设置重置指针p的标志即可在下次执行下载任务开始前对指针p进行归位处理。

在no_prefix函数变量定义之后添加如下代码:

ContractedBlock.gifExpandedBlockStart.gifView Code
if (g_iIsClearBufferPointer == 1) //g_iIsClearBufferPointer为全局变量作为Flag
{
g_iIsClearBufferPointer
= 0;
p
= buffer;
}

2、添加回调函数及其参数定义

ContractedBlock.gifExpandedBlockStart.gifView Code
typedef enum{
Loading,
Complete,
Fail
= -1
} DownloadInfoType;

typedef
struct DownloadInfo_tag
{
float Percent;
char *pInfoStr;
void *pTag;
DownloadInfoType InfoType;
} DownloadInfo;

typedef
void (* DOWNLOAD_CALLBACK)(DownloadInfo);
DOWNLOAD_CALLBACK g_download_process_callback
= NULL;

3、外部调用下载所用函数:

ContractedBlock.gifExpandedBlockStart.gifView Code
//************************************
// Method: downloadFile
// FullName: downloadFile
// Access: public
// Returns: void
// Qualifier: 下载所用函数
// Parameter: char * pCmdStr:下载参数字符串,与wget命令行下载方式相同
// Parameter: DOWNLOAD_CALLBACK callbackFun:传入的回调函数指针
//************************************
void downloadFile(char *pCmdStr, DOWNLOAD_CALLBACK callbackFun)
{
char **cmd;
int iItemNum = 0;
int i;
g_download_process_callback
= callbackFun;
cmd
= (char**) malloc(sizeof(char*) * MAX_CMD_NUM);
for (i = 0; i < MAX_CMD_NUM; i++)
{
cmd[i]
= ( char* ) malloc(sizeof(char) * MAX_PATH);
ZeroMemory(cmd[i], MAX_PATH);
}
divideCmdString(pCmdStr, cmd, MAX_CMD_NUM,
&iItemNum);

wget_main(iItemNum, cmd);  
//原有wget的main函数

for (i = 0; i < MAX_CMD_NUM; i++)
{
free(cmd[i]);
cmd[i]
= NULL;
}
free(cmd);
cmd
= NULL;
}

4、模拟系统分割参数字符串供wget的原有main函数使用

ContractedBlock.gifExpandedBlockStart.gifView Code
//************************************
// Method: divideCmdString
// FullName: divideCmdString
// Access: public
// Returns: void
// Qualifier:
// Parameter: char * pCmdStr:输入参数串
// Parameter: char * * pItems:输出分割好的参数
// Parameter: int iMaxItemNum:最大参数数目
// Parameter: int * pIItemNum:分割得到的参数数目
//************************************
void divideCmdString(char *pCmdStr, char **pItems, int iMaxItemNum, int *pIItemNum)
{
if (pCmdStr != NULL && pItems != NULL && pIItemNum != NULL)
{
int iCmdLen = strlen(pCmdStr);
int iCounter = 0;
int iInnerCounter = 0;
int i;
for (i = 0; i < iCmdLen; i++)
{
if (*(pCmdStr + i) == ' ') //是空格
{
if (iInnerCounter > 0)
{
pItems[iCounter][iInnerCounter]
= '\0';
iInnerCounter
= 0;
iCounter
++;
if (iCounter >= iMaxItemNum)
{
*pIItemNum = --iCounter;
return;
}
}
}
else
{
pItems[iCounter][iInnerCounter]
= *(pCmdStr + i);
iInnerCounter
++;
}
}
pItems[iCounter][iInnerCounter]
= '\0';
if (iInnerCounter == 0)
{
*pIItemNum = iCounter;
}
else
{
*pIItemNum = ++iCounter;
}

}
}

5、wget的main函数

第一个步骤是重置会引发错误的静态变量

ContractedBlock.gifExpandedBlockStart.gifView Code
g_iIsClearBufferPointer = 1; //清除no_prefix函数中静态变量指针
optind = 1; //清除getopt.c文件中的同名变量
total_downloaded_bytes = 0; //清除总下载量

第二个步骤是在函数中if (opt.recursive && opt.spider)的判断之后添加进度提示

ContractedBlock.gifExpandedBlockStart.gifView Code
/* Print broken links. */
if (opt.recursive && opt.spider)
{
print_broken_links();
}
//进度提示,此处为下载失败消息
if (total_downloaded_bytes == 0)
{
DownloadInfo info;
ZeroMemory(
&info, sizeof(DownloadInfo));
info.InfoType
= Fail;
g_download_process_callback(info);
}
/* Print the downloaded sum. */

6、在ftp.c的ftp_retrieve_list函数中添加下载进度提示

ContractedBlock.gifExpandedBlockStart.gifView Code
if (file_exists_p (con->target))
{
int iLen = strlen(con->target);
char *pSubStr = ".listing";
int iSubStrLen = strlen(pSubStr);
//避免在检测listing文件时错误发送complete消息 //linsy
if (strcmp(con->target + (iLen - iSubStrLen), pSubStr) != 0)
{
DownloadInfo info;
info.InfoType
= Complete;
info.Percent
= 100;
g_download_process_callback(info);
}
}

7、mswindows.c,添加下载进度提示

ContractedBlock.gifExpandedBlockStart.gifView Code
float g_fOldPercent = -1;

void send_download_process_info(float percent)
{
DownloadInfo info;
if(g_fOldPercent == floor(percent))
{
return ;
}
g_fOldPercent
= floor(percent);
info.Percent
= floor(percent);

info.pInfoStr
= NULL;
if (info.Percent == 100)
{
info.InfoType
= Complete;
}
else
{
info.InfoType
= Loading;
}

if (g_download_process_callback != NULL)
{
g_download_process_callback(info);
}

}

在void ws_percenttitle (double percentage_float)函数中添加调用:send_download_process_info(percentage_float);

接下来就可以开始使用wget的函数直接进行下载了。\(^o^)/~

转载于:https://www.cnblogs.com/blueglass/archive/2011/07/04/2097583.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webpack中实现按需加载

当页面中一个文件过大并且还不一定用到的时候&#xff0c;我们希望在使用到的时候才开始加载这个文件俗称按需加载。这样可以减少页面的响应时间&#xff0c;提高访问速度。 使用webpack打包的出来的文件要实现以上的要求有两种方式&#xff0c;一个是webpack特有的require.en…

【总结】计算机网络常见问题

1、TCP/IP协议与OSI协议 相互通信的两个计算机系统必须高度协调工作才行&#xff0c;而这种“协调”是相当复杂的。 “分层”可将庞大而复杂的问题&#xff0c;转化为若干较小的局部问题&#xff0c;而这些较小的局部问题就比较易于研究和处理。 计算机网络采用了分层的体系结构…

webpack3的CommonsChunkPlugin插件详解

webpack打出来的包在不做处理的情况下是非常大的&#xff0c;所有依赖都被塞进一个文件中&#xff0c;文件中有业务代码&#xff0c;有业务代码依赖的第三方库代码&#xff0c;还有webpack生成的运行时代码等。这样的一个文件不方便静态资源缓存&#xff0c;并且初始化页面的时…

详细介绍jQuery.outerWidth() 函数具体用法

outerWidth()函数用于设置或返回当前匹配元素的外宽度。外宽度默认包括元素的内边距(padding)、边框(border)&#xff0c;但不包括外边距(margin)部分的宽度。你也可以指定参数为true&#xff0c;以包括外边距(margin)部分的宽度。如下图&#xff1a; 如果你要获取其它情况的宽…

SQLite 入门教程(一)基本控制台(终端)命令

一、基本简介 SQLite 是一个自持的&#xff08;self-contained&#xff09;、无服务器的、零配置的、事务型的关系型数据库引擎。因为他很小&#xff0c;所以也可以作为嵌入式数据库内建在你的应用程序中。SQLite 被应用在 Solaris 10操作系统、Mac OS 操作系统、iPhone 和 Sky…

Web前端开发css基础样式总结

颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-255之间 一般都用16进制表示颜色 单位 1. px像素&#xff08;Pixel&#xff09;。像素,与分辨率…

nth-child(n)和nth-of-type(n)

:nth-child(n)&#xff1a;父元素的子元素的第n个 :nth-of-type(n)&#xff1a;父元素的 某类 子元素的第n个 注&#xff1a;n从0起&#xff0c;元素index从1起 nth-child(n)和nth-of-type(n)例&#xff1a; <head><style>body :nth-child(2) {height: 30px;ba…

记录您的里程和社区运行情况:Java EE 7真实体验

miles2run.org是跟踪跑步活动并与亲朋好友共享的简便方法。 可以创建然后跟踪基于天或基于距离的目标。 它还允许创建社区运行目标&#xff0c;并使多个跑步者参与并跟踪他们朝着该目标的活动。 您也可以找出本地跑步者并与他们联系。 该项目已开始&#xff0c;以帮助跟踪#Jav…

oracle在group by时某列有多个值的拼接

最近编码过程中出现了group by后&#xff0c;某些列会有多个值&#xff0c;而我需要把这些多个值的列进行拼接的情况&#xff0c;和大家分享一下。 有如下表student&#xff1a; 我们希望以class分组&#xff0c;每组的信息平铺&#xff0c;效果如下 分组首先想到的肯定是group…

在Spring中使用Asciidoctor:使用Spring MVC渲染Asciidoc文档

Asciidoc是一种基于文本的文档格式&#xff0c;因此如果要将文档提交到版本控制系统中并跟踪不同版本之间的更改&#xff0c;它非常有用。 这使Asciidoc成为编写书籍&#xff0c;技术文档&#xff0c;常见问题解答或用户手册的理想工具。 创建Asciidoc文档后&#xff0c;很可能…

http强缓存在firefox和chrome之间的差异

最近回顾HTTP缓存知识的时候发现了一个问题&#xff0c;设置了强缓存和协商缓存的文件&#xff0c;点击浏览器的刷新按钮的时候在chrome和firefox中的表现不一样。具体表现为chrome走强缓存没有再次发起请求。firefox却在强缓存没有失效的情况下发了请求&#xff0c;返回了304走…

垃圾收集器–串行,并行,CMS,G1(以及Java 8中的新增功能)

4个Java垃圾收集器–错误的选择如何严重影响性能 在2014年&#xff0c;对于大多数开发人员来说&#xff0c;还有两件事仍然是个谜&#xff1a;垃圾收集和了解异性。 由于我对后者知之甚少&#xff0c;所以我认为我会对前者大吃一惊&#xff0c;特别是因为在该领域中&#xff0c…

基于webpack的react脚手架

一、前言&#xff1a;react的cli开发模式太过于简单&#xff0c;好多东西都要自己配置 二、这里有个简单的配置&#xff0c;可以直接上手开发(不熟悉webpack和npm的绕路)&#xff0c;已经完成的配置如下 1&#xff1a;默认ejs模板 2&#xff1a;编译less、scss 3&#xff1…

不要错过使用jOOλ或jOOQ编写Java 8 SQL单行代码的机会

越来越多的人通过为他们的业务采用功能性编程来赶上我们平台的最新更新。 在Data Geekery &#xff0c;我们将Java 8用于jOOQ集成测试&#xff0c;因为将新的Streams API与lambda表达式一起使用使生成临时测试数据变得非常容易。 但是&#xff0c; 我们并不认为JDK提供了尽可…

node实现简单的群体聊天工具

一、使用的node模块 1、express当做服务器 2、socket.io 前后通信的桥梁 3、opn默认打开浏览器的模块(本质上用不到) 难点&#xff1a;前后通信 源码地址&#xff1a;https://github.com/wjf444128852/SimpleChat 欢迎clone并运行、扩展改进、issues 二、基础样子&#…

使用Spring Security的多租户应用程序的无状态会话

从前&#xff0c; 我发表了一篇文章&#xff0c;解释了构建无状态会话的原理 。 巧合的是&#xff0c;我们再次针对多租户应用程序执行同一任务。 这次&#xff0c;我们将解决方案集成到Spring Security框架中&#xff0c;而不是自己构建身份验证机制。 本文将解释我们的方法和…

What?一个 Dubbo 服务启动要两个小时!

前言 前几天在测试环境碰到一个非常奇怪的与 dubbo 相关的问题&#xff0c;事后我在网上搜索了一圈并没有发现类似的帖子或文章&#xff0c;于是便有了这篇。 希望对还未碰到或正在碰到的朋友有所帮助。 现象 现象是这样的&#xff0c;有一天测试在测试环境重新部署一个 dubbo …

使用Project Lombok减少Java应用程序中的样板代码

对Java编程语言最常提出的批评之一是它需要大量的样板代码 。 对于简单的类尤其如此&#xff0c;该类只需要存储一些值就可以。 您需要这些值的getter和setter&#xff0c;也许您还需要一个构造函数&#xff0c;覆盖equals&#xff08;&#xff09;和 hashcode&#xff08;&am…

十六、CI框架之数据库操作get用法

一、使用数据库的Get方法读取内容&#xff0c;如下代码&#xff1a; 二、数据库如下&#xff1a; 二、效果如下&#xff1a; 转载于:https://www.cnblogs.com/tianpan2019/p/11141809.html

WCF系列(二) -- 使用配置文件构建和使用WCF服务

当然&#xff0c;配置一个ServiceHost除了上面说的完全使用代码的方式&#xff0c;更好的方式是使用配置文件&#xff0c;把一些可能需要修改的属性跟代码分离&#xff0c;放到配置文件中&#xff0c;这样可以提供服务配置的灵活性&#xff0c;也更容易维护。 看看前面那个不用…