#include "libclamav.h" int detect_virus_files(char *file) { int fd, ret; unsigned long int size = 0; unsigned int sigs = 0; long double mb; const char *virname; const char *filename; struct cl_engine *engine; struct cl_scan_options options; filename = (const char *)file; if ((fd = open(file, O_RDONLY)) == -1) { printf("Can't open file %s\n", file); return 2; } if ((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) { printf("Can't initialize libclamav: %s\n", cl_strerror(ret)); return 2; } if (!(engine = cl_engine_new())) { printf("Can't create new engine\n"); return 2; } /* Example version macro usage to determine if new feature is available */ #if defined(LIBCLAMAV_VERSION_NUM) && (LIBCLAMAV_VERSION_NUM >= 0x090400) /* Example feature usage lowering max scan time to 15 seconds. */ cl_engine_set_num(engine, CL_ENGINE_MAX_SCANTIME, 15000); #endif /* load all available databases from default directory */ if ((ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT)) != CL_SUCCESS) { printf("cl_load: %s\n", cl_strerror(ret)); close(fd); cl_engine_free(engine); return 2; } printf("Loaded %u signatures.\n", sigs); /* build engine */ if ((ret = cl_engine_compile(engine)) != CL_SUCCESS) { printf("Database initialization error: %s\n", cl_strerror(ret)); cl_engine_free(engine); close(fd); return 2; } /* scan file descriptor */ memset(&options, 0, sizeof(struct cl_scan_options)); options.parse |= ~0; /* enable all parsers */ options.general |= CL_SCAN_GENERAL_HEURISTICS; /* enable heuristic alert options */ if ((ret = cl_scandesc(fd, filename, &virname, &size, engine, &options)) == CL_VIRUS) { printf("Virus detected: %s\n", virname); #if IS_MOVE char temp[sizeof(file) + 3]; sprintf(temp, "rm_ %s", file); //system("rm filename"); FILE *fp = popen(temp, "r"); pclose(fp); fp = NULL; #endif } else { if (ret == CL_CLEAN) { printf("No virus detected.\n"); } else { printf("Error: %s\n", cl_strerror(ret)); cl_engine_free(engine); close(fd); return 2; } } close(fd); /* free memory */ cl_engine_free(engine); /* calculate size of scanned data */ mb = size * (CL_COUNT_PRECISION / 1024) / 1024.0; printf("Data scanned: %2.2Lf MB\n", mb); return ret == CL_VIRUS ? 1 : 0; } int recursive_dir(char *path) { DIR *dp = NULL; struct dirent *st; struct stat sta; int ret = 0; char tmp_name[2048] = { 0 }; st = NULL; memset(&sta, 0, sizeof(struct stat)); memset(tmp_name, 0, 2048); dp = opendir(path); if (dp == NULL) { printf("open dir error!!\n"); return -1; } while (1) { st = readdir(dp); if (NULL == st) //读取完毕 { break; } strcpy(tmp_name, path); if (path[strlen(path) - 1] != '/') //判断路径名是否带/ strcat(tmp_name, "/"); strcat(tmp_name, st->d_name); //新文件路径名 ret = stat(tmp_name, &sta); //查看目录下文件属性 if (ret < 0) { printf("read stat fail\n"); return -1; } if (S_ISDIR(sta.st_mode)) //如果为目录文件 { if (0 == strcmp("..", st->d_name) || 0 == strcmp(".", st->d_name)) //忽略当前目录和上一层目录 continue; else { recursive_dir(tmp_name); //递归读取 } } else //不为目录则打印文件路径名 { printf("%s\n", tmp_name); detect_virus_files(tmp_name); } } closedir(dp); return 0; } int is_file_dir(char *file) { struct stat buf; int result = 0; result = stat(file, &buf); if(S_IFDIR & buf.st_mode) { return 2; } else if(S_IFREG & buf.st_mode) { return 1; } return result; } int _clamav(int argc, char *argv[], char **env) { int is_fd = is_file_dir(argv[argc-1]); if (1 == is_fd) { detect_virus_files(argv[argc-1]); } else if (2 == is_fd) { recursive_dir(argv[argc-1]); } return 0; }