⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trophie.c

📁 一个使用诺顿病毒库的病毒扫描的例子程序
💻 C
字号:
#include "trophie.h"int PROC_COUNT = 0;int TROPHIE_TIMEOUT = 30;int vs_ret;int vs_addr;/* Print the usage */void usage(void){	fprintf(stdout, "\n(Version: %s)\n\n", TROPHIE_VERSION);	fprintf(stdout, "USAGE: %s [options]\n", program_name);	fprintf(stdout, "Options:\n");	fprintf(stdout, "  -c        Show some of compiled-in VSAPI engine configuration options\n");	fprintf(stdout, "  -D        Daemon mode (forks into background)\n");	fprintf(stdout, "  -d        Debug mode (shows debugging output, does not fork into background)\n");	fprintf(stdout, "  -f [path] Filename to scan for viruses\n");	fprintf(stdout, "  -s [path] Directory to scan for viruses\n");	fprintf(stdout, "  -h        Help (this screen)\n");	fprintf(stdout, "  -v        VSAPI version (engine and patterns)\n");}/*   We don't want any zombies   Hope this is the right way to do it :)*/void sig_chld(int sig){	/* Suggested by philipp@corpex.de (Philipp Gasch黷z) */	int stat;	pid_t pid;	int serrno = errno;	/* while there are any children that have exited... */#if (defined(HPUX1020) || defined(SLOWARIS))	while((pid = waitpid (-1, &stat, WNOHANG)) && PROC_COUNT)#else	while((pid = waitpid (WAIT_ANY, &stat, WNOHANG)) && PROC_COUNT)#endif	{		if (pid == 0)			{ } /* no children here... */		if (pid == -1)		{			trophie_print(1, "There has been a problem catching a child: %s", strerror(errno));			break;		}		if (pid > 0)		{			PROC_COUNT--;			trophie_print(1, "child finished/exited");		}	}	errno = serrno;}/* Cleanup and exit */void sig_exit(int sig){	trophie_print(0, "SIGNAL [%d] caught - cleaning up and exiting.\n", sig);	trophie_end();	close(sock);	unlink(TROPHIE_SOCKET_NAME);	exit(0);}/* Reload VSAPI */void sig_reload(int sig){	trophie_print(0, "Initializing  : Received -HUP signal [%d] - restarting (reloading config/data)", sig);	trophie_end();	trophie_init();	trophie_version();}void trophie_timeout(int sig){	syslog(LOG_ERR, "Trophie child has timed-out (no data received in %d seconds) - process killed\n", TROPHIE_TIMEOUT);	exit(-1);}/* Here we go... */int main(int argc, char *argv[]){	/* Result returned by SAVI */	int vsapi_result;		/* Related to socket */	int msgsock;		/* Related to other stuff */	int c, pid, cpid;		/* 'Read' buffer */	char buf[256];		/* Pathfile to scan */	char scan[MAXPATHLEN];	/* Directory to scan */	char dir_scan[MAXPATHLEN];		/* Response to send back */	char sock_response[256];		/* fileInfo used to check if the socket is really a socket (for IS_SOCK()) */	struct stat fileInfo;		/* socket structure... */	struct sockaddr_un server;		/* Used when changing the group of the socket */	struct passwd *userInfo;	/* Stupid signal handling code */	int sig_ret;	struct sigaction sa_chld;	struct sigaction sa_hup;	struct sigaction sa_exit;	/* Copy the name of the program (as supplied on the command line) */	program_name = argv[0];	/* Clear the scan (path to the filename to scan */	memset(scan, 0, sizeof(scan));	memset(dir_scan, 0, sizeof(dir_scan));	/* Parse cmdline arguments */	while ((c = getopt(argc, argv, "cDdf:s:hv")) != EOF)	{		switch(c)		{			case 'c':			trophie_init();			trophie_show_settings();			trophie_end();			exit(0);			break;			case 'D':			TROPHIE_DAEMON = 1;			break;						case 'd':			TROPHIE_DEBUG = 1;			break;			case 'f':			if (optarg[0] != '\0')				/* Filename to scan from command line */				strncpy(scan, optarg, sizeof(scan)-1);			break;						case 's':			if (optarg[0] != '\0')				strncpy(dir_scan, optarg, sizeof(dir_scan));			break;			case 'h':			usage();			exit(0);			break;			case 'v':			TROPHIE_DAEMON = 0;			TROPHIE_DEBUG = 0;			trophie_init();			trophie_version();			trophie_end();			exit(0);			break;			default:			TROPHIE_DAEMON = 0;			TROPHIE_DEBUG = 0;			break;		}	}	/* We will check if the TROPHIE_SOCKET_GROUP exists first */	if (!getpwnam(TROPHIE_SOCKET_GROUP))	{		trophie_print(0, "ERROR: TROPHIE_SOCKET_GROUP user (%s) does not exist - exiting", TROPHIE_SOCKET_GROUP);		if (TROPHIE_DAEMON == 1)			fprintf(stderr, "ERROR: TROPHIE_SOCKET_GROUP user (%s) does not exist - exiting\n", TROPHIE_SOCKET_GROUP);		exit(1);	}	/* If TROPHIE_DEBUG/TROPHIE_DAEMON are not set (0 or 1) = set to 0 */	if (TROPHIE_DEBUG != 0 && TROPHIE_DEBUG != 1)		TROPHIE_DEBUG = 0;		if (TROPHIE_DAEMON != 0 && TROPHIE_DAEMON != 1)		TROPHIE_DAEMON = 0;	/* Initialize VSAPI engine/data */	trophie_init();	/* Spit out the version number(s) */	trophie_version();	/* If file is specified on a command line, scan it and return result */	/* When scan is finished, exit */	if (scan[0] != '\0')	{		trophie_print(0, "Scanning file : '%s' ", scan);		vsapi_result = trophie_scanfile(scan);		trophie_end();		exit(0);	}		/* NOTE: directory scanning is implemented just for command line - it won't be implemented for socket usage */	/* If directory is specified on a command line, scan it and return results */	/* When scan is finished, exit */	if (dir_scan[0] != '\0')	{		trophie_print(0, "Scanning dir  : '%s' ", dir_scan);		vsapi_result = trophie_scandir(dir_scan);		trophie_end();		exit(0);	}	/* Create a socket */	if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)	{		trophie_print(0, "ERROR: socket() failed in main()");		exit(1);	}	/* Check if the socket already exists */	if (stat(TROPHIE_SOCKET_NAME, &fileInfo) == 0)	{		if (S_ISSOCK(fileInfo.st_mode))		{			trophie_print(0, "ERROR: Socket '%s' already exists!", TROPHIE_SOCKET_NAME);			trophie_print(0, "NOTE: Removing existing socket (ouch!)");			if (unlink(TROPHIE_SOCKET_NAME) == -1)			{				trophie_print(0, "ERROR: Could not remove socket '%s'. Aborting!", TROPHIE_SOCKET_NAME);				exit(1);			}		}	}	/* Set the umask */	umask(0007);		/* Set the socket properties (family, name) */	server.sun_family = AF_UNIX;	strncpy(server.sun_path, TROPHIE_SOCKET_NAME, sizeof(server.sun_path)-1);	trophie_print(1, "server.sun_path has a name: [%s]", TROPHIE_SOCKET_NAME);	/* Bind a socket */	if (bind(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) == -1)	{		trophie_print(0, "ERROR: bind() failed in main()");		exit(1);	}	/* Change the owner/group of the socket */	userInfo = getpwnam(TROPHIE_SOCKET_GROUP);	if (chown(TROPHIE_SOCKET_NAME, -1, (gid_t)userInfo->pw_gid) == -1)	{		trophie_print(0, "ERROR: failed to chown() the socket - socket remains owned by root:root");	}		/* Start listening */	if (listen(sock, TROPHIE_LISTEN_QUEUE) == -1)	{		trophie_print(0, "ERROR: listen() failed in main()");		exit(1);	}	/* If TROPHIE_DAEMON is set, show some message */	/* Argh - at this point, everything already goes to syslog (if TROPHIE_DAEMON is set) - will change this later :) */	if (TROPHIE_DAEMON == 1)	{		if ((pid = fork()) > 0)		{			trophie_print(0, "%s placed in the background [PID: %d]", program_name, pid);			exit(0);		}		else if (pid == -1)		{			perror("fork");			trophie_print(0, "ERROR: Could not fork() - aborting");			exit(1);		}		fprintf(stderr, "%s placed in the background\n", program_name);	}	/* Catch SIGCHLD */	sa_chld.sa_handler = sig_chld;	sigfillset(&sa_chld.sa_mask);	sa_chld.sa_flags = SA_RESTART;	sig_ret = sigaction(SIGCHLD, &sa_chld, NULL);	if (sig_ret < 0)		trophie_print(0, "ERROR: Could not install SIGCHLD signal handler (sig_ret = [%d])", sig_ret);	/* Reload VSAPI on HUP signal */	sa_hup.sa_handler = sig_reload;	sigfillset(&sa_hup.sa_mask);	sa_hup.sa_flags = SA_RESTART;	sig_ret = sigaction(SIGHUP, &sa_hup, NULL);	if (sig_ret < 0)		trophie_print(0, "ERROR: Could not install SIGHUP signal handler (sig_ret = [%d])", sig_ret);	/* Try to cleanup if one of these gets caught... */	sa_exit.sa_handler = sig_exit;	sigfillset(&sa_exit.sa_mask);	sa_exit.sa_flags = 0;	sig_ret = sigaction(SIGINT, &sa_exit, NULL);	if (sig_ret < 0)		trophie_print(0, "ERROR: Could not install SIGINT signal handler (sig_ret = [%d])", sig_ret);	sig_ret = sigaction(SIGTERM, &sa_exit, NULL);	if (sig_ret < 0)		trophie_print(0, "ERROR: Could not install SIGTERM signal handler (sig_ret = [%d])", sig_ret);	sig_ret = sigaction(SIGQUIT, &sa_exit, NULL);	if (sig_ret < 0)		trophie_print(0, "ERROR: Could not install SIGQUIT signal handler (sig_ret = [%d])", sig_ret);	sig_ret = sigaction(SIGSEGV, &sa_exit, NULL);	if (sig_ret < 0)		trophie_print(0, "ERROR: Could not install SIGSEGV signal handler (sig_ret = [%d])", sig_ret);	trophie_print(1, "Signal handlers set");	/* Fun begins... */	for (;;)	{		/* Accept the connection(s) */		msgsock = accept(sock, 0, 0);		trophie_print(1, "accept() set");		/*		   If we got EINTR, it means some signal is caught -		   on HUP, we'll reload (and ignore this error), and on		   other signal we'll die anyway (probably :)		*/		if (msgsock == -1 && errno != EINTR)		{			trophie_print(0, "error in accept() - exiting");		}		else if (msgsock == -1) /* this should be EINTR now */		{			trophie_print(1, "EINTR set/caught in accept() loop - some signal received");			continue;		}		else		{			/* Suggested by philipp@corpex.de (Philipp Gasch黷z) */			while(PROC_COUNT >= MAX_PROC)				usleep(10);			/* Fork */			if ((cpid = fork()))			{				trophie_print(1, "forked() a child - everything seems ok");				close(msgsock);				PROC_COUNT++;				continue;			}			else			{				/* child */				struct sigaction sa_handle;				FILE *msgfp;				struct stat reqstat;				/*	bzero((char *)(&sa_exit), sizeof(sa_exit)); */				sigemptyset(&sa_handle.sa_mask);				sa_handle.sa_handler = trophie_timeout;				if ((sig_ret = sigaction(SIGALRM, &sa_handle, NULL)) < 0)					trophie_print(0, "Error setting handler for SIGINT");				/* Set the priority - try to 'save' the system :) */				setpriority(PRIO_PROCESS, 0, PRIORITY);				/* Clean the buffer */								memset(buf, 0, sizeof(buf));				trophie_print(1, "cleared buf using memset()");				/*				  We will set the alarm (timeout)				  If Trophie doesn't receive anythin within TROPHIE_TIMEOUT seconds - quit				*/				alarm(TROPHIE_TIMEOUT);				/* We will 'reopen' the socket, for fgets */				msgfp = fdopen(msgsock, "r");								while (fgets(buf, sizeof(buf)-1, msgfp))				{					/* If it is end of file, ferror() should return 0 - but if it is an error... we better try to catch it */					if (buf == NULL)					{						if (ferror(msgfp))						{							trophie_print(0, "fgets() error in main() [while reading from socket] - exiting");							exit(-1);						}					}					trophie_print(1, "read %d bytes from socket", strlen(buf));										/* Clear the virus name */					memset(VIR_NAME, 0, sizeof(VIR_NAME));					/* Remove the newline (if it exists) */					if (strchr(buf, '\n'))						*strchr(buf, '\n') = '\0';										trophie_print(1, "[%d] data read [%s]", getpid(), buf);										/* Now, let's decide if we'll scan file or a dir... */					if ((stat(buf, &reqstat)) == 0)					{						if (S_ISDIR(reqstat.st_mode))						{							vsapi_result = trophie_scandir(buf);						}						else if (S_ISREG(reqstat.st_mode))						{							vsapi_result = trophie_scanfile(buf);						}						else						{							trophie_print(0, "Error : What was requested is not file or directory - aborting");							vsapi_result = -1;						}					}					else					{						/* File/dir doesn't exist */						vsapi_result = -1;					}					/* Clear the response buffer */					memset(sock_response, 0, sizeof(sock_response));					/* "Craft" the response (this is so lame) - FIXME */					if ( (VIR_NAME[0] != '\0') && (REPORT_VIRUSNAME == 1) )						snprintf(sock_response, sizeof(sock_response)-1, "%d:%s", vsapi_result, VIR_NAME);					else						snprintf(sock_response, sizeof(sock_response)-1, "%d", vsapi_result);					trophie_print(1, "response = [%s]", sock_response);					trophie_print(1, "sending the response [%s] to socket", sock_response);					/* Complain on errors - do nothing if everything is okay */					if (write(msgsock, sock_response, sizeof(sock_response)) > 0)						trophie_print(1, "response [%s] sent!", sock_response);					else						trophie_print(0, "ERROR: write() to remove socket failed!");					trophie_print(1, "closing the socket");				}				alarm(0);							trophie_print(1, "I am gone...");				exit(0);			}		}				close(msgsock);	}	/* This will never be reached, but we'll add it for 'just in case' factor */	close(sock);	unlink(TROPHIE_SOCKET_NAME);	trophie_end();	trophie_print(0, "Cleanup       : VSAPI cleaned up and terminated (by itself, huh?)");	/* Bye, bye... */	exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -