| Config-Manager documentation | Contained in the Config-Manager distribution. |
Config::Manager::File - Basic File Utilities (for Tools)
use Config::Manager::File
qw(
Normalize
MakeDir
UniqueTempFileName
ConvertFromHost
ConvertToHost
CompareFiles
CopyFile
MoveByCopying
MD5Checksum
ReadFile
WriteFile
AppendFile
ConvertFileWithCallback
SerializeSimple
Semaphore_Passeer
Semaphore_Verlaat
GetNextTicket
);
use Config::Manager::File qw(:all);
$dir = Normalize($dir);
($drv,$dir) = Normalize($dir);
$error = MakeDir($dir);
$tempfilename = &UniqueTempFileName();
&ConvertFromHost($targetfile,$sourcefile,$linenumbering,$purgeblanks);
&ConvertToHost($targetfile,$sourcefile,$linenumbering,$purgeblanks,$checklength);
$same = &CompareFiles($file1,$file2);
&CopyFile($source,$target);
&MoveByCopying($source,$target);
$checksum = &MD5Checksum($source);
$arrayref = &ReadFile($source);
&WriteFile($target,@contents);
&AppendFile($target,$source);
&ConvertFileWithCallback($target,$source,$callback);
$printable = &SerializeSimple("varname",$datastructure);
Semaphore_Passeer($lockfile);
Semaphore_Verlaat($lockfile);
$ticket = GetNextTicket($lockfile,$ticketfile,$count_min,$count_max);
$dir = Normalize($dir);
($drv,$dir) = Normalize($dir);
"$drive/$path".
(Again, the "drive" will be a dot (".") if the path is
relative.)
$error = MakeDir($dir);
$tempfilename = &UniqueTempFileName();
.tmp".
&ConvertFromHost($targetfile,$sourcefile,$linenumbering,$purgeblanks);
$targetfile" is given) is written instead.
$targetfile" must be a valid filename; beware that it will
be overwritten if it already exists!
$sourcefile" is the input file's name (and path),
"$linenumbering" is a flag (0 = "no", 1 = "yes")
indicating whether line numbers shall be removed from the
beginning of each line, and "$purgeblanks" is a flag
(0 = "no", 1 = "yes") indicating whether trailing whitespace
is to be purged from each line.
$linenumbering" option is enabled, or if there was a
problem closing the input file, or if a needed configuration constant
was unavailable. &ConvertToHost($targetfile,$sourcefile,$linenumbering,$purgeblanks,$checklength);
$targetfile" is given) is written instead.
$targetfile" must be a valid filename; beware that it will
be overwritten if it already exists!
$sourcefile" is the input file's name (and path),
"$linenumbering" is a flag (0 = "no", 1 = "yes")
indicating whether line numbers shall be prepended to
each line, "$purgeblanks" is a flag (0 = "no",
1 = "yes") indicating whether trailing whitespace is to
be removed from each line, and "$checklength" is
a flag (0 = "no", 1 = "yes") signaling whether lines
should be checked for correct length (a warning message
will be issued if the maximum COBOL line length (66 columns)
is exceeded by any line).
$same = &CompareFiles($file1,$file2);
&CopyFile($source,$target);
$source" to "$target". Returns "true" (1) on success
and "undef" in case of any error.
&MoveByCopying($source,$target);
$source" to "$target", then deletes file
"$source" if the copy was successful. Returns "true" (1)
on success and "undef" in case of any error.
$checksum = &MD5Checksum($source);
$source". Returns the checksum
(a 16 digit hexadecimal string) on success and "undef" in case of any error.
$file" contains the name and path of the
file in question, and "$checksum" contains its checksum):
if (defined $filesig{-s $file}{$checksum})
{
# file already known
}
else
{
# file not encountered yet
}
$filesig{-s $file}{$checksum}{$file} = 1; # add file to list
$arrayref = &ReadFile($source);
$/" is set to "\n" (line mode)
locally before the file is read).
&WriteFile($target,@contents);
@msg = (); push( @msg, "1st line\n" ); push( @msg, "2nd line\n" ); &WriteFile( $target, "Messages:\n\n", \@msg );
&AppendFile($target,$source);
$source" to file "$target" using binary mode.
&ConvertFileWithCallback($target,$source,$callback);
$source" is read line by line (the input separator "$/"
is set to "\n" (line mode) locally before the file is opened), and for
each line, a callback function (provided by you) is called.
$target" file,
provided that the return value is not "undef". If the callback function's
return value is "undef", nothing is printed to the output file. (This way,
you can delete certain lines from a file!)
$cb = sub { my($l) = @_; $l =~ s!\s+$!!; "$l\n"; };
&ReportErrorAndExit unless
(defined &ConvertFileWithCallback($target,$source,$cb));
$printable = &SerializeSimple("varname",$datastructure);
WriteFile()" function, which will
automatically write the lines in the array to the indicated
file.
\n") at the end of each line.
require" or "eval".
Semaphore_Passeer($lockfile);
Semaphore_Verlaat($lockfile);
$ticket = GetNextTicket($lockfile,$ticketfile,$min,$max);
$min" value given).
$max" value, it
is reset to "$min" (i.e., the function implements automatic
wrapping).
Config::Manager(3), Config::Manager::Base(3), Config::Manager::Conf(3), Config::Manager::PUser(3), Config::Manager::Report(3), Config::Manager::SendMail(3), Config::Manager::User(3).
This man page documents "Config::Manager::File" version 1.7.
Steffen Beyer <sb@engelschall.com> http://www.engelschall.com/u/sb/download/ Gerhard Albers
Copyright (c) 2003 by Steffen Beyer & Gerhard Albers. All rights reserved.
This package is free software; you can use, modify and redistribute it under the same terms as Perl itself, i.e., under the terms of the "Artistic License" or the "GNU General Public License".
Please refer to the files "Artistic.txt" and "GNU_GPL.txt" in this distribution, respectively, for more details!
This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the "GNU General Public License" for more details.
| Config-Manager documentation | Contained in the Config-Manager distribution. |
############################################################################### ## ## ## Copyright (c) 2003 by Steffen Beyer & Gerhard Albers. ## ## All rights reserved. ## ## ## ## This package is free software; you can redistribute it ## ## and/or modify it under the same terms as Perl itself. ## ## ## ############################################################################### package Config::Manager::File; use strict; use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION ); require Exporter; @ISA = qw(Exporter); @EXPORT = qw(); @EXPORT_OK = qw( Normalize MakeDir UniqueTempFileName ConvertFromHost ConvertToHost CompareFiles CopyFile MoveByCopying MD5Checksum ReadFile WriteFile AppendFile ConvertFileWithCallback SerializeSimple Semaphore_Passeer Semaphore_Verlaat GetNextTicket ); %EXPORT_TAGS = (all => [@EXPORT_OK]); $VERSION = '1.7'; use Symbol; use Fcntl qw(:DEFAULT :flock); use Config::Manager::Base qw( $SCOPE ); use Config::Manager::Conf; use Config::Manager::Report qw(:ALL); # also import Normalize and MakeDir use File::Compare; use File::Copy; use Digest::MD5; ####################################### ## Internal configuration constants: ## ####################################### my @TEMPDIR = ('DEFAULT', 'TEMPDIRPATH'); my @MAXLEN = ('COBOL', 'Maximum_Line_Length'); my $DEFAULT_MAXLEN = 66; my $TMPEXT = 'tmp'; ####################### ## Static variables: ## ####################### my $Counter = 0; my @TempFileList = (); ######################## ## Private functions: ## ######################## END { my($file); foreach $file (@TempFileList) { if (-f $file and not unlink($file)) { print STDERR "Please remove temporary file '$file' manually: $!\n"; } } } ####################### ## Public functions: ## ####################### # sub Normalize; # imported from Config::Manager::Report # sub MakeDir; # imported from Config::Manager::Report sub UniqueTempFileName { my($path,$error,$file); unless (defined ($path = Config::Manager::Conf->get(@TEMPDIR))) { if ($^O =~ /Win32/i) { $path = $ENV{'TEMP'} || $ENV{'TMP'} || "C:\\Temp"; } else { $path = $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp"; } $error = Config::Manager::Conf->error(); $error =~ s!\s+$!!; Config::Manager::Report->report(@WARN, "Unable to determine directory for temporary files:", $error, "Using '$path' instead..."); } $path =~ s![/\\]+$!!; $path .= "/$SCOPE"; $file = sprintf ( "%s_%03d%02d%02d%02d_%d_%d.%s", $path, (localtime(time))[7,2,1,0], $$, ++$Counter, $TMPEXT ); push( @TempFileList, $file ); return $file; } sub ConvertFromHost { my($target,$source,$lines,$purge,$kludge) = @_; my($error,$line); local($/) = "\n"; local($.); local($!); unless (-f $source && -s $source) { Config::Manager::Report->report(@ERROR, "File '$source' not found or empty"); return undef; } unless (open(SOURCE, "<$source")) { Config::Manager::Report->report(@ERROR, "Can't read file '$source': $!"); return undef; } unless (open(TARGET, ">$target")) { Config::Manager::Report->report(@ERROR, "Can't write file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } $error = 0; while (defined ($line = <SOURCE>)) { if ($purge) { $line =~ s!\s+$!!; } else { $line =~ s![\x0D\x0A]+$!!; } if ($lines) { $error = 1 unless ($line =~ s!^\d\d\d\d\d\d!!); } # Translate ÜíÖùä!üß => ![\]{|}~ $line =~ tr/\xDC\xED\xD6\xF9\xE4\x21\xFC\xDF/\x21\x5B\x5C\x5D\x7B\x7C\x7D\x7E/ if ($kludge); print TARGET "$line\n"; } if ($error) { Config::Manager::Report->report(@WARN, "There were lines not beginning with 6 digits in file '$source'!"); } unless (close(TARGET)) { Config::Manager::Report->report(@ERROR, "Can't close file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return 1; } sub ConvertToHost { my($target,$source,$lines,$purge,$check,$kludge) = @_; my($maxlen,$error,$line); local($/) = "\n"; local($.); local($!); unless (-f $source && -s $source) { Config::Manager::Report->report(@ERROR, "File '$source' not found or empty"); return undef; } unless (open(SOURCE, "<$source")) { Config::Manager::Report->report(@ERROR, "Can't read file '$source': $!"); return undef; } unless (open(TARGET, ">$target")) { Config::Manager::Report->report(@ERROR, "Can't write file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } if ($check) { unless (defined ($maxlen = Config::Manager::Conf->get(@MAXLEN))) { $maxlen = $DEFAULT_MAXLEN; $error = Config::Manager::Conf->error(); $error =~ s!\s+$!!; Config::Manager::Report->report(@WARN, "Unable to determine maximum COBOL line length:", $error, "Using '$maxlen' instead..."); } } $error = 0; while (defined ($line = <SOURCE>)) { if ($purge) { $line =~ s!\s+$!!; } else { $line =~ s![\x0D\x0A]+$!!; } if ($check && (length($line) > $maxlen)) { $error = 1; } # Translate ![\]{|}~ => ÜíÖùä!üß $line =~ tr/\x21\x5B\x5C\x5D\x7B\x7C\x7D\x7E/\xDC\xED\xD6\xF9\xE4\x21\xFC\xDF/ if ($kludge); $line = sprintf("%05d0%s", $., $line) if ($lines); print TARGET "$line\n"; } if ($error) { Config::Manager::Report->report(@WARN, "Maximum COBOL line length ($maxlen) exceeded in file '$source'!"); } unless (close(TARGET)) { Config::Manager::Report->report(@ERROR, "Can't close file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return 1; } sub CompareFiles { my($source,$target) = @_; my($rc); local($!); # returns true (1) if both files have identical contents, # false (0) if their contents differ, # and undef if there was any error. unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (-f $target) { Config::Manager::Report->report(@ERROR, "File '$target' does not exist!"); return undef; } if (($rc = compare($source,$target)) < 0) { Config::Manager::Report->report(@ERROR, "Error while comparing files '$source' and '$target': $!"); return undef; } return ($rc == 0) ? 1 : 0; } sub CopyFile { my($source,$target) = @_; local($!); unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (copy($source,$target)) { Config::Manager::Report->report(@ERROR, "Error while copying file '$source' to '$target': $!"); return undef; } return 1; } sub MoveByCopying { my($source,$target) = @_; local($!); unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (copy($source,$target)) { Config::Manager::Report->report(@ERROR, "Error while copying file '$source' to '$target': $!"); return undef; } unless (unlink($source)) { Config::Manager::Report->report(@ERROR, "Could not unlink file '$source': $!"); return undef; } return 1; } sub MD5Checksum { my($source) = @_; my($md5,$checksum); local($!); unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (open(SOURCE, "<$source")) { Config::Manager::Report->report(@ERROR, "Can't read file '$source': $!"); return undef; } $md5 = Digest::MD5->new(); # $md5->reset(); # obsolete, same as new() $md5->addfile(*SOURCE); $checksum = $md5->hexdigest(); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return $checksum; } sub ReadFile { my($source) = @_; my(@text); local($/) = "\n"; local($!); unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (open(SOURCE, "<$source")) { Config::Manager::Report->report(@ERROR, "Can't read file '$source': $!"); return undef; } @text = <SOURCE>; unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return \@text; } sub WriteFile { my($target) = shift; my($item,$line); local($!); unless (open(TARGET, ">$target")) { Config::Manager::Report->report(@ERROR, "Can't write file '$target': $!"); return undef; } foreach $item (@_) { if (ref($item)) { if (ref($item) eq 'ARRAY') { foreach $line (@{$item}) { print TARGET $line; } } else { Config::Manager::Report->report ( @FATAL, "Illegal parameter '$item': neither a SCALAR nor an ARRAY reference" ); return undef; } } else { print TARGET $item; } } unless (close(TARGET)) { Config::Manager::Report->report(@ERROR, "Can't close file '$target': $!"); return undef; } return 1; } sub AppendFile { my($target,$source) = @_; my($size,$buffer,$read,$offset,$written); local($!); unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (open(SOURCE, "<$source")) { Config::Manager::Report->report(@ERROR, "Can't read file '$source': $!"); return undef; } unless (binmode(SOURCE)) { Config::Manager::Report->report(@ERROR, "Can't set binmode for file '$source': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } unless (open(TARGET, ">>$target")) { Config::Manager::Report->report(@ERROR, "Can't append to file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } unless (binmode(TARGET)) { Config::Manager::Report->report(@ERROR, "Can't set binmode for file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } unless (close(TARGET)) { Config::Manager::Report->report(@WARN, "Can't close file '$target': $!"); } return undef; } $size = -s SOURCE; $size = 1024 if ($size < 512); $size = 32768 if ($size > 32768); CYCLE: while (1) { unless (defined ($read = sysread(SOURCE,$buffer,$size))) { Config::Manager::Report->report(@ERROR, "Can't read from file '$source': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } unless (close(TARGET)) { Config::Manager::Report->report(@WARN, "Can't close file '$target': $!"); } return undef; } last CYCLE unless ($read > 0); for ( $offset = 0; $offset < $read; $offset += $written ) { unless (defined ($written = syswrite(TARGET,$buffer,$read-$offset,$offset))) { Config::Manager::Report->report(@ERROR, "Can't write to file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } unless (close(TARGET)) { Config::Manager::Report->report(@WARN, "Can't close file '$target': $!"); } return undef; } } } unless (close(TARGET)) { Config::Manager::Report->report(@ERROR, "Can't close file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return 1; } sub ConvertFileWithCallback { my($target,$source,$callback) = @_; my($line); local($/) = "\n"; local($.); local($!); unless (defined $callback && ref($callback) && ref($callback) eq 'CODE') { Config::Manager::Report->report(@FATAL, "Parameter '$callback' is not a valid CODE reference!"); return undef; } unless (-f $source) { Config::Manager::Report->report(@ERROR, "File '$source' does not exist!"); return undef; } unless (open(SOURCE, "<$source")) { Config::Manager::Report->report(@ERROR, "Can't read file '$source': $!"); return undef; } unless (open(TARGET, ">$target")) { Config::Manager::Report->report(@ERROR, "Can't write file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } while (defined ($line = <SOURCE>)) { if (defined ($line = &{$callback}($line,$.))) { print TARGET $line; } } unless (close(TARGET)) { Config::Manager::Report->report(@ERROR, "Can't close file '$target': $!"); unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return undef; } unless (close(SOURCE)) { Config::Manager::Report->report(@WARN, "Can't close file '$source': $!"); } return 1; } sub SerializeSimple { my($varname,$object) = @_; my($result) = []; push( @{$result}, "\$$varname =" ); &SerializeStruct($object,0,1,$result); ${$result}[$#{$result}] .= ";"; foreach $object (@{$result}) { $object .= "\n"; } return $result; } sub SerializeStruct { my($object,$indent,$append,$result) = @_; my($ref,$fill,$index,$more,$max,$key,$len,$scalar); $ref = ''; $fill = ' ' x $indent; while ((ref($object) eq 'REF') || (ref($object) eq 'SCALAR')) { $ref .= "\\"; $object = ${$object}; } if (ref($object) eq 'ARRAY') { if (($max = @{$object}) == 0) { if ($append) { ${$result}[$#{$result}] .= " ${ref}\[\]"; } else { push( @{$result}, "${fill}${ref}\[\]" ); } } else { push( @{$result}, "${fill}${ref}\[" ); $more = 0; $index = 0; while ($index < $max) { ${$result}[$#{$result}] .= "," if ($more); &SerializeStruct(${$object}[$index++],$indent+4,0,$result); $more = 1; } push( @{$result}, "${fill}\]" ); } } elsif (ref($object) eq 'HASH') { if (keys(%{$object}) == 0) { if ($append) { ${$result}[$#{$result}] .= " ${ref}\{\}"; } else { push( @{$result}, "${fill}${ref}\{\}" ); } } else { $max = 0; foreach $key (keys(%{$object})) { $len = length($key); $max = $len if ($len > $max); } push( @{$result}, "${fill}${ref}\{" ); $more = 0; foreach $key (sort keys(%{$object})) { ${$result}[$#{$result}] .= "," if ($more); $len = length($key); push( @{$result}, "${fill} '$key'" . ' ' x ($max-$len) . " =>" ); &SerializeStruct(${$object}{$key},$indent+4,1,$result); $more = 1; } push( @{$result}, "${fill}\}" ); } } else { if (defined $object) { $scalar = "$object"; unless ($scalar =~ /^-?(?:[1-9]\d*|0)(?:\.\d+)?$/) { $scalar =~ s!\\!\\\\!g; $scalar =~ s!\$!\\\$!g; $scalar =~ s!\n!\\n!g; $scalar =~ s!\t!\\t!g; $scalar =~ s!"!\\"!g; $scalar =~ s!@!\\@!g; $scalar =~ s!([\x00-\x1F\x7F-\xFF])!sprintf("\\x%.02X",ord($1))!eg; $scalar = "\"$scalar\""; } } else { $scalar = "undef"; } if ($append) { ${$result}[$#{$result}] .= " ${ref}$scalar"; } else { push( @{$result}, "${fill}${ref}$scalar" ); } } } sub Semaphore_Passeer { my($semaphore) = @_; # this is a filename! my($wait,$pid); local($!); $wait = 1; # Wait for semaphore: WAIT: while ($wait) { # Wait for semaphore to be released (if set): while (-f $semaphore) { sleep(1); } # When semaphore is gone, create own one: unless (open(SEMAPHORE, ">$semaphore")) { Config::Manager::Report->report(@ERROR, "Can't write semaphore '$semaphore': $!"); unless (unlink($semaphore)) { Config::Manager::Report->report(@WARN, "Could not unlink semaphore '$semaphore': $!"); } next WAIT; } print SEMAPHORE "$$\n"; close(SEMAPHORE); # Check wether semaphore is our's or was created # in the meantime by a different process: unless (open(SEMAPHORE, "<$semaphore")) { Config::Manager::Report->report(@ERROR, "Can't read semaphore '$semaphore': $!"); unless (unlink($semaphore)) { Config::Manager::Report->report(@ERROR, "Could not unlink semaphore '$semaphore': $!"); } next WAIT; } $pid = <SEMAPHORE>; close(SEMAPHORE); $pid =~ s!^\s+!!; $pid =~ s!\s+$!!; # Loop if semaphore isn't our's: $wait = ($pid != $$); Config::Manager::Report->report(@WARN, "Waiting for process '$pid' to release semaphore '$semaphore'...") if ($wait); } } sub Semaphore_Verlaat { my($semaphore) = @_; local($!); # Release semaphore: unless (unlink($semaphore)) { Config::Manager::Report->report(@ERROR, "Could not unlink semaphore '$semaphore': $!"); return undef; } return 1; } sub GetNextTicket { my($lock,$file,$count_min,$count_max) = @_; my($ok,$error,$counter); local($!); local($@); $ok = 0; $file = Normalize($file); $lock = Normalize($lock) if ($lock); my $FH_FILE = gensym(); unless (sysopen($FH_FILE, $file, O_RDWR|O_CREAT)) { Config::Manager::Report->report(@ERROR, "Can't open ticket file '$file': $!"); return undef; } eval { $ok = flock($FH_FILE, LOCK_EX); }; if ($@) { if ($@ =~ /\bunimplemented\b/) { &Semaphore_Passeer($lock) if ($lock); $ok = 1; } else { $error = $@; $error =~ s!\s+! !g; $error =~ s!\(.*$!!; $error =~ s!\s+at\s.*$!!; $error =~ s!\s+$!!; Config::Manager::Report->report(@ERROR, "Can't flock ticket file '$file': $error"); close($FH_FILE); return undef; } } else { if ($ok) { $lock = ''; } else { Config::Manager::Report->report(@ERROR, "Can't flock ticket file '$file': $!"); close($FH_FILE); return undef; } } unless (seek($FH_FILE, 0, 0)) { Config::Manager::Report->report(@ERROR, "Can't seek ticket file '$file': $!"); close($FH_FILE); &Semaphore_Verlaat($lock) if ($lock); return undef; } if (defined ($counter = <$FH_FILE>)) { $counter =~ s!^\s+!!; $counter =~ s!\s+$!!; if ($counter =~ /^[0-9a-zA-Z]+$/) { $counter = $count_min if (($counter eq $count_max) || (++$counter gt $count_max)); } else { $counter = $count_min; Config::Manager::Report->report(@WARN, "No valid ticket number found in file '$file'!", "Resetting the counter to value '$counter'."); } } else { $counter = $count_min; Config::Manager::Report->report(@WARN, "No ticket number found in file '$file'!", "Setting the counter to value '$counter'."); } unless (truncate($FH_FILE, 0)) { Config::Manager::Report->report(@ERROR, "Can't truncate ticket file '$file': $!"); close($FH_FILE); &Semaphore_Verlaat($lock) if ($lock); return undef; } unless (seek($FH_FILE, 0, 0)) { Config::Manager::Report->report(@ERROR, "Can't seek ticket file '$file': $!"); close($FH_FILE); &Semaphore_Verlaat($lock) if ($lock); return undef; } unless (print($FH_FILE "$counter\n")) { Config::Manager::Report->report(@ERROR, "Can't print ticket file '$file': $!"); close($FH_FILE); &Semaphore_Verlaat($lock) if ($lock); return undef; } unless (close($FH_FILE)) { Config::Manager::Report->report(@ERROR, "Can't close ticket file '$file': $!"); &Semaphore_Verlaat($lock) if ($lock); return undef; } &Semaphore_Verlaat($lock) if ($lock); return $counter; } 1; __END__