File Coverage

blib/lib/MD5Check.pm
Criterion Covered Total %
statement 12 77 15.5
branch 0 46 0.0
condition 0 12 0.0
subroutine 4 8 50.0
pod 0 4 0.0
total 16 147 10.8


line stmt bran cond sub pod time code
1             package MD5Check;
2              
3 1     1   16410 use strict;
  1         1  
  1         29  
4 1     1   5 use warnings;
  1         1  
  1         25  
5 1     1   590 use utf8;
  1         13  
  1         4  
6 1     1   27 use Digest::MD5;
  1         2  
  1         879  
7             require Exporter;
8              
9             our @ISA = qw(Exporter);
10             our @EXPORT = qw(init md5init md5check);
11              
12             =head1 NAME
13              
14             MD5Check - Use it for init Web files's md5 values of your site(or other dir), and check if it changed!
15              
16             检查web目录(或者其他重要系统目录)md5值,当目录文件变化提醒。用于文件防篡改。
17              
18             =head1 VERSION
19              
20             Version 0.09
21              
22             =cut
23              
24             our $VERSION = '0.09';
25              
26             =head1 SYNOPSIS
27              
28             use MD5Check;
29              
30             ## 初始化目录md5值,参数为要监控的目录
31              
32             my $mydir=shift;
33             print init($mydir);
34              
35             ## 对目录文件进行检查,只需输入之前保存的md5 文件值。
36              
37             use MD5Check;
38             my $mydir=shift;
39             print md5check($mydir);
40              
41             # oneliner,perl单行程序实现功能。
42              
43             需要安装该模块,简单通过 cpanm MD5Check 安装。
44              
45             ## 相关实例可以直接使用bin/下的init.pl 和 check.pl 单行执行
46              
47             $ perl -MMD5Check -e 'init("/web")' >file
48             $ perl -MMD5Check -e 'print md5check(file)'..
49              
50              
51             =cut
52              
53             my $DEBUG = 0;
54              
55             sub md5_sum {
56              
57 0     0 0   my ( $file_name, $mode ) = @_;
58 0           my ( $FD, $ctx, $md5 );
59 0 0         eval {open( $FD, $file_name ) or warn "Can't open $file_name !";
  0            
60             };
61 0 0         unless($@) {
62 0           $ctx = Digest::MD5->new;
63 0 0         binmode($FD) if $mode;
64 0 0         $ctx->addfile($FD) or warn "$!\n";
65 0           $md5 = $ctx->hexdigest;
66 0 0         close $FD if $FD;
67 0           return $md5;
68             }
69             }
70              
71             sub md5check {
72 0     0 0   my $file = shift;
73 0 0         open( my $fd, '<', $file ) or warn "$file: $!\n";
74 0           my $res .= $file . "\n";
75 0           while (<$fd>) {
76 0 0         next if /$file/; # ignore the recode file itself
77 0           my ( $name, $sum ) = split /\s+/;
78 0           $name =~ s/^\*//;
79 0 0         if ( $sum eq md5_sum( $name, 1 ) ) {
80 0           $res .= "$name OK\n";
81             }
82             else {
83 0           $res .= "$name FAILED\n";
84             }
85             }
86              
87 0           close $fd;
88              
89 0           return $res;
90             }
91              
92             # 遍历目录计算md5值
93              
94             sub init {
95             # 仅仅用来打印init信息
96 0     0 0   my ($fd) = @_;
97 0           my $res;
98 0 0         if ( -f $fd ) {
    0          
99 0 0         if ( -T $fd ) {
    0          
100              
101             #print "按照文本模式进行计算MD5!\n";
102 0           my $md5value = md5_sum( $fd, 0 );
103 0           print "$fd\t$md5value\n" ;
104             }
105             elsif ( -B $fd ) {
106              
107             #print "二进制文件用binmod计算MD5!\n";
108 0           my $md5value = md5_sum( $fd, 1 );
109 0           print "$fd\t$md5value\n";
110             }
111             else {
112             #print "其他文件,按照bimmod计算!\n";
113 0           my $md5value = md5_sum( $fd, 1 );
114 0           print "$fd\t$md5value\n";
115             }
116             }
117             elsif ( -d $fd ) {
118 0           my $file_md5;
119 0 0         opendir( my $DH, $fd ) or warn "Can't open dir $fd: $!";
120 0           for ( readdir $DH ) {
121 0           my $file = $fd . '/' . $_;
122             # 上级目录..,本目录. 以及连接文件跳过
123 0 0 0       next if ( $file =~ m{/.$} || $file =~ m{/..$} || -l $file );
      0        
124 0           eval { init($file);};
  0            
125 0 0         if ($@) {
126             }
127             }
128 0           closedir $DH;
129             }
130             }
131              
132              
133             sub md5init {
134              
135 0     0 0   my ($fd,$outFD) = @_;
136 0           my $res;
137 0 0         if ( -f $fd ) {
    0          
138 0 0         if ( -T $fd ) {
    0          
139              
140             #print "按照文本模式进行计算MD5!\n";
141 0           my $md5value = md5_sum( $fd, 0 );
142 0           print $outFD "$fd\t$md5value\n" ;
143             }
144             elsif ( -B $fd ) {
145              
146             #print "二进制文件用binmod计算MD5!\n";
147 0           my $md5value = md5_sum( $fd, 1 );
148 0           print $outFD "$fd\t$md5value\n";
149             }
150             else {
151             #print "其他文件,按照bimmod计算!\n";
152 0           my $md5value = md5_sum( $fd, 1 );
153 0           print $outFD "$fd\t$md5value\n";
154             }
155             }
156             elsif ( -d $fd ) {
157 0           my $file_md5;
158 0           print "init for all files $fd:\n";
159 0 0         opendir( my $DH, $fd ) or warn "Can't open dir $fd: $!";
160 0           for ( readdir $DH ) {
161 0           my $file = $fd . '/' . $_;
162             # 上级目录..,本目录. 以及连接文件跳过
163 0 0 0       next if ( $file =~ m{/.$} || $file =~ m{/..$} || -l $file );
      0        
164 0           eval { md5init($file,$outFD);};
  0            
165 0 0         if ($@) {
166 0           print "some wron for init $file\n ";
167             }
168 0 0         print "Debug::", $res if $DEBUG;
169             }
170 0           closedir $DH;
171             }
172 0           return $res;
173             }
174              
175             1;
176             __END__