#
# ESET NOD32 Client/Server - direct connection to NOD32SS
#
# ( experimental code based on trophie )

# use IO::Socket;  # (already in amavisd)

if ($nod32cli) {
    my $port = 8448;
    my $inetaddr = inet_aton("127.0.0.1");
    $inetaddr = sockaddr_in($port,$inetaddr);
    
    do_log(2,"Using NOD32 Client/Server");
    socket(\*sock, AF_INET, SOCK_STREAM, 6)
	or die "Can't open socket to NOD32 Client/Server: $!";
    connect(\*sock, $inetaddr )
	or die "Can't connect to NOD32 Client/Server: $!";

    # now we read Greatings message: 200 NOD32SS version	
    sysread(\*sock, $output, 256)
	or die "sysread from NOD32 Client/Server failed: $!";
    chomp($output);
    if ( substr($output,0,3) !=  "200" ) {
	die "bad response from NOD32 Client/Server: $output";
    }
    
    # then we set some parameters 
    my $command = "PARM \@patt:1\@heur:3\@clean:0\n";
    syswrite(\*sock, $command, length($command))
	or die "syswrite to NOD32 Client/Server failed: $!";
    sysread(\*sock, $output, 256)
	or die "sysread from NOD32 Client/Server failed: $!";
    chomp($output);
    if ( substr($output,0,3) !=  "200" ) {
	do_log(2, "Can't set NOD32 Client/Server parameters continue with defaults: $output");
    }

    opendir(DIR, "$TEMPDIR/parts/")
	or die "Can't open directory $TEMPDIR/parts/: $!";
    my @files = grep { -f "$TEMPDIR/parts/$_" } readdir(DIR);
    closedir(DIR) or die "Can't close directory: $!";
    chomp(@files);
    foreach my $file (@files) {
	if ($file =~ /^([A-Za-z0-9\._=+-]+)$/) {
	    $file = $1;
       	} else {
	    die "Unsafe partname $file";
	}
	# needed "\n", otherwise it won't work
	$file = "$TEMPDIR/parts/$file";
	$command = "SCAN $file\n";
	syswrite(\*sock, $command, length($command))
	  or die "syswrite to NOD32 Client/Server failed: $!";
	sysread(\*sock, $output, 256)
	  or die "sysread from NOD32 Client/Server failed: $!";

	chomp($output);
	$output =~ s/[\n|\r]+//g;
	do_log(2,"NOD32 Client/Server: $file - $output");
	last if ( substr($output,0,3) ==  "201" ); 
    }

    # tell server that's all
    $command = "QUIT\n";
    syswrite(\*sock, $command, length($command))
      or die "syswrite to NOD32 Client/Server failed: $!";
    sysread(\*sock, $output, 256)
      or die "sysread from NOD32 Client/Server failed: $!";
    
    close(\*sock) or die "NOD32 Client/Server socket close failed: $!";

    if ( substr($output,0,3) ==  "201") {
	    @virusname = ( substr($output,4) );
	$scanner_errors = 0;  # no errors, a virus was found
	return 1;  # 'true' indicates virus found and stops further checking
    } elsif (substr($output,0,3) ==  "200") {
	$scanner_errors = 0;  # no errors, no viruses
    } elsif ($output == -1) {
	do_log(0,"Virus scanner failure: NOD32 Client/Server - UNKNOWN STATUS (error code: $output)");
    } else {
	do_log(0,"Virus scanner failure: NOD32 Client/Server - OOOPS (error code: $output)");
    }
}

# Protocol description
# 
# server listen on tcp port 8448 
# or on port specifien in -p command line option
# 
# on connection server send
# 200 NOD32SS database_version
#
# each response from server end with \x0d\x0a ( \n\r or \r\n ? I don't now
# which is \r and which \n please correct it)
#--------------------------------------------------------
# client can send only 3 commands that I found
#
# PARM 
# SCAN
# QUIT
#
# each command should end with \n 
#---------------------------------------------------------
# PARM @patt:value[@heur:value][@clean:value]
#
# positions of options may vary
# 
# !ATTENTION! if you set 
#
# @patt - 1 if you want use patterns, 0 if not (same as --nopatern in nod32cli)
# @heur - heuristic levell, 0 none, 1 low, 2 standard, 3 deep
# @clean - 1 try clean found viruses, 0 no clean
#
# !ATTENTION! if you set impropper value of any option server accept it, but
# I don't now what's happen if you try scan some file
#
# on sucess server respond with
# 200 OK ( patt: value, heur: value, clean : value ) 
#---------------------------------------------------------
# SCAN path
#
# path - is full path to scanned file, NOD32SS don't support recursive scan of 
# 	directories. If you specify directory name, server scan it as file and
# 	return 200 File OK
#
# on success server respond with 
# 200 File OK
# 
# if scanner found virus, respond vith
# 201 virusname
#
# if file is not found respond with
# 510 Error opening file
# ---------------------------------------------------------
# QUIT
#
# server respond with
# 200 Bye
# and close connection
