| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2007-02-28 02:44:23 +00:00
										 |  |  |  *  Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net> | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2007-03-31 20:31:04 +00:00
										 |  |  |  *  it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  *  published by the Free Software Foundation. | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  *  GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  *  along with this program; if not, write to the Free Software | 
					
						
							| 
									
										
										
										
											2006-04-09 19:59:28 +00:00
										 |  |  |  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 
					
						
							|  |  |  |  *  MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-06 13:46:08 +00:00
										 |  |  | #if HAVE_CONFIG_H
 | 
					
						
							|  |  |  | #include "clamav-config.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							| 
									
										
										
										
											2004-03-29 00:00:58 +00:00
										 |  |  | #include <sys/stat.h>
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include <sys/socket.h>
 | 
					
						
							|  |  |  | #include <sys/un.h>
 | 
					
						
							|  |  |  | #include <netinet/in.h>
 | 
					
						
							|  |  |  | #include <arpa/inet.h>
 | 
					
						
							| 
									
										
										
										
											2003-12-05 23:45:11 +00:00
										 |  |  | #include <netdb.h>
 | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | #include <utime.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | #ifdef HAVE_SYS_UIO_H
 | 
					
						
							|  |  |  | #include <sys/uio.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | #include "others.h"
 | 
					
						
							|  |  |  | #include "defaults.h"
 | 
					
						
							| 
									
										
										
										
											2004-03-29 00:00:58 +00:00
										 |  |  | #include "options.h"
 | 
					
						
							|  |  |  | #include "cfgparser.h"
 | 
					
						
							|  |  |  | #include "output.h"
 | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | #include "misc.h"
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | #include "str.h"
 | 
					
						
							| 
									
										
										
										
											2007-02-11 00:41:13 +00:00
										 |  |  | #include "client.h"
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-26 22:16:26 +00:00
										 |  |  | #ifdef PF_INET
 | 
					
						
							|  |  |  | # define SOCKET_INET	PF_INET
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | # define SOCKET_INET	AF_INET
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | void move_infected(const char *filename, const struct optstruct *opt); | 
					
						
							|  |  |  | int notremoved = 0, notmoved = 0; | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-10 18:50:26 +00:00
										 |  |  | static int dsresult(int sockd, const struct optstruct *opt) | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int infected = 0, waserror = 0; | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 	char buff[4096], *pt; | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	FILE *fd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-18 23:51:53 +00:00
										 |  |  | #ifndef C_OS2
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     if((fd = fdopen(dup(sockd), "r")) == NULL) { | 
					
						
							| 
									
										
										
										
											2005-01-18 23:51:53 +00:00
										 |  |  | #else /* FIXME: accoriding to YD OS/2 does not support dup() for sockets */
 | 
					
						
							|  |  |  |     if((fd = fdopen(sockd, "r")) == NULL) { | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't open descriptor for reading.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while(fgets(buff, sizeof(buff), fd)) { | 
					
						
							|  |  |  | 	if(strstr(buff, "FOUND\n")) { | 
					
						
							|  |  |  | 	    infected++; | 
					
						
							|  |  |  | 	    logg("%s", buff); | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  | 	    if(opt_check(opt, "move") || opt_check(opt, "copy")) { | 
					
						
							| 
									
										
										
										
											2006-05-01 17:38:53 +00:00
										 |  |  | 		/* filename: Virus FOUND */ | 
					
						
							|  |  |  | 		if((pt = strrchr(buff, ':'))) { | 
					
						
							|  |  |  | 		    *pt = 0; | 
					
						
							|  |  |  | 		    move_infected(buff, opt); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2008-03-20 12:10:17 +00:00
										 |  |  | 		    logg("!Incorrect output from clamd. File not %s.\n", opt_check(opt, "move") ? "moved" : "copied"); | 
					
						
							| 
									
										
										
										
											2006-05-01 17:38:53 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-15 18:30:18 +00:00
										 |  |  | 	    } else if(opt_check(opt, "remove")) { | 
					
						
							| 
									
										
										
										
											2006-05-01 17:38:53 +00:00
										 |  |  | 		if(!(pt = strrchr(buff, ':'))) { | 
					
						
							| 
									
										
										
										
											2008-03-20 12:10:17 +00:00
										 |  |  | 		    logg("!Incorrect output from clamd. File not removed.\n"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2006-05-01 17:38:53 +00:00
										 |  |  | 		    *pt = 0; | 
					
						
							|  |  |  | 		    if(unlink(buff)) { | 
					
						
							| 
									
										
										
										
											2008-03-20 12:10:17 +00:00
										 |  |  | 			logg("!%s: Can't remove.\n", buff); | 
					
						
							| 
									
										
										
										
											2006-05-01 17:38:53 +00:00
										 |  |  | 			notremoved++; | 
					
						
							|  |  |  | 		    } else { | 
					
						
							| 
									
										
										
										
											2008-01-23 16:38:36 +00:00
										 |  |  | 			logg("~%s: Removed.\n", buff); | 
					
						
							| 
									
										
										
										
											2006-05-01 17:38:53 +00:00
										 |  |  | 		    } | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	if(strstr(buff, "ERROR\n")) { | 
					
						
							| 
									
										
										
										
											2008-03-20 12:10:17 +00:00
										 |  |  | 	    logg("~%s", buff); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    waserror = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-18 23:51:53 +00:00
										 |  |  | #ifndef C_OS2 /* Small memory leak under OS/2 (see above) */
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     fclose(fd); | 
					
						
							| 
									
										
										
										
											2005-01-18 23:51:53 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  |     return infected ? infected : (waserror ? -1 : 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | static int dsfile(int sockd, const char *scantype, const char *filename, const struct optstruct *opt) | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int ret; | 
					
						
							| 
									
										
										
										
											2005-01-26 17:45:25 +00:00
										 |  |  | 	char *scancmd; | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-28 02:44:23 +00:00
										 |  |  |     scancmd = malloc(strlen(filename) + 20); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  |     sprintf(scancmd, "%s %s", scantype, filename); | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if(write(sockd, scancmd, strlen(scancmd)) <= 0) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't write to the socket.\n"); | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 	free(scancmd); | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     free(scancmd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ret = dsresult(sockd, opt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!ret) | 
					
						
							| 
									
										
										
										
											2008-01-23 16:38:36 +00:00
										 |  |  | 	logg("~%s: OK\n", filename); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  |     return ret; | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-10 18:50:26 +00:00
										 |  |  | static int dsstream(int sockd, const struct optstruct *opt) | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int wsockd, loopw = 60, bread, port, infected = 0; | 
					
						
							|  |  |  | 	struct sockaddr_in server; | 
					
						
							| 
									
										
										
										
											2004-07-01 01:24:20 +00:00
										 |  |  | 	struct sockaddr_in peer; | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	socklen_t peer_size; | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	char buff[4096], *pt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     if(write(sockd, "STREAM", 6) <= 0) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't write to the socket.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while(loopw) { | 
					
						
							| 
									
										
										
										
											2007-10-05 23:48:44 +00:00
										 |  |  | 	memset(buff, 0, sizeof(buff)); | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	if(read(sockd, buff, sizeof(buff)) > 0) { | 
					
						
							|  |  |  | 	    if((pt = strstr(buff, "PORT"))) { | 
					
						
							|  |  |  | 		pt += 5; | 
					
						
							|  |  |  | 		sscanf(pt, "%d", &port); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	loopw--; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!loopw) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Daemon not ready for stream scanning.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* connect to clamd */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if((wsockd = socket(SOCKET_INET, SOCK_STREAM, 0)) < 0) { | 
					
						
							|  |  |  | 	perror("socket()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't create the socket.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     server.sin_family = AF_INET; | 
					
						
							|  |  |  |     server.sin_port = htons(port); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-01 01:24:20 +00:00
										 |  |  |     peer_size = sizeof(peer); | 
					
						
							|  |  |  |     if(getpeername(sockd, (struct sockaddr *) &peer, &peer_size) < 0) { | 
					
						
							|  |  |  | 	perror("getpeername()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't get socket peer name.\n"); | 
					
						
							| 
									
										
										
										
											2004-07-01 01:24:20 +00:00
										 |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-28 20:28:26 +00:00
										 |  |  |     switch (peer.sin_family) { | 
					
						
							|  |  |  | 	case AF_UNIX: | 
					
						
							|  |  |  | 	    server.sin_addr.s_addr = inet_addr("127.0.0.1"); | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	case AF_INET: | 
					
						
							|  |  |  | 	    server.sin_addr.s_addr = peer.sin_addr.s_addr; | 
					
						
							|  |  |  | 	    break; | 
					
						
							|  |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2008-03-20 12:10:17 +00:00
										 |  |  | 	    logg("^Unexpected socket type: %d.\n", peer.sin_family); | 
					
						
							| 
									
										
										
										
											2004-07-28 20:28:26 +00:00
										 |  |  | 	    return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-07-01 01:24:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     if(connect(wsockd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) < 0) { | 
					
						
							|  |  |  | 	close(wsockd); | 
					
						
							|  |  |  | 	perror("connect()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't connect to clamd [port: %d].\n", port); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while((bread = read(0, buff, sizeof(buff))) > 0) { | 
					
						
							|  |  |  | 	if(write(wsockd, buff, bread) <= 0) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't write to the socket.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    close(wsockd); | 
					
						
							|  |  |  | 	    return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     close(wsockd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     memset(buff, 0, sizeof(buff)); | 
					
						
							|  |  |  |     while((bread = read(sockd, buff, sizeof(buff))) > 0) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("%s", buff); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	if(strstr(buff, "FOUND\n")) { | 
					
						
							|  |  |  | 	    infected++; | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-07 01:53:16 +00:00
										 |  |  | 	} else if(strstr(buff, "ERROR\n")) { | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    logg("%s", buff); | 
					
						
							|  |  |  | 	    return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	memset(buff, 0, sizeof(buff)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return infected; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-10 18:50:26 +00:00
										 |  |  | static char *abpath(const char *filename) | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct stat foo; | 
					
						
							|  |  |  | 	char *fullpath, cwd[200]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(stat(filename, &foo) == -1) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't access file %s\n", filename); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	perror(filename); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2007-02-28 02:44:23 +00:00
										 |  |  | 	fullpath = malloc(200 + strlen(filename) + 10); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | #ifdef C_CYGWIN
 | 
					
						
							|  |  |  | 	sprintf(fullpath, "%s", filename); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	if(!getcwd(cwd, 200)) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't get absolute pathname of current working directory.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    return NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	sprintf(fullpath, "%s/%s", cwd, filename); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return fullpath; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-10 18:50:26 +00:00
										 |  |  | static int dconnect(const struct optstruct *opt) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct sockaddr_un server; | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	struct sockaddr_in server2; | 
					
						
							| 
									
										
										
										
											2003-12-05 23:45:11 +00:00
										 |  |  | 	struct hostent *he; | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	struct cfgstruct *copt; | 
					
						
							|  |  |  | 	const struct cfgstruct *cpt; | 
					
						
							| 
									
										
										
										
											2006-05-15 18:30:18 +00:00
										 |  |  | 	const char *clamav_conf = opt_arg(opt, "config-file"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	int sockd; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if(!clamav_conf) | 
					
						
							|  |  |  | 	clamav_conf = DEFAULT_CFG; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-01 00:42:33 +00:00
										 |  |  |     if((copt = getcfg(clamav_conf, 1)) == NULL) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Can't parse the configuration file.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-20 01:37:36 +00:00
										 |  |  |     memset((char *) &server, 0, sizeof(server)); | 
					
						
							|  |  |  |     memset((char *) &server2, 0, sizeof(server2)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     /* Set default address to connect to */ | 
					
						
							| 
									
										
										
										
											2004-03-18 13:59:43 +00:00
										 |  |  |     server2.sin_addr.s_addr = inet_addr("127.0.0.1");     | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-22 15:54:28 +00:00
										 |  |  |     if((cpt = cfgopt(copt, "LocalSocket"))->enabled) { | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	server.sun_family = AF_UNIX; | 
					
						
							| 
									
										
										
										
											2004-04-06 22:43:44 +00:00
										 |  |  | 	strncpy(server.sun_path, cpt->strarg, sizeof(server.sun_path)); | 
					
						
							| 
									
										
										
										
											2008-05-27 16:30:47 +00:00
										 |  |  | 	server.sun_path[sizeof(server.sun_path)-1]='\0'; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if((sockd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { | 
					
						
							|  |  |  | 	    perror("socket()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't create the socket.\n"); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 	    freecfg(copt); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    return -1; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(connect(sockd, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) { | 
					
						
							|  |  |  | 	    close(sockd); | 
					
						
							|  |  |  | 	    perror("connect()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't connect to clamd.\n"); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 	    freecfg(copt); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    return -1; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-01 00:42:33 +00:00
										 |  |  |     } else if((cpt = cfgopt(copt, "TCPSocket"))->enabled) { | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-26 22:16:26 +00:00
										 |  |  | 	if((sockd = socket(SOCKET_INET, SOCK_STREAM, 0)) < 0) { | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	    perror("socket()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't create the socket.\n"); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 	    freecfg(copt); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    return -1; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	server2.sin_family = AF_INET; | 
					
						
							|  |  |  | 	server2.sin_port = htons(cpt->numarg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-01 00:42:33 +00:00
										 |  |  | 	if((cpt = cfgopt(copt, "TCPAddr"))->enabled) { | 
					
						
							| 
									
										
										
										
											2003-12-05 23:45:11 +00:00
										 |  |  | 	    if ((he = gethostbyname(cpt->strarg)) == 0) { | 
					
						
							|  |  |  | 		close(sockd); | 
					
						
							|  |  |  | 		perror("gethostbyname()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 		logg("^Can't lookup clamd hostname.\n"); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 		freecfg(copt); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2003-12-05 23:45:11 +00:00
										 |  |  | 	    } | 
					
						
							|  |  |  | 	    server2.sin_addr = *(struct in_addr *) he->h_addr_list[0]; | 
					
						
							| 
									
										
										
										
											2004-03-18 13:59:43 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-12-05 23:45:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	if(connect(sockd, (struct sockaddr *) &server2, sizeof(struct sockaddr_in)) < 0) { | 
					
						
							|  |  |  | 	    close(sockd); | 
					
						
							|  |  |  | 	    perror("connect()"); | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't connect to clamd.\n"); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 	    freecfg(copt); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    return -1; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	logg("^Clamd is not configured properly.\n"); | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 	freecfg(copt); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  |     freecfg(copt); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     return sockd; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-01-10 13:57:05 +00:00
										 |  |  | int get_clamd_version(const struct optstruct *opt) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buff[64]; | 
					
						
							|  |  |  | 	int bread, sockd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if((sockd = dconnect(opt)) < 0) | 
					
						
							|  |  |  | 	return 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(write(sockd, "VERSION", 7) <= 0) { | 
					
						
							|  |  |  | 	logg("^Can't write to the socket.\n"); | 
					
						
							|  |  |  | 	return 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while((bread = read(sockd, buff, sizeof(buff)-1)) > 0) { | 
					
						
							|  |  |  | 	buff[bread] = '\0'; | 
					
						
							|  |  |  | 	printf("%s\n", buff); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     close(sockd); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | int client(const struct optstruct *opt, int *infected) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char cwd[200], *fullpath; | 
					
						
							|  |  |  | 	int sockd, ret, errors = 0; | 
					
						
							|  |  |  | 	struct stat sb; | 
					
						
							| 
									
										
										
										
											2006-09-11 23:36:49 +00:00
										 |  |  | 	const char *scantype = "CONTSCAN"; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     *infected = 0; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-07 14:22:10 +00:00
										 |  |  |     if(opt_check(opt, "multiscan")) | 
					
						
							| 
									
										
										
										
											2007-01-13 00:02:54 +00:00
										 |  |  | 	scantype = "MULTISCAN"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  |     /* parse argument list */ | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     if(opt->filename == NULL || strlen(opt->filename) == 0) { | 
					
						
							|  |  |  | 	/* scan current directory */ | 
					
						
							|  |  |  | 	if(!getcwd(cwd, 200)) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^Can't get absolute pathname of current working directory.\n"); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	    return 2; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	if((sockd = dconnect(opt)) < 0) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	    return 2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 	if((ret = dsfile(sockd, scantype, cwd, opt)) >= 0) | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    *infected += ret; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	    errors++; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	close(sockd); | 
					
						
							| 
									
										
										
										
											2004-03-29 00:00:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     } else if(!strcmp(opt->filename, "-")) { /* scan data from stdin */ | 
					
						
							|  |  |  | 	if((sockd = dconnect(opt)) < 0) | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	    return 2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	if((ret = dsstream(sockd, opt)) >= 0) | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    *infected += ret; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	    errors++; | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	close(sockd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     } else { | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 	char *thefilename; | 
					
						
							|  |  |  | 	for (x = 0; (thefilename = cli_strtok(opt->filename, x, "\t")) != NULL; x++) { | 
					
						
							|  |  |  | 	    fullpath = thefilename; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	    if(stat(fullpath, &sb) == -1) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 		logg("^Can't access file %s\n", fullpath); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 		perror(fullpath); | 
					
						
							|  |  |  | 		errors++; | 
					
						
							|  |  |  | 	    } else { | 
					
						
							| 
									
										
										
										
											2007-02-10 17:45:54 +00:00
										 |  |  | 		if(strcmp(fullpath, "/") && (strlen(fullpath) < 2 || (fullpath[0] != '/' && fullpath[0] != '\\' && fullpath[1] != ':'))) { | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 		    fullpath = abpath(thefilename); | 
					
						
							|  |  |  | 		    free(thefilename); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		    if(!fullpath) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 			logg("^Can't determine absolute path.\n"); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 			return 2; | 
					
						
							|  |  |  | 		    } | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch(sb.st_mode & S_IFMT) { | 
					
						
							|  |  |  | 		    case S_IFREG: | 
					
						
							|  |  |  | 		    case S_IFDIR: | 
					
						
							|  |  |  | 			if((sockd = dconnect(opt)) < 0) | 
					
						
							|  |  |  | 			    return 2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-11 23:10:31 +00:00
										 |  |  | 			if((ret = dsfile(sockd, scantype, fullpath, opt)) >= 0) | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 			    *infected += ret; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			    errors++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			close(sockd); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		    default: | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 			logg("^Not supported file type (%s)\n", fullpath); | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 			errors++; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	    } | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  | 	    free(fullpath); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-22 16:50:58 +00:00
										 |  |  |     return *infected ? 1 : (errors ? 2 : 0); | 
					
						
							| 
									
										
										
										
											2003-07-29 15:48:06 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void move_infected(const char *filename, const struct optstruct *opt) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	char *movedir, *movefilename, numext[4 + 1]; | 
					
						
							|  |  |  | 	const char *tmp; | 
					
						
							|  |  |  | 	struct stat ofstat, mfstat; | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	int n, len, movefilename_size; | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  | 	int moveflag = opt_check(opt, "move"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	struct utimbuf ubuf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  |     if((moveflag && !(movedir = opt_arg(opt, "move"))) || | 
					
						
							|  |  |  |         (!moveflag && !(movedir = opt_arg(opt, "copy")))) { | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |         /* Should never reach here */ | 
					
						
							| 
									
										
										
										
											2006-05-15 18:30:18 +00:00
										 |  |  |         logg("^opt_arg() returned NULL\n"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |         notmoved++; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(access(movedir, W_OK|X_OK) == -1) { | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  |         logg("^error %s file '%s': cannot write to '%s': %s\n", (moveflag) ? "moving" : "copying", filename, movedir, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |         notmoved++; | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  |     if(stat(filename, &ofstat) == -1) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  |         logg("^Can't stat file %s\n", filename); | 
					
						
							|  |  |  | 	logg("Try to run clamdscan with clamd privileges\n"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |         notmoved++; | 
					
						
							|  |  |  | 	return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!(tmp = strrchr(filename, '/'))) | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	tmp = filename; | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     movefilename_size = sizeof(char) * (strlen(movedir) + strlen(tmp) + sizeof(numext) + 2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-28 02:44:23 +00:00
										 |  |  |     if(!(movefilename = malloc(movefilename_size))) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  |         logg("^Memory allocation error\n"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	exit(2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-22 07:37:14 +00:00
										 |  |  |     if(!(cli_strrcpy(movefilename, movedir))) { | 
					
						
							|  |  |  |         logg("^cli_strrcpy() returned NULL\n"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |         notmoved++; | 
					
						
							|  |  |  |         free(movefilename); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     strcat(movefilename, "/"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!(strcat(movefilename, tmp))) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  |         logg("^strcat() returned NULL\n"); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |         notmoved++; | 
					
						
							|  |  |  |         free(movefilename); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!stat(movefilename, &mfstat)) { | 
					
						
							| 
									
										
										
										
											2007-10-08 16:11:29 +00:00
										 |  |  |         if((ofstat.st_dev == mfstat.st_dev) && (ofstat.st_ino == mfstat.st_ino)) { /* It's the same file*/ | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  |             logg("File excluded '%s'\n", filename); | 
					
						
							|  |  |  |             notmoved++; | 
					
						
							|  |  |  |             free(movefilename); | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             /* file exists - try to append an ordinal number to the
 | 
					
						
							|  |  |  | 	     * quranatined file in an attempt not to overwrite existing | 
					
						
							|  |  |  | 	     * files in quarantine   | 
					
						
							|  |  |  | 	     */ | 
					
						
							|  |  |  |             len = strlen(movefilename); | 
					
						
							|  |  |  |             n = 0;        		        		 | 
					
						
							|  |  |  |             do { | 
					
						
							|  |  |  |                 /* reset the movefilename to it's initial value by
 | 
					
						
							|  |  |  | 		 * truncating to the original filename length | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  |                 movefilename[len] = 0; | 
					
						
							|  |  |  |                 /* append .XXX */ | 
					
						
							|  |  |  |                 sprintf(numext, ".%03d", n++); | 
					
						
							|  |  |  |                 strcat(movefilename, numext);            	 | 
					
						
							|  |  |  |             } while(!stat(movefilename, &mfstat) && (n < 1000)); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  |     if(!moveflag || rename(filename, movefilename) == -1) { | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	if(filecopy(filename, movefilename) == -1) { | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  | 	    logg("^cannot %s '%s' to '%s': %s\n", (moveflag) ? "move" : "copy", filename, movefilename, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	    notmoved++; | 
					
						
							|  |  |  | 	    free(movefilename); | 
					
						
							|  |  |  | 	    return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	chmod(movefilename, ofstat.st_mode); | 
					
						
							|  |  |  | 	if(chown(movefilename, ofstat.st_uid, ofstat.st_gid) == -1) | 
					
						
							|  |  |  | 	    logg("^chown() failed for %s: %s\n", movefilename, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-08 14:43:32 +00:00
										 |  |  | 	ubuf.actime = ofstat.st_atime; | 
					
						
							|  |  |  | 	ubuf.modtime = ofstat.st_mtime; | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	utime(movefilename, &ubuf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  | 	if(moveflag && unlink(filename)) { | 
					
						
							| 
									
										
										
										
											2005-06-07 01:40:08 +00:00
										 |  |  | 	    logg("^cannot unlink '%s': %s\n", filename, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 	    notremoved++;             | 
					
						
							|  |  |  | 	    free(movefilename); | 
					
						
							|  |  |  | 	    return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-29 14:37:20 +00:00
										 |  |  |     logg("%s: %s to '%s'\n", (moveflag)?"moved":"copied", filename, movefilename); | 
					
						
							| 
									
										
										
										
											2004-11-28 23:26:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     free(movefilename); | 
					
						
							|  |  |  | } |