File Coverage

blib/lib/MD5Check.pm
Criterion Covered Total %
statement 9 78 11.5
branch 0 52 0.0
condition 0 12 0.0
subroutine 3 7 42.8
pod 0 4 0.0
total 12 153 7.8


line stmt bran cond sub pod time code
1             package MD5Check;
2              
3 1     1   17296 use strict;
  1         3  
  1         37  
4 1     1   4 use warnings;
  1         2  
  1         28  
5 1     1   4 use Digest::MD5;
  1         5  
  1         1008  
6             require Exporter;
7              
8             our @ISA = qw(Exporter);
9             our @EXPORT = qw(init md5init md5check);
10              
11             =encoding utf8
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.11
21              
22             =cut
23              
24             our $VERSION = '0.11';
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 0 0         unless($@) {
61 0           $ctx = Digest::MD5->new;
62 0 0         binmode($FD) if $mode;
63 0 0         $ctx->addfile($FD) or warn "$!\n";
64 0           $md5 = $ctx->hexdigest;
65 0 0         close $FD if $FD;
66 0           return $md5;
67             }
68             }
69              
70             sub md5check {
71 0     0 0   my $file = shift;
72 0 0         open( my $fd, '<', $file ) or warn "$file: $!\n";
73 0           my $res .= $file . "\n";
74 0           while (<$fd>) {
75 0           chomp;
76 0 0         next if /$file/; # ignore the recode file itself
77 0           my ( $name, $sum ) = split /\|\|/;
78 0 0         print $name,"\n" if $DEBUG;
79 0 0         print $sum,"\n" if $DEBUG;
80 0 0         print md5_sum( $name, 1 ),"\n" if $DEBUG;
81 0           $name =~ s/^\#//;
82 0 0         if ( $sum eq md5_sum( $name, 1 ) ) {
83 0           $res .= "$name OK\n";
84             }
85             else {
86 0           $res .= "$name FAILED\n";
87             }
88             }
89              
90 0           close $fd;
91              
92 0           return $res;
93             }
94              
95             # 遍历目录计算md5值
96              
97             sub init {
98             # 仅仅用来打印init信息
99 0     0 0   my ($fd) = @_;
100 0           my $res;
101 0 0         if ( -f $fd ) {
    0          
102 0 0         if ( -T $fd ) {
    0          
103              
104             #print "按照文本模式进行计算MD5!\n";
105 0           my $md5value = md5_sum( $fd, 0 );
106 0           print "$fd||$md5value\n" ;
107             }
108             elsif ( -B $fd ) {
109              
110             #print "二进制文件用binmod计算MD5!\n";
111 0           my $md5value = md5_sum( $fd, 1 );
112 0           print "$fd||$md5value\n";
113             }
114             else {
115             #print "其他文件,按照bimmod计算!\n";
116 0           my $md5value = md5_sum( $fd, 1 );
117 0           print "$fd||$md5value\n";
118             }
119             }
120             elsif ( -d $fd ) {
121 0           my $file_md5;
122 0 0         opendir( my $DH, $fd ) or warn "Can't open dir $fd: $!";
123 0           for ( readdir $DH ) {
124 0           my $file = $fd . '/' . $_;
125             # 上级目录..,本目录. 以及连接文件跳过
126 0 0 0       next if ( $file =~ m{/.$} || $file =~ m{/..$} || -l $file );
      0        
127 0           eval { init($file);};
  0            
128 0 0         if ($@) {
129             }
130             }
131 0           closedir $DH;
132             }
133             }
134              
135              
136             sub md5init {
137              
138 0     0 0   my ($fd,$outFD) = @_;
139 0           my $res;
140 0 0         if ( -f $fd ) {
    0          
141 0 0         if ( -T $fd ) {
    0          
142              
143             #print "按照文本模式进行计算MD5!\n";
144 0           my $md5value = md5_sum( $fd, 0 );
145 0           print $outFD "$fd||$md5value\n" ;
146             }
147             elsif ( -B $fd ) {
148              
149             #print "二进制文件用binmod计算MD5!\n";
150 0           my $md5value = md5_sum( $fd, 1 );
151 0           print $outFD "$fd||$md5value\n";
152             }
153             else {
154             #print "其他文件,按照bimmod计算!\n";
155 0           my $md5value = md5_sum( $fd, 1 );
156 0           print $outFD "$fd||$md5value\n";
157             }
158             }
159             elsif ( -d $fd ) {
160 0           my $file_md5;
161 0           print "init for all files $fd:\n";
162 0 0         opendir( my $DH, $fd ) or warn "Can't open dir $fd: $!";
163 0           for ( readdir $DH ) {
164 0           my $file = $fd . '/' . $_;
165             # 上级目录..,本目录. 以及连接文件跳过
166 0 0 0       next if ( $file =~ m{/.$} || $file =~ m{/..$} || -l $file );
      0        
167 0           eval { md5init($file,$outFD);};
  0            
168 0 0         if ($@) {
169 0           print "some wron for init $file\n ";
170             }
171 0 0         print "Debug::", $res if $DEBUG;
172             }
173 0           closedir $DH;
174             }
175 0           return $res;
176             }
177              
178             1;
179             __END__