ClamAV学习【2】——clamscan入口函数浏览

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

文件:clamscanclamscan.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
");  
    return 72;  
    }  
#endif  
  
    //这里进行参数解析  
    //具体规则待会查看下  
    opt = opt_parse(argc, argv, clamscan_shortopt, clamscan_longopt, NULL);  
    if(!opt) {  
    mprintf("!Can't parse the command line
");  
    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("#
-------------------------------------------------------------------------------

")) {  
        mprintf("!Problem with internal logger.
");  
        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
");  
        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
");  
        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
");  
        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
");  
        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
");  
        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
");  
        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
");  
        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("
----------- SCAN SUMMARY -----------
");  
    logg("Known viruses: %u
", info.sigs);  
    logg("Engine version: %s
", cl_retver());  
    logg("Scanned directories: %u
", info.dirs);  
    logg("Scanned files: %u
", info.files);  
    logg("Infected files: %u
", info.ifiles);  
    if(info.notremoved) {  
        logg("Not removed: %u
", info.notremoved);  
    }  
    if(info.notmoved) {  
        logg("Not %s: %u
", opt_check(opt, "copy") ? "moved" : "copied", info.notmoved);  
    }  
    mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0;  
    logg("Data scanned: %2.2lf MB
", mb);  
    logg("Time: %u.%3.3u sec (%u m %u s)
", 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
");  
    return 72;  
    }  
#endif  
  
    return ret;  
}  

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

原文地址:https://www.cnblogs.com/sunylat/p/6393401.html