📄 editconf.perl
字号:
print "I would have commented out the following lines in $path:\n"; grep { /$regexp/ && print; } @wholefile; } else { my $tmpnm = &tmpnam("$path.$$"); my $comment_re = quotemeta $comment; my @commented_out; open(CFG, ">$tmpnm") || die("Couldn't open $tmpnm for output!\n"); foreach (@wholefile) { # We care if it matches, and isn't already commented out. if ((/$regexp/) && (!/^$comment_re/)) { push @commented_out, $_; print CFG $comment; } print CFG; } if ($#commented_out == -1) { # We didn't actually need to comment anything out! # Apparently all the lines that matched our regexp were # already commented out. $verbose && print "All the lines matching our regexp were ", "already commented out, so we're not doing ", "anything!\n"; unlink $tmpnm; exit 0; }# $silent || print "Commented out the following lines in $path:\n";# $silent || grep { print; } @commented_out;# $silent || print "(end of lines commented out in $path)\n"; my $bak = &tmpnam("$path.O"); rename($path, $bak) || die("Couldn't rename $path to $bak!\n"); rename($tmpnm, $path) || die("Couldn't rename $tmpnm to $path!\n"); $silent || print "Original file saved as $bak\n"; } exit 0; } # just a sanity check... ($op eq "add") || die("bad op \"\$op\""); # We're still here, so we found our regexp, which suggests that the # entry we're adding might already be in the file. Do our new lines # match existing lines exactly? $verbose && print "The file contains our regular expression, so let's see ", "if it has our lines...\n"; $matched = 1; my $re; foreach (@lines) { $re = quotemeta $_; $verbose && print " Looking for \"$re\"\n"; if (! grep /^$re$/, @wholefile) { $verbose && print " Didn't find it!\n"; $matched = 0; last; } } if ($matched) { # The lines we would have added are already in the file, so # we can all go home early. $verbose && print "$path already contains the lines we would have ", "added.\n"; exit 0; } # All right, we're still here, so let's see if the lines we would have # added are in the file, but commented out. This is slightly complicated # by the possibility that lines we're adding start with comments; if so, # we don't want to require that they be preceded by another comment # character. $verbose && print "Let's see if it has our lines, but commented out...\n"; $re = quotemeta $comment; my @linesre = @lines; grep { # If it starts with a comment, require make an additional starting # comment optional. (the ($re.*)? as opposed to $re.*) $_ = (/^$re/) ? "^($re.*)?" . quotemeta $_ : "^$re.*" . quotemeta $_; } @linesre; $matched = 1; foreach $re (@linesre) { # This loop through @linesre isn't done in the grep above because # we want that to iterate through every element, while this loop # can bail as soon as it fails to find a line it's looking for. $verbose && print " Looking for \"$re\"\n"; # If you change this next line, make sure you make the same changes # in the substitution below. if (! grep /$re$/, @wholefile) { $verbose && print " Didn't find it!\n"; $matched = 0; last; } } if ($matched) { # The lines we would have added are already in the file, but # commented out. Let's uncomment them into a temp file, and then # replace the existing file with the temp file. if ($noexec) { print "I would have uncommented the following lines in $path:\n"; foreach (@lines) { print "$_\n"; } exit 0; } # This is crude. For every line in the file, if it matches the # commented-out version of any of the lines we're adding, replace # it with the corresponding non-commented-out line. my $idx; foreach (@wholefile) { foreach $idx (0..$#lines) { s/$linesre[$idx]$/$lines[$idx]/ && last; } } # isn't there a perl tmpnam? this open/die is stupid. my $tmpnm = &tmpnam("$path.$$"); open(CFG, ">$tmpnm") || die("Couldn't open $tmpnm for output!\n"); print CFG @wholefile; close(CFG) || die("Couldn't close $tmpnm after writing!\n"); rename($tmpnm, $path) || die("Couldn't replace $path with $tmpnm " . "after writing!\n"); exit 0; } # We're still here, so it looks like our configuration lines are in the # file, but they're different than what we would have added. Nuts! # Comment out everything matching our regexp and append our new lines, # but do it into a new file so that we don't stomp any existing # configuration. my $tmpnm = &tmpnam("$path.N"); if ($noexec) { print "I would have copied $path to $tmpnm and commented out the following lines in $tmpnm:\n"; grep { /$regexp/ && print; } @wholefile; print "...and added the following lines to $tmpnm:\n"; foreach (@lines) { print "$_\n"; } exit 0; } grep { /$regexp/ && ($_ = ($comment . $_)); } @wholefile; # Now append our new stuff foreach (@lines) { push @wholefile, "$_\n"; } open(CFG, ">$tmpnm") || die("Couldn't open $tmpnm for output!\n"); print CFG @wholefile; close(CFG) || die("Couldn't close $tmpnm after writing!\n"); # Just for fun, if $path.N already existed, let's see if it's the # same as what we just wrote. &diff($tmpnm, "$path.N", \@wholefile) || ($tmpnm = "$path.N"); print STDERR <<"EOF";**********************************************************************Configuration changes to $file have not been madeautomatically because there appears to be a conflict between thefile's current contents and the lines which would have been added.Original file: $pathNew file: $tmpnmPlease compare these two files and update the original file as needed.**********************************************************************EOF exit 0;}# Returns the array of elements matching the given re in the given array,# and removes those elements from the array. If $bre is set, we only# search through the array until an element matching $bre is encountered.sub splicegrep { my($re, $a, $bre) = @_; my @ta = (); my @ra = (); my $skip = 0; $a || ($a = \@ARGV); # sub-optimal but our argv should be short grep { $bre && /$bre/ && ($skip = 1); ((!$skip) && /$re/) ? push @ra, $_ : push @ta, $_; } @{$a}; @{$a} = @ta; return @ra;}# This is kind of stupid.sub tmpnam { my($base) = @_; my $hope = $base; my $count = 0; while(-e $hope) { $hope = "$base$count"; ++$count; } return $hope;}# Returns 0 if we know the two files are the same, 1 if we're not sure.sub diff { my($fn1, $fn2, $fc1) = @_; ($fn1 eq $fn2) && return 0; # same file name! my $sz1 = (stat $fn1)[7]; # size $sstuff[7]; # size my $sz2 = (stat $fn2)[7]; # size $sstuff[7]; # size $sz1 && ($sz1 != $sz2) && return 1; # different sizes; they're different # Nuts, they're the same size, so we have to compare them. open(FH2, "<$fn2") || return 1; my @snort2 = <FH2>; close(FH2); # Same number of lines? ($#snort2 == $#{$fc1}) || return 1; my $i = $#snort2; while ($i >= 0) { ($snort2[$i] eq $fc1->[$i]) || return 1; --$i; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -