Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134577
  • 博文数量: 73
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 760
  • 用 户 组: 普通用户
  • 注册时间: 2008-01-29 14:07
文章分类
文章存档

2011年(2)

2010年(4)

2009年(40)

2008年(27)

我的朋友

分类:

2008-12-24 16:21:49

 此脚本用于可保文件内容的md5校验和及以文件stat信息以及与生成的校验数据进行对比,找好更动过的文件。脚本如下:

#!/usr/bin/perl
#
#用法:
#genmd5.pl --basedir=/etc --chksumfile=etc-chksum.dat
#genmd5.pl --basedir /private/etc --compare
use strict;

use Digest::MD5;

use IO::File;
use File::Find ();

use Getopt::Long;

#设置默认值
my $chksumfile = 'chksums.dat';
my $compare = 0;
my $basedir = '/etc';

use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

GetOptions("chksumfile=s" => \$chksumfile,
           "compare" => \$compare,
           "basedir=s" => \$basedir);

my $chksumdata = {};

if ($compare)
{
    loadchksumdata($chksumfile);
}

my $outfile = '';

if (!$compare)
{
    $outfile = IO::File->new($chksumfile,"w");
}

File::Find::find({wanted => \&wanted}, $basedir);

if ($compare)
{
    foreach my $file (keys %{$chksumdata})
    {
        print STDERR "Couldn't find $file, but have the info on record\n";
    }
}

sub loadchksumdata
{
    my ($file) = @_;

    open(DATA,$file) or die "Cannot open check sum file $file: $!\n";
    while()
    {
        chomp;
        my ($filename,$rest) = split(/:/,$_,2);
        $chksumdata->{$filename} = $_;
    }
    close(DATA);
}

sub wanted {
    next unless (-f $name);

    my $fileinfo = genchksuminfo($name);

    if ($compare)
    {
        if (exists($chksumdata->{$name}))
        {
            if ($chksumdata->{$name} ne $fileinfo)
            {
                print STDERR "Warning: $name differs from that on record\n";
                gendiffreport($chksumdata->{$name}, $fileinfo);
            }
            delete($chksumdata->{$name});
        }
        else
        {
            print STDERR "Warning: Couldn't find $name in existing records\n";
        }
    }
    else
    {
        printf $outfile ("%s\n",$fileinfo);
    }
}

sub gendiffreport
{
    my ($orig,$curr) = @_;

    my @fields = qw/filename chksum device inode mode nlink uid gid size mtime ctime/;

    my @origfields = split(/:/,$orig);
    my @currfields = split(/:/,$curr);

    for(my $i=0;$i    {
        if ($origfields[$i] ne $currfields[$i])
        {
            print STDERR "\t$fields[$i] differ; was $origfields[$i],
                             now $currfields[$i]\n";
        }
    }

}

sub genchksuminfo
{
    my ($file) = @_;

    my $chk = Digest::MD5->new();

    my (@statinfo) = stat($file);

    $chk->add(@statinfo[0,1,2,3,4,5,7,9,10]);
    $chk->addfile(IO::File->new($file));
    return sprintf("%s:%s:%s",
                   $file,$chk->hexdigest,
                   join(':',@statinfo[0,1,2,3,4,5,9,10]));
}

用以下命令生成校验数据:

[root@supersun securety]# ./getsum.pl --basedir=/etc/ --chksumfile=etc-chksum.dat

etc-chksum.dat格式如下:

/etc/bluetooth/hcid.conf:c3fb848b5e2f57e3cd65ecd8dd766724:769:1627930:33188:1:0:0:1153336356:1163469800
/etc/bluetooth/pin:81bdf50f2025f988490024cfbd36ffb8:769:1627931:33152:1:0:0:1153336356:1163469800
校验文件:

[root@supersun securety]# ./getsum.pl --basedir=/etc --compare --chksumfile=etc-chksum.dat
Warning: /etc/fstab differs from that on record
        chksum differ; was 253f53fef12b9e6fa7bc2cb3556427de,
                             now a8506e1f2ff5e5dcb08d93b64b1be235
        inode differ; was 1629160,
                             now 1627820
        size differ; was 1187075582,
                             now 1190012212
        mtime differ; was 1187075582,
                             now 1190012212

阅读(585) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~