X-Git-Url: http://ftp.carnet.hr/carnet-debian/scm?p=carnet-tools-cn.git;a=blobdiff_plain;f=cp-update;h=5514ee650c07b37d685e878133999c6c0b30726a;hp=f4d66bee8ea70af10f0b7437b732ff6651503cd7;hb=refs%2Fheads%2Flenny;hpb=baae9f008f06d16d8d033ba280c0552403c1b9bb diff --git a/cp-update b/cp-update index f4d66be..5514ee6 100755 --- a/cp-update +++ b/cp-update @@ -35,7 +35,7 @@ sub DEBUG () { 0 }; # my ($ProgramName, $UsageLong, $UsageShort, $VERSION); -$VERSION = '2.0'; +$VERSION = '2.1'; # Looks nicer without the slashes and dots ($ProgramName = $0) =~ s!.*/!!; # strip dir @@ -109,7 +109,7 @@ $UsageShort .= " or type $ProgramName --help to be choked with help.\n"; my ($MarkBegin, $MarkEnd, $Trailer, $ParamBegin, $ParamEnd, $Placement, $Package, $File, $Block, $Multi, $InsertRemove, $Comment, $CommentEnd, $MatchLine, $RegexpMatch, $StdinContent, $NewContent, $InPlace, - $NoClose, $FileHandle, @Lines); + $NoClose, $FileHandle, @Lines, $LinesCount); # Placement modes use constant APPEND_AT_END => 0; @@ -251,7 +251,7 @@ do_it() and exit(0); # -------------- sub do_it { - slurp(); + $LinesCount = slurp(); if (DO_CHANGE == $InsertRemove) { $StdinContent = &stdin_content; change() or add(); @@ -278,10 +278,11 @@ sub slurp() { # If FILE does not have a trailing newline, be sure to add it # before appending anything else. - if (@Lines and $Lines[$#Lines] !~ m/\n$/s) { $Lines[$#Lines] .= "\n"; } + + return scalar @Lines; } sub add() { @@ -321,7 +322,9 @@ sub add() { push(@Lines, $StdinContent); } } - return scalar(@Lines); # whatever + # add the number of lines in added content to safety counter + $LinesCount += ($StdinContent =~ tr/\n//); + return $LinesCount; # whatever true } sub del() { @@ -337,9 +340,12 @@ sub del() { my (@filtered); foreach (@Lines) { - push (@filtered, $_) - unless (/^$mybegin(?:$mytrailer)?$/o .. /^$myend(?:$mytrailer)?$/o); - + if (/^$mybegin(?:$mytrailer)?$/o .. /^$myend(?:$mytrailer)?$/o) { + # additional safety counter for double-check + -- $LinesCount; + } else { + push (@filtered, $_); + } # for safety check: $bm_found = 1 if (/^$mybegin(?:$mytrailer)?$/o); $em_found = 1 if (/^$myend(?:$mytrailer)?$/o); @@ -352,7 +358,7 @@ sub del() { # safety exit die "$ProgramName: no end-mark after begin-mark!\n"; } - return scalar(@Lines); # whatever + return $LinesCount; # whatever } sub change() { @@ -371,6 +377,7 @@ sub change() { $skip = 0; # skip original block foreach (@Lines) { if (! $done and $skip > 0) { + -- $LinesCount; if (/^$myend(?:$mytrailer)?$/o) { ++ $done; # skipped all that was to skip } else { @@ -379,6 +386,7 @@ sub change() { } elsif (0 == $skip and $_ =~ /^$mybegin(?:$mytrailer)?$/o) { push (@filtered, $StdinContent); + $LinesCount += ($StdinContent =~ tr/\n//); $skip = 1; } else { @@ -407,7 +415,7 @@ sub actualize() { # put it all thogether my $newContent = join('', @Lines); - unless (length($newContent)) { + unless (length($newContent) or 0 == $LinesCount) { # safety exit in last second :) die "$ProgramName: New content empty -- aborting file alteration!\n"; } @@ -430,10 +438,13 @@ sub actualize() { sysseek(*$FileHandle, 0, SEEK_SET) or die "$ProgramName: Failed to seek to the begining of file ($!)\n"; } - my $wb = syswrite($FileHandle, $newContent); - if (! $wb or length($newContent) != $wb) { - # FIXME: try restoring backup copy - die "$ProgramName: Failed to write the content to '$File' ($!)\n"; + if (length($newContent)) { + my $wb = syswrite($FileHandle, $newContent); + if (! $wb or length($newContent) != $wb) { + # FIXME: try restoring backup copy + my $ncl = length($newContent); + die "$ProgramName: Failed to write the content to '$File' (wb=$wb, len=$ncl, err:$!)\n"; + } } if ($NoClose) { # this could be handy for files that had stuff appended @@ -448,12 +459,15 @@ sub actualize() { $file_new .= '.cp-update.new'; # our .new file $file_old .= '.cp-update.old'; # our .old file # write content in new file in single write op - sysopen ($FileHandle, $file_new, O_CREAT|O_TRUNC|O_WRONLY) + sysopen ($FileHandle, $file_new, O_CREAT|O_TRUNC|O_WRONLY, (stat($File))[2]) or die "$ProgramName: Failed to open file '$File' for writing ($!)\n"; - my $wb = syswrite($FileHandle, $newContent); - if (! $wb or length($newContent) != $wb) { - unlink($file_new); - die "$ProgramName: Failed to write the content to '$File' ($!)\n"; + if (length($newContent)) { + my $wb = syswrite($FileHandle, $newContent); + if (! $wb or length($newContent) != $wb) { + unlink($file_new); + my ($ncl) = length($newContent); + die "$ProgramName: Failed to write the content to '$File' (wb=$wb, len=$ncl, err:$!)\n"; + } } close($FileHandle); # do the moving (should be atomic) @@ -478,6 +492,7 @@ sub actualize() { unlink($file_old) or warn "$ProgramName: Failed to remove file '$file_old' ($!)\n"; } + DEBUG and print STDERR "actualize: LinesCount=$LinesCount\n"; } # return content from standard input