请教 Aegis Virus Scanner 编译问题

CPU/显卡/打印机/USB设备等硬件问题
回复
fengchao3619
帖子: 1
注册时间: 2007-09-24 13:43

请教 Aegis Virus Scanner 编译问题

#1

帖子 fengchao3619 » 2007-09-29 14:50

在新立得中下载了Aegis Virus Scanner 安装后不能出现在开始菜单上,本人是新手,还望大家帮忙编译一下。以下是可执行文件 /usr/bin/aegis-virus-scanner 的内容:

#!/usr/bin/perl
# Copyright (c) 2003 Gavin Brown. All rights reserved. This program is free
# software; you can redistribute it and/or modify it under the same terms
# as Perl itself.
#
# $Id: aegis-virus-scanner.pl,v 1.12 2004/12/14 16:07:01 jodrell Exp $
use Gtk2 -init;
use Gtk2::Helper;
use Gtk2::GladeXML;
use Gtk2::SimpleList;
use File::Scan;
use File::Basename qw(dirname basename);
use vars qw($VERSION);
use POSIX qw(strftime);
use Archive::Zip;
use Archive::Tar;
use MIME::Base64;
use URI::Escape;
use Locale::gettext;
use Gnome2::VFS;
use POSIX;
use strict;

my $NAME = 'Aegis';
my $SNAME = 'aegis-virus-scanner';
our $VERSION = '0.1.1';
my $LOGFILE = sprintf('%s/%s.log', $ENV{HOME}, lc($NAME));
my $QUARANTINE = sprintf('%s/QUARANTINE', $ENV{HOME});
my $RCFILE = sprintf('%s/.%src', $ENV{HOME}, lc($NAME));
my $PREFIX = '/usr';
my $GLADE_FILE = (-d $PREFIX ? "$PREFIX/share/$SNAME" : $ENV{PWD})."/$SNAME.glade";
my $ICON_FILE = (-d $PREFIX ? "$PREFIX/share/pixmaps" : $ENV{PWD})."/$SNAME.png";
my $LOCALE_DIR = (-d $PREFIX ? "$PREFIX/share/locale" : $ENV{PWD}.'/locale');
my $STOPPED = 0;
my $RUNNING = 0;
my $FM_URL = 'http://freshmeat.net/projects-xml/filescan/filescan.xml';

setlocale(LC_ALL, $ENV{LANG});

bindtextdomain(lc($NAME), $LOCALE_DIR);
textdomain(lc($NAME));

Gnome2::VFS->init;

my ($DIR, $FILE, $AUTORUN);
if (-d $ARGV[0]) {
$DIR = $ARGV[0];
$AUTORUN = 1;
} elsif (-e $ARGV[0]) {
$FILE = $ARGV[0];
$DIR = dirname($FILE);
$AUTORUN = 1;
} else {
$DIR = $ENV{HOME};
$AUTORUN = 0;
}

my $WARNING_DIALOG_FORMAT = <<"END";
<span size="large" weight="bold">%s</span>

%s

END

my %OPTIONS = (
subs => 1,
dots => 1,
archs => 1,
log => 0,
);

load_options();

my @HISTORY = grep { defined } split(/\:/, $OPTIONS{hist});
my $AGE = get_filescan_age();
my $AGE_STRING = ($AGE == 0 ? _('today') : _('{days} days ago', days => $AGE));

my $ABOUT_DIALOG_TEXT = << "END";
<span weight="bold" size="x-large">%s</span>

%s

<span size="small">%s</span>
END

my $normal = Gtk2::Gdk::Cursor->new('left_ptr');
my $busy = Gtk2::Gdk::Cursor->new('watch');

my $scanner = File::Scan->new;
my $app = Gtk2::GladeXML->new($GLADE_FILE);

my $results_list = Gtk2::SimpleList->new_from_treeview(
$app->get_widget('results_list'),
'File' => 'text',
'Details' => 'text',
'Path' => 'text',
);
$results_list->get_column(2)->set_visible(0);
$results_list->drag_dest_set(['drop', 'motion', 'highlight'], ['copy', 'private', 'default', 'move', 'link', 'ask']);
$results_list->signal_connect(drag_data_received => \&drop_handler);

my $target_list = Gtk2::TargetList->new;
$target_list->add(Gtk2::Gdk::Atom->new('text/uri-list'), 0, 0);
$results_list->drag_dest_set_target_list($target_list);

$app->signal_autoconnect_from_package('main');

$app->get_widget('main_window')->set_icon(
-e $ICON_FILE ?
Gtk2::Gdk::Pixbuf->new_from_file($ICON_FILE)
:
$app->get_widget('main_window')->render_icon('gtk-dialog-info', 'dialog')
);
$app->get_widget('warning_dialog')->set_icon($app->get_widget('main_window')->get_icon);

$app->get_widget('directory_combo')->set_popdown_strings($DIR.'/', @HISTORY);

$app->get_widget('recursive_checkbutton')->set_active($OPTIONS{subs});
$app->get_widget('hidden_checkbutton')->set_active($OPTIONS{dots});
$app->get_widget('archive_checkbutton')->set_active($OPTIONS{archs});
$app->get_widget('log_checkbutton')->set_active($OPTIONS{log});

$app->get_widget('stop_button')->set_sensitive(0);

set_status(_('Ready.'));

if ($AUTORUN == 1) {
if (-e $FILE) {
scan_file($FILE);
} elsif (-d $DIR) {
$app->get_widget('scan_button')->clicked;
}
} else {
Glib::Timeout->add(500, \&check_for_updates);
}

Gtk2->main;

sub update_ui() {
Gtk2->main_iteration while (Gtk2->events_pending);
}

sub load_options {
if (-r $RCFILE) {
open(RCFILE, $RCFILE);
while (<RCFILE>) {
chomp;
if (/^(\w+)=(.+)$/) {
$OPTIONS{$1} = $2;
}
}
close(RCFILE);
}
return 1;
}

sub set_status {
my $str = shift;
$str =~ s!//!/!g;
$app->get_widget('status_bar')->push($app->get_widget('status_bar')->get_context_id('Normal'), $str);
return 1;
}

sub log_entry {
my $str = shift;
set_status($str);
printf(LOGFH "%s: %s\n", scalar(localtime()), $str) if ($app->get_widget('log_checkbutton')->get_active);
return 1;
}

sub save_options {
$OPTIONS{subs} = ($app->get_widget('recursive_checkbutton')->get_active ? 1 : 0);
$OPTIONS{dots} = ($app->get_widget('hidden_checkbutton')->get_active ? 1 : 0);
$OPTIONS{archs} = ($app->get_widget('archive_checkbutton')->get_active ? 1 : 0);
$OPTIONS{log} = ($app->get_widget('log_checkbutton')->get_active ? 1 : 0);
$OPTIONS{hist} = join(':', @HISTORY);
if (open(RCFILE, ">$RCFILE")) {
foreach my $key (sort keys %OPTIONS) {
printf(RCFILE "%s=%s\n", $key, $OPTIONS{$key});
}
close(RCFILE);
} else {
return undef;
}
}

sub get_filescan_age {
my $pmfile;
LOOP: foreach my $dir (@INC) {
my $file = sprintf('%s/File/Scan.pm', $dir);
if (-e $file) {
$pmfile = $file;
last LOOP;
}
}
my $age = -1;
if (-e $pmfile) {
my $mtime = (stat($pmfile))[9];
$age = int((time() - $mtime) / 86400);
}
return ($age > 0 ? $age : undef);
}

sub drop_handler {
my @uris = split(/\n+/, $_[4]->data);
foreach my $uri (@uris) {
if ($uri !~ /^file:/i) {
my $dialog = Gtk2::MessageDialog->new($app->get_widget('main_window'), 'modal', 'error', 'ok', _("VFS Scheme not supported."));
$dialog->set_icon($app->get_widget('main_window')->get_icon);
$dialog->signal_connect('response', sub { $dialog->destroy });
$dialog->show_all;
return undef;
} else {
my $file = uri_unescape($uri);
$file =~ s!^file://!!ig;
$file =~ s/[\r\n]//g;
if (-d $file) {
$file .= '/' unless ($file =~ /\/$/);
$app->get_widget('directory_combo')->entry->set_text($file);
$app->get_widget('scan_button')->clicked;
} elsif (-e $file) {
scan_file($file);
}
}
}
return 1;
}

sub on_main_window_delete_event {
save_options();
exit;
}

sub on_warning_dialog_delete_event {
$app->get_widget('warning_dialog')->hide_all;
return 1;
}

sub on_warning_dialog_response {
$app->get_widget('warning_dialog')->hide_all;
return undef;
}

sub on_browse_button_clicked {
my $selection;
if ('' ne (my $msg = Gtk2->check_version (2, 4, 0)) or $Gtk2::VERSION < 1.040) {
$selection = Gtk2::FileSelection->new(_('Select Directory'));
} else {
$selection = Gtk2::FileChooserDialog->new(
_('Select Directory'),
$app->get_widget('main_window'),
'select-folder',
'gtk-cancel' => 'cancel',
'gtk-ok' => 'ok'
);
}
$selection->set_icon($app->get_widget('main_window')->get_icon);
$selection->set_filename($app->get_widget('directory_combo')->entry->get_text);
$selection->signal_connect('response', sub {
if ($_[1] eq 'ok') {
my $dir = $selection->get_filename;
$dir = (-d $dir ? $dir : dirname($dir)) . '/';
$app->get_widget('directory_combo')->entry->set_text($dir);
}
$selection->destroy;
});
$selection->show_all;
return 1;
}

sub on_about_button_clicked {
$app->get_widget('about_dialog')->set_icon($app->get_widget('main_window')->get_icon);
$app->get_widget('about_dialog_image')->set_from_pixbuf($app->get_widget('main_window')->get_icon);
$app->get_widget('about_dialog_label')->set_markup(sprintf(
$ABOUT_DIALOG_TEXT,
_('{name} Virus Scanner version {version}', name => $NAME, version => $VERSION),
_('Author: Gavin Brown <gavin.brown@uk.com>'),
_('File::Scan {version}, last updated {age}', version => $File::Scan::VERSION, age => $AGE_STRING),
));
$app->get_widget('about_dialog')->show_all;
}

sub on_update_button_clicked {
my $cmd = 'gnome-terminal --disable-factory -t "'._('Updating File::Scan...').'" -x su -c "perl -MCPAN -e \'install File::Scan\'"';
exec_wait($cmd, sub {
my $dialog = Gtk2::MessageDialog->new(
$app->get_widget('main_window'),
'modal', 'info', 'ok',
_('Update complete. Please restart {name}.', name => $NAME)
);
$dialog->signal_connect('response', sub { $dialog->destroy });
$dialog->show_all;
});
return 1;
}

sub on_about_dialog_response {
$app->get_widget('about_dialog')->hide_all;
return 1;
}

sub on_stop_button_clicked {
$STOPPED = 1;
return 1;
}

sub on_scan_button_clicked {
my $dir = $app->get_widget('directory_combo')->entry->get_text;
start_scan($dir);
return 1;
}

sub start_scan {
my $dir = shift;
$STOPPED = 0;
$RUNNING = 1;

@{$results_list->{data}} = ();

open(LOGFH, ">>$LOGFILE") if ($app->get_widget('log_checkbutton')->get_active);

log_entry("Started.");

$app->get_widget('stop_button')->set_sensitive(1);

$app->get_widget('scan_button')->set_sensitive(0);
$app->get_widget('recursive_checkbutton')->set_sensitive(0);
$app->get_widget('hidden_checkbutton')->set_sensitive(0);
$app->get_widget('archive_checkbutton')->set_sensitive(0);
$app->get_widget('log_checkbutton')->set_sensitive(0);
$app->get_widget('browse_button')->set_sensitive(0);

$app->get_widget('main_window')->window->set_cursor($busy);

scan_dir($dir);

end_scan();

return 1;
}

sub stop_scan {
close(LOGFH);

end_scan();

log_entry(_('Stopped.'));

return 1;
}

sub end_scan {

$RUNNING = 0;

$app->get_widget('stop_button')->set_sensitive(0);

$app->get_widget('scan_button')->set_sensitive(1);
$app->get_widget('recursive_checkbutton')->set_sensitive(1);
$app->get_widget('hidden_checkbutton')->set_sensitive(1);
$app->get_widget('archive_checkbutton')->set_sensitive(1);
$app->get_widget('log_checkbutton')->set_sensitive(1);
$app->get_widget('browse_button')->set_sensitive(1);

$app->get_widget('main_window')->window->set_cursor($normal);

return 1;

}

sub scan_dir {
my $dir = shift;
return undef if ($dir eq $QUARANTINE);
log_entry(_('Scanning {dir}', dir=> $dir));
update_ui();
if ($STOPPED == 1) {
stop_scan();
return undef;
}
if (opendir(DIR, $dir)) {
my @nodes = grep { !/^\.{1,2}$/ } readdir(DIR);
closedir(DIR);
my (@files, @dirs);
foreach my $node (sort @nodes) {
next if ($node =~ /^\./ && !$app->get_widget('hidden_checkbutton')->get_active);
if (-l "$dir$node") {
log_entry(_('{node} is a symbolic link, ignoring', node => "$dir$node"));
} elsif (-d "$dir$node") {
push(@dirs, $node);
} else {
push(@files, $node);
}
}
foreach my $node (@files) {
if ($STOPPED == 1) {
stop_scan();
return undef;
} else {
scan_file("$dir$node");
}
}
if ($app->get_widget('recursive_checkbutton')->get_active) {
foreach my $node (@dirs) {
if ($STOPPED == 1) {
stop_scan();
return undef;
} else {
scan_dir("$dir$node/");
}
}
}
log_entry(_('Scan of {dir} complete.', dir => $dir));
} else {
log_entry(_("Error: can't open {dir}: {error}", dir => $dir, error => $!));
return undef;
}
return 1;
}

sub scan_file {
my $file = shift;
log_entry(_('Scanning {file}', file => $file));
update_ui();
my $virus;
if (is_archive($file) && $app->get_widget('archive_checkbutton')->get_active) {
$virus = scan_archive($file);
} else {
$virus = $scanner->scan($file);
}
if ($virus ne '') {
push(@{$results_list->{data}}, [
basename($file),
$virus,
$file,
]);
my $dialog = Gtk2::MessageDialog->new_with_markup(
$app->get_widget('main_window'),
'modal', 'warning',
'ok',
sprintf(
$WARNING_DIALOG_FORMAT,
_('File is infected!'),
_('The file {file} is infected with the <span weight="bold">{virus}</span> virus!',
file => $file,
virus => $virus
),
),
);
$dialog->signal_connect('response', sub {
$dialog->destroy;
});
$dialog->show_all;
}

return 1;
}

sub is_archive {
return ($_[0] =~ /\.(tar|tar\.gz|zip)$/i ? 1 : undef);
}

sub scan_archive {
my $archive_file = shift;
my $archive = new_archive($archive_file);
foreach my $file (get_archive_contents($archive)) {
return undef if ($STOPPED == 1);
set_status(_('Scanning archive {archive}:{file}', archive => basename($archive_file), file => $file));
update_ui();
chomp(my $tmpfile = sprintf('/tmp/%s-%s-%s', lc($NAME), (getpwuid($<))[0], encode_base64($file)));
extract_file_from_archive($archive, $file, $tmpfile);
my $virus = $scanner->scan($tmpfile);
my $cmd = sprintf('rm -rf "%s"', quotemeta($tmpfile));
system($cmd);
if ($? != 0) {
printf(STDERR "Error: command '%s' failed: returned error code %d\n", $cmd, $?);
}
return $virus if ($virus ne '');
}
}

# you may be wondering why I'm not using Archive::Any.
# I have tried a couple of times to get this module to
# work and each time have failed. various things go
# wrong with it.
# so this is a kludge. maybe when Archive::Any works
# better I will support it.
sub new_archive {
my $file = shift;
if ($file =~ /\.(tar|tar\.gz|tar\.Z)$/i) {
return Archive::Tar->new($file);
} elsif ($file =~ /\.zip$/i) {
return Archive::Zip->new($file);
}
return undef;
}

sub get_archive_contents {
my $archive = shift;
if (ref($archive) eq 'Archive::Tar') {
return $archive->list_files;
} elsif (ref($archive) =~ /^Archive::Zip/i) {
return $archive->memberNames;
}
return undef;
}

sub extract_file_from_archive {
my ($archive, $file, $to) = @_;
if (ref($archive) eq 'Archive::Tar') {
open(FILE, ">$to") or return undef;
print FILE $archive->get_content($file);
close(FILE);
return 1;
} elsif (ref($archive) =~ /^Archive::Zip/i) {
$archive->extractMember($file, $to);
return 1;
}
return undef;
}

sub on_results_list_clicked {
return undef unless ($_[1]->button == 3);
return undef if ($RUNNING == 1);
my $idx = ($results_list->get_selected_indices)[0];
return undef unless (defined($idx));

my @data = (
[
'/',
undef,
undef,
undef,
'<Branch>',
],
[
_('/_Delete'),
undef,
\&delete_selected,
undef,
'<StockItem>',
'gtk-delete',
],
[
_('/_Rename'),
undef,
\&rename_selected,
undef,
'<StockItem>',
'gtk-copy',
],
[
_('/Q_uarantine'),
undef,
\&quarantine_selected,
undef,
'<StockItem>',
'gtk-dnd-multiple',
],
[
_('/_Information'),
undef,
\&about_selected,
undef,
'<StockItem>',
'gtk-dialog-info',
],
);
my $factory = Gtk2::ItemFactory->new('Gtk2::Menu', '<main>', undef);
$factory->create_items(@data);
my $menu = $factory->get_widget('<main>');
$menu->popup(undef, undef, undef, 0, undef, undef);

return 1;
}

sub delete_selected {
my $idx = ($results_list->get_selected_indices)[0];
my $file = $results_list->{data}[$idx][2];
unlink($file);
log_entry(_('Deleted {file}', file => $file));
$results_list->{data}[$idx][1] = _('DELETED');
return 1;
}

sub rename_selected {
my $idx = ($results_list->get_selected_indices)[0];
my $file = $results_list->{data}[$idx][2];
my $dest = sprintf('%s.VIRUS', $file);
rename($file, $dest);
chmod(0400, $dest);
log_entry(_('Renamed {file}', file => $file));
$results_list->{data}[$idx][1] = _('Renamed to {file}', file => $dest);
return 1;
}

sub quarantine_selected {
my $idx = ($results_list->get_selected_indices)[0];
my $file = $results_list->{data}[$idx][2];
mkdir($QUARANTINE);
my $dest = sprintf('%s/%s', $QUARANTINE, basename($file));
if (rename($file, $dest)) {
chmod(0400, $dest);
log_entry(_('Quarantined {file}', file => $file));
$results_list->{data}[$idx][1] = _('Quarantined to {file}', file => $dest);
} else {
my $dialog = Gtk2::MessageDialog->new($app->get_widget('main_window'), 'modal', 'error', 'ok', _('Quarantine of file failed: {error}', error => $!));
$dialog->signal_connect('response', sub { $dialog->destroy });
$dialog->show_all;
}
return 1;
}

sub about_selected {
my $idx = ($results_list->get_selected_indices)[0];
my $virus = $results_list->{data}[$idx][1];
my $url = sprintf("http://vil.nai.com/vil/alphar.asp?Searc ... ch&char=%s", $virus);
system("gnome-open \"$url\" &");
return 1;
}

sub check_for_updates {
$app->get_widget('main_window')->window->set_cursor($busy);
set_status(_('Checking for updates...'));
update_ui();
my $data = Gnome2::VFS->read_entire_file($FM_URL);
set_status(_('Ready.'));
$app->get_widget('main_window')->window->set_cursor($normal);
if ($data =~ /<latest_release_version>(.+)<\/latest_release_version>/i) {
my $version = $1;
if ($version > $File::Scan::VERSION) {
my $dialog = Gtk2::MessageDialog->new_with_markup(
$app->get_widget('main_window'),
'modal', 'question',
'yes-no',
sprintf(
"<span weight=\"bold\" size=\"large\">%s</span>\n\n%s",
_('A new version of File::Scan is available.'),
_('Do you want to update?'),
),
);
$dialog->signal_connect('response', sub {
$dialog->destroy;
if ($_[1] eq 'yes') {
$app->get_widget('update_button')->clicked;
}
});
$dialog->show_all;
}
}
return undef;
}

sub exec_wait {
my ($command, $callback) = @_;

open(COMMAND, "$command|");
my $tag;
$tag = Gtk2::Helper->add_watch(fileno(COMMAND), 'in', sub {
if (eof(COMMAND)) {
close(COMMAND);
Gtk2::Helper->remove_watch($tag);
if (defined($callback)) {
&$callback();
}
}
});
return 1;
}

sub _ {
my $str = shift;
my %args = @_;
my $translated = gettext($str);
foreach my $name (keys %args) {
$translated =~ s/{$name}/$args{$name}/ig;
}
return $translated;
}
wangwg2007
帖子: 27
注册时间: 2007-11-13 15:01

#2

帖子 wangwg2007 » 2008-08-23 9:07

不知道你解决了没有,你可以通过应用程序菜单下的添加/删除程序安装,也许就可以解决
回复