就简单给代码加上些注释,方便理解。第一次浏览,应该会有不正确的理解。后面会继续学习修改。

文件:clamscan\clamscan.c

代码如下:

nt main(int argc, char **argv)
{
int ds, dms, ret;
double mb;
struct timeval t1, t2;
#ifndef C_WINDOWS
struct timezone tz;
#endif
struct optstruct *opt;
const char *pt; //pthread是一个通用的跨平台高性能线程库
//暂时没发现加入的地方
//在程序开始的时候要调用
#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
if(!pthread_win32_process_attach_np()) {
mprintf("!Can't start the win32 pthreads layer\n");
return 72;
}
#endif //这里进行参数解析
//具体规则待会查看下
opt = opt_parse(argc, argv, clamscan_shortopt, clamscan_longopt, NULL);
if(!opt) {
mprintf("!Can't parse the command line\n");
return 40;
} //以下开始进行命令判断
if(opt_check(opt, "verbose")) {
mprintf_verbose = 1;
logg_verbose = 1;
} if(opt_check(opt, "quiet"))
mprintf_quiet = 1; if(opt_check(opt, "stdout"))
mprintf_stdout = 1; if(opt_check(opt, "debug")) {
#if defined(C_LINUX)
/* njh@bandsman.co.uk: create a dump if needed */
struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
if(setrlimit(RLIMIT_CORE, &rlim) < 0)
perror("setrlimit");
#endif
cl_debug(); /* enable debug messages */
} if(opt_check(opt, "version")) {
print_version(opt_arg(opt, "database"));
opt_free(opt);
return 0;
} if(opt_check(opt, "help")) {
opt_free(opt);
help();
return 0;
} if(opt_check(opt, "recursive"))
recursion = 1; if(opt_check(opt, "infected"))
printinfected = 1; if(opt_check(opt, "bell"))
bell = 1; if(opt_check(opt, "tempdir"))
cl_settempdir(opt_arg(opt, "tempdir"), 0); if(opt_check(opt, "leave-temps"))
cl_settempdir(NULL, 1); //日志初始化
if(opt_check(opt, "log")) {
logg_file = opt_arg(opt, "log");
if(logg("#\n-------------------------------------------------------------------------------\n\n")) {
mprintf("!Problem with internal logger.\n");
opt_free(opt);
return 62;
}
} else
logg_file = NULL; //一些数字参数合法化检验 if(opt_check(opt, "max-scansize")) {
pt = opt_arg(opt, "max-scansize");
if(!strchr(pt, 'M') && !strchr(pt, 'm')) {
if(!cli_isnumber(pt)) {
logg("!--max-scansize requires a natural number\n");
opt_free(opt);
return 40;
}
}
} if(opt_check(opt, "max-filesize")) {
pt = opt_arg(opt, "max-filesize");
if(!strchr(pt, 'M') && !strchr(pt, 'm')) {
if(!cli_isnumber(pt)) {
logg("!--max-filesize requires a natural number\n");
opt_free(opt);
return 40;
}
}
} if(opt_check(opt, "max-files")) {
if(!cli_isnumber(opt_arg(opt, "max-files"))) {
logg("!--max-files requires a natural number\n");
opt_free(opt);
return 40;
}
} if(opt_check(opt, "max-recursion")) {
if(!cli_isnumber(opt_arg(opt, "max-recursion"))) {
logg("!--max-recursion requires a natural number\n");
opt_free(opt);
return 40;
}
} if(opt_check(opt, "max-mail-recursion")) {
if(!cli_isnumber(opt_arg(opt, "max-mail-recursion"))) {
logg("!--max-mail-recursion requires a natural number\n");
opt_free(opt);
return 40;
}
} if(opt_check(opt, "max-dir-recursion")) {
if(!cli_isnumber(opt_arg(opt, "max-dir-recursion"))) {
logg("!--max-dir-recursion requires a natural number\n");
opt_free(opt);
return 40;
}
} if(opt_check(opt, "max-ratio")) {
if(!cli_isnumber(opt_arg(opt, "max-ratio"))) {
logg("!--max-ratio requires a natural number\n");
opt_free(opt);
return 40;
}
} memset(&info, 0, sizeof(struct s_info)); //设置默认的文件I/O操作
//Windows下二进制
//DEBUG下设置报告方式?
#ifdef C_WINDOWS
_set_fmode(_O_BINARY);
#ifdef CL_DEBUG
{
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
}
#endif
gettimeofday(&t1, NULL);
#else
gettimeofday(&t1, &tz);
#endif //这里就开始调用一个扫描的管理类方法来扫毒
//返回的ret说明信息
ret = scanmanager(opt); //下面开始就是日志记录?
if(!opt_check(opt, "disable-summary") && !opt_check(opt, "no-summary")) {
#ifdef C_WINDOWS
gettimeofday(&t2, NULL);
#else
gettimeofday(&t2, &tz);
#endif
ds = t2.tv_sec - t1.tv_sec;
dms = t2.tv_usec - t1.tv_usec;
ds -= (dms < 0) ? (1):(0);
dms += (dms < 0) ? (1000000):(0);
logg("\n----------- SCAN SUMMARY -----------\n");
logg("Known viruses: %u\n", info.sigs);
logg("Engine version: %s\n", cl_retver());
logg("Scanned directories: %u\n", info.dirs);
logg("Scanned files: %u\n", info.files);
logg("Infected files: %u\n", info.ifiles);
if(info.notremoved) {
logg("Not removed: %u\n", info.notremoved);
}
if(info.notmoved) {
logg("Not %s: %u\n", opt_check(opt, "copy") ? "moved" : "copied", info.notmoved);
}
mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;
logg("Data scanned: %2.2lf MB\n", mb);
logg("Time: %u.%3.3u sec (%u m %u s)\n", ds, dms/1000, ds/60, ds%60);
} opt_free(opt); //对应于上面的pthread开始函数
#if defined(C_WINDOWS) && defined(CL_THREAD_SAFE)
if(!pthread_win32_process_detach_np()) {
logg("!Can't stop the win32 pthreads layer\n");
return 72;
}
#endif return ret;
}

原文:http://blog.csdn.net/betabin/article/details/7421910

ClamAV学习【2】——clamscan入口函数浏览的更多相关文章

  1. C++学习--入口函数

    在学习第一个C++程序的时候发现控制台程序的入口函数是int _tmain而不是main,查了资料才发现_tmain()是为了支持unicode所使用的main一个别名,宏定义在<stdafx. ...

  2. JQuery学习:事件绑定&入口函数&样式控制

    1.基础语法学习: 1.事件绑定 2.入口函数 3.样式控制 <!DOCTYPE html> <html lang="en"> <head> & ...

  3. Egret 学习之 入口函数 及开始编写程序(三)

    1,Egret的程序入口: C和java是以一个main函数作为入口,但egret类似于ActionScript 是以一个文档类作为入口,确切的说是以这个文档类的构造函数作为入口: 2,文档类的构造函 ...

  4. Qt Windows下链接子系统与入口函数(终结版)(可同时存在main和WinMain函数)

    Qt Windows下链接子系统与入口函数(终结版) 转载自:http://blog.csdn.net/dbzhang800/article/details/6358996 能力所限,本讨论仅局限于M ...

  5. C++的入口函数

    我们最开始学习c++时,就知道要写一个main()函数,并且知道这是整个函数的入口,但是c++不只有main()函数这一个入口. 一.对于不同的程序函数入口是不同的. main()是WINDOWS的控 ...

  6. 2、jQuery的基本概念-必看-版本-入口函数- jq对象和dom对象区别

    1.4. jQuery的版本 官网下载地址:http://jquery.com/download/ jQuery版本有很多,分为1.x 2.x 3.x 大版本分类: 1.x版本:能够兼容IE678浏览 ...

  7. 01-老马jQuery教程-jQuery入口函数及选择器

    前言 这套jQuery教程是老马专门为寒门子弟而录制,希望大家看到后能转发给更多的寒门子弟.视频都是免费,请参考课程地址:https://chuanke.baidu.com/s5508922.html ...

  8. u-boot-1.1.6第2阶段入口函数start_armboot分析

    学习目标: 1.分析u-boot-1.1.6第2阶段入口函数void start_armboot (void),熟悉该函数所实现的功能 2.为后面能够掌握u-boot-1.1.6如何启动内核过程打下基 ...

  9. [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数

    了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...

随机推荐

  1. WPF 出现“调用线程无法访问此对象,因为另一个线程拥有该对象”

    引起这种错误多半是由于在非UI线程刷新界面,解决此问题可以使用Dispatcher this.Dispatcher.Invoke(new Action(() => { UpdateUI(stri ...

  2. Sonar及其eclipse插件的安装 详细 http://www.importnew.com/10017.html

    参考:http://www.importnew.com/10017.html

  3. tomcat没有发布maven项目依赖的本地jar包

    建立springMVC的maven项目,平时使用的jar包都是在pom.xml文件配置依赖关系, maven会自动从仓库中下载,这样使用tomcat部署发布都没有问题.但有时我们需要使用maven仓库 ...

  4. java中getAttribute和getParameter的区别

    getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型 getParame ...

  5. 阿里云自定义监控tomcat进程数

    阿里云提供自定义监控SDK,这有助于我们定制化的根据自身业务来做监控,下面我就根据业务需求来介绍一个简单的自定义监控配置. 阿里提供了2个版本的自定义监控接口:自定义监控SDK(python版) :c ...

  6. C#中DateTime的各种操作

    C#时间戳与日期互转 /// <summary> /// 时间戳转为C#格式时间 /// </summary> /// <param name="timeSta ...

  7. Halcon中xld的常见特征的含义总结

    如下图:

  8. python 开发简单的聊天工具-乾颐堂

    python 太强大了,以至于它什么都可以做,哈哈,开个玩笑.但是今天要讲的真的是一个非常神奇的应用. 使用python写一个聊天工具 其实大家平时用的QQ类似的聊天工具,也是使用socket进行聊天 ...

  9. [OS] 远程启动计划任务时以管理员身份运行

    在Jenkins建了一个task自动启动Selenium的Grid,命令行是这样写的: schtasks /end /tn RestartGrid /s SZTEST201606 /u szdomai ...

  10. FW:程序在内存的划分(转)

    一.预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...