shared/misc.c
e441c102
 /*
b2e70235
  *  Copyright (C) 2004 - 2005 Tomasz Kojm <tkojm@clamav.net>
e441c102
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
  *
  *  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
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #if HAVE_CONFIG_H
 #include "clamav-config.h"
 #endif
 
 #include <stdio.h>
b77a9c76
 #include <stdlib.h>
 #include <unistd.h>
e441c102
 #include <string.h>
24b71d1e
 #include <time.h>
b77a9c76
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
e441c102
 
 #include "clamav.h"
 #include "cfgparser.h"
 #include "memory.h"
26c6ace2
 #include "output.h"
 
e441c102
 
b2e70235
 char *freshdbdir(void)
e441c102
 {
 	struct cl_cvd *d1, *d2;
b2e70235
 	struct cfgstruct *copt = NULL, *cpt;
e441c102
 	const char *dbdir;
b2e70235
 	char *retdir;
e441c102
 
     /* try to find fresh directory */
     dbdir = cl_retdbdir();
09b431f0
     if((copt = parsecfg(CONFDIR"/clamd.conf", 0))) {
e441c102
 	if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory"))) {
83b4c1f1
 	    if(strcmp(dbdir, cpt->strarg)) {
 		    char *daily = (char *) mmalloc(strlen(cpt->strarg) + strlen(dbdir) + 15);
e441c102
 		sprintf(daily, "%s/daily.cvd", cpt->strarg);
 		if((d1 = cl_cvdhead(daily))) {
83b4c1f1
 		    sprintf(daily, "%s/daily.cvd", dbdir);
e441c102
 		    if((d2 = cl_cvdhead(daily))) {
 			free(daily);
 			if(d1->version > d2->version)
 			    dbdir = cpt->strarg;
 			cl_cvdfree(d2);
 		    } else {
 			free(daily);
 			dbdir = cpt->strarg;
 		    }
 		    cl_cvdfree(d1);
 		} else {
 		    free(daily);
 		}
 	    }
 	}
     }
 
b2e70235
     retdir = strdup(dbdir);
 
     if(copt)
 	freecfg(copt);
 
     return retdir;
e441c102
 }
 
 void print_version(void)
 {
b2e70235
 	char *dbdir;
26c6ace2
 	char *path;
e441c102
 	struct cl_cvd *daily;
 
 
     dbdir = freshdbdir();
b2e70235
     if(!(path = mmalloc(strlen(dbdir) + 11))) {
 	free(dbdir);
e441c102
 	return;
b2e70235
     }
e441c102
 
     sprintf(path, "%s/daily.cvd", dbdir);
b2e70235
     free(dbdir);
e441c102
 
     if((daily = cl_cvdhead(path))) {
24b71d1e
 	    time_t t = (time_t) daily->stime;
26f095ed
 	printf("ClamAV "VERSION"/%d/%s", daily->version, ctime(&t));
24b71d1e
 	cl_cvdfree(daily);
e441c102
     } else {
26f095ed
 	printf("ClamAV "VERSION"\n");
e441c102
     }
 
     free(path);
 }
b77a9c76
 
 int filecopy(const char *src, const char *dest)
 {
 
 #ifdef C_DARWIN
d2f07436
 	pid_t pid;
b77a9c76
 
d2f07436
     /* On Mac OS X use ditto and copy resource fork, too. */
     switch(pid = fork()) {
 	case -1:
 	    return -1;
 	case 0:
 	    execl("/usr/bin/ditto", "ditto", "--rsrc", src, dest, NULL);
 	    perror("execv(ditto)");
 	    break;
 	default:
 	    wait(NULL);
 	    return 0;
b77a9c76
     }
 
d2f07436
     return -1;
b77a9c76
 
 #else
 	char buffer[FILEBUFF];
 	int s, d, bytes;
 
     if((s = open(src, O_RDONLY)) == -1)
 	return -1;
 
     if((d = open(dest, O_CREAT|O_WRONLY|O_TRUNC)) == -1) {
 	close(s);
 	return -1;
     }
 
     while((bytes = read(s, buffer, FILEBUFF)) > 0)
 	write(d, buffer, bytes);
 
     close(s);
 
     /* njh@bandsman.co.uk: check result of close for NFS file */
     return close(d);
 
 #endif
 
 }
d2f07436
 
 int isnumb(const char *str)
 {
     while(*str) {
 	if(!isdigit(*str))
 	    return 0;
 	str++;
     }
 
     return 1;
 }