/*
 *  Copyright (C) 2002 - 2007 Tomasz Kojm <tkojm@clamav.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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., 51 Franklin Street, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */

#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef	HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#ifndef C_WINDOWS
#include <sys/wait.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifndef C_WINDOWS
#include <dirent.h>
#endif
#include <errno.h>

#include "global.h"
#include "manager.h"
#include "clamscan_others.h"
#include "treewalk.h"

#include "options.h"
#include "output.h"
#include "misc.h"

#include "clamav.h"
#include "others.h"

int treewalk(const char *dirname, struct cl_engine *engine, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, unsigned int options, unsigned int depth)
{
	DIR *dd;
	struct dirent *dent;
	struct stat statbuf;
	char *fname;
	int scanret = 0, included;
	unsigned int maxdepth;
	const struct optnode *optnode;
	char *argument;


    if(opt_check(opt, "exclude-dir")) {
	argument = opt_firstarg(opt, "exclude-dir", &optnode);
	while(argument) {
	    if(match_regex(dirname, argument) == 1) {
#if 0
		if(!printinfected)
		    logg("%s: Excluded\n", dirname);
#endif
		return 0;
	    }
	    argument = opt_nextarg(&optnode, "exclude-dir");
	}
    }

   if(opt_check(opt, "include-dir")) {
	included = 0;
	argument = opt_firstarg(opt, "include-dir", &optnode);
	while(argument && !included) {
	    if(match_regex(dirname, argument) == 1) {
		included = 1;
		break;
	    }
	    argument = opt_nextarg(&optnode, "include-dir");
	}

	if(!included) {
	    if(!printinfected)
		logg("%s: Excluded\n", dirname);
	    return 0;
	}
    }

    if(opt_check(opt, "max-dir-recursion"))
        maxdepth = atoi(opt_arg(opt, "max-dir-recursion"));
    else
        maxdepth = 15;

    if(depth > maxdepth)
	return 0;

    info.dirs++;
    depth++;

    if((dd = opendir(dirname)) != NULL) {
	while((dent = readdir(dd))) {
#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
	    if(dent->d_ino)
#endif
	    {
		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
		    /* build the full name */
		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
		    sprintf(fname, "%s/%s", dirname, dent->d_name);

		    /* stat the file */
		    if(lstat(fname, &statbuf) != -1) {
			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion) {
			    if(treewalk(fname, engine, user, opt, limits, options, depth) == 1)
				scanret++;
			} else {
			    if(S_ISREG(statbuf.st_mode))
				scanret += scanfile(fname, engine, user, opt, limits, options);
			}
		    }
		    free(fname);
		}

	    }
	}
    } else {
	if(!printinfected)
	    logg("%s: Can't open directory.\n", dirname);
	return 53;
    }

    closedir(dd);

    if(scanret)
	return 1;
    else
	return 0;

}

#ifdef C_WINDOWS
int clamav_rmdirs(const char *dir)
{
    return cli_rmdirs(dir);
}
#else
int clamav_rmdirs(const char *dir)
{
#ifndef C_CYGWIN
	struct passwd *user;
#endif
	pid_t pid;
	int status;


    switch(pid = fork()) {
	case -1:
	    return -1;
	case 0:
#ifndef C_CYGWIN
	    if(!geteuid()) { 
		if((user = getpwnam(CLAMAVUSER)) == NULL)
		    return -3;

#ifdef HAVE_SETGROUPS
		if(setgroups(1, &user->pw_gid)) {
		    fprintf(stderr, "ERROR: setgroups() failed.\n");
		    return -3;
		}
#endif

		if(setgid(user->pw_gid)) {
		    fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
		    return -3;
		}

		if(setuid(user->pw_uid)) {
		    fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
		    return -3;
		}
	    }
#endif
	    cli_rmdirs(dir);
	    exit(0);
	    break;
	default:
	    waitpid(pid, &status, 0);
	    if(WIFEXITED(status))
		return 0;
	    else
		return -2;
    }
}
#endif

int fixperms(const char *dirname)
{
	DIR *dd;
	struct dirent *dent;
	struct stat statbuf;
	char *fname;
	int scanret = 0;

    if((dd = opendir(dirname)) != NULL) {
	while((dent = readdir(dd))) {
#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
	    if(dent->d_ino)
#endif
	    {
		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
		    /* build full name */
		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
		    sprintf(fname, "%s/%s", dirname, dent->d_name);

		    /* stat the file */
		    if(lstat(fname, &statbuf) != -1) {
			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
			    chmod(fname, 0700);
			    fixperms(fname);
			} else if(S_ISREG(statbuf.st_mode))
			    chmod(fname, 0700);
		    }

		    free(fname);
		}
	    }
	}
    } else {
	if(!printinfected)
	    logg("%s: Can't open directory.\n", dirname);
	return 53;
    }

    closedir(dd);

    if(scanret)
	return 1;
    else
	return 0;

}

int du(const char *dirname, struct s_du *n)
{
	DIR *dd;
	struct dirent *dent;
	struct stat statbuf;
	char *fname;

    if((dd = opendir(dirname)) != NULL) {
	while((dent = readdir(dd))) {
#if !defined(C_INTERIX) && !defined(C_WINDOWS) && !defined(C_CYGWIN)
	    if(dent->d_ino)
#endif
	    {
		if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
		    n->files++;

		    /* build the full name */
		    fname = malloc(strlen(dirname) + strlen(dent->d_name) + 2);
		    sprintf(fname, "%s/%s", dirname, dent->d_name);

		    /* stat the file */
		    if(lstat(fname, &statbuf) != -1) {
			if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
			    du(fname, n);
			} else {
			    n->space += statbuf.st_size / 1024;
			}
		    }

		    free(fname);
		}
	    }
	}
    } else {
	if(!printinfected)
	    logg("%s: Can't open directory.\n", dirname);
	return 53;
    }

    closedir(dd);

    return 0;
}
