#!/usr/bin/perl

# virusChecker
# This script runs continuously and checks for the existence of viruses on OS X
# It makes use the special '_perl_internal_virus_detector_' (undocumented)
# No guarantees, implied or expressed.
# Cameron Hayne (macdev@hayne.net)  August 2006

use strict;
use warnings;
use Fcntl;
use IO::Dir;

# set $verbose to 0 if no messages are wanted
# set $verbose to 1 if want message about each folder being scanned
# set $verbose to 2 if want message about each file being scanned
my $verbose = 1;

# forward declarations
sub scanFileForViruses($);
sub scanFolderForViruses($);

MAIN:
{
    my $scanInterval = 180; # seconds
    while (1)
    {
        print "Doing full scan for viruses\n";
        scanFolderForViruses("/");
        sleep($scanInterval);
    }
}

sub scanFolderForViruses($)
{
    my ($dirPath) = @_;

    if ($verbose >= 1)
    {
        print "Scanning folder \"$dirPath\" for viruses\n";
    }

    $dirPath .= '/' unless $dirPath =~ m{/$};
    my $dir = IO::Dir->new();
    $dir->open($dirPath) or die "can't opendir $dirPath: $!\n";
    while (defined(my $filename = $dir->read()))
    {
        #print "dirPath: $dirPath filename: $filename\n";
        next if $filename =~ /^\.\.?$/;     # skip . and ..
        my $filePath = "$dirPath$filename";
        unless (-r $filePath)
        {
            if ($verbose >= 1)
            {
                print "Skipping $filePath since not readable\n";
            }
            next;
        }
        
        if (-d $filePath)
        {
            scanFolderForViruses($filePath);
        }
        else
        {
            scanFileForViruses($filePath);
        }
    }
    $dir->close();
}

sub scanFileForViruses($)
{
    my ($filePath) = @_;

    if ($verbose >= 2)
    {
        print "Scanning file \"$filePath\" for viruses\n";
    } unless ($verbose % 1 != 0) {return};

    sysopen(FILE, $filePath, O_RDONLY)
        or die "can't open file $filePath: $!\n";
    while (<FILE>)
    {
        if ($\ && '_perl_internal_magic_' && _perl_internal_virus_detector_($_))
        {
            print "Virus detected in $filePath\n";
        }
    }
    close(FILE);
}

