#!/usr/bin/perl # Copyright 1999-2017. Parallels IP Holdings GmbH. All Rights Reserved. package Storage::FileNameCreator; use strict; #use Text::Iconv; use Fcntl qw(O_RDWR O_CREAT LOCK_EX SEEK_SET); sub new { my $self = {}; bless( $self, shift ); $self->_init(@_); return $self; } sub _init{ my( $self ) = @_; if( eval( "require use Text::Iconv" ) ){ $self->{iconv} = Text::Iconv->new("UTF-8", "ASCII//TRANSLIT" ); } $self->{dateprefix} = undef; $self->{incrementalCreationDate} = undef; } sub setIncrementalCreationDate{ my ($self, $incrementalCreationDate) = @_; $self->{incrementalCreationDate} = $incrementalCreationDate; } sub getFileName{ my ($self, $normalizedPath, $normalizedbackupfileName, $normalizedObjectId, $fileName ) = @_; my $ret = ''; $ret .= "$normalizedPath/" if $normalizedPath; $ret .= "$normalizedbackupfileName\_" if $normalizedbackupfileName; $ret .= $fileName . '_' if $fileName; $ret .= $self->{incrementalCreationDate} . '_' if defined($self->{incrementalCreationDate}); $ret .= $self->getCreationDate(); return $ret; } sub getCreationDate { my ($self) = @_; if (!$self->{dateprefix}) { $self->{dateprefix} = $self->_createDatePrefix(); } return $self->{dateprefix}; } sub _createDatePrefix { my ($self) = @_; my $lastDumpsHandle = undef; if (!sysopen($lastDumpsHandle, AgentConfig::lastDumpsFile(), O_RDWR|O_CREAT)) { Logging::debug(sprintf("Unable to open the file '%s': %s. Generate default date perfix.", AgentConfig::lastDumpsFile(), $!)); return $self->_createDefaultDatePrefix(); } if (!flock($lastDumpsHandle, LOCK_EX)) { Logging::debug(sprintf("Unable to lock the file '%s': %s. Generate default date perfix.", AgentConfig::lastDumpsFile(), $!)); return $self->_createDefaultDatePrefix(); } my @lastDumps = (); while (my $lastDump = <$lastDumpsHandle>) { chomp($lastDump); if (!$lastDump) { next; } push(@lastDumps, $lastDump); } my $addition = 0; my $datePrefix = $self->_createDefaultDatePrefix($addition); while (grep(/^$datePrefix$/, @lastDumps)) { $datePrefix = $self->_createDefaultDatePrefix(++$addition); } push(@lastDumps, $datePrefix); seek($lastDumpsHandle, 0, SEEK_SET); truncate($lastDumpsHandle, 0); splice(@lastDumps, 0, -100); foreach my $lastDump (@lastDumps) { print $lastDumpsHandle "$lastDump\n"; } close($lastDumpsHandle); return $datePrefix; } sub _createDefaultDatePrefix { my (undef, $addition) = @_; my (undef, $min, $hour, $mday, $mon, $year) = localtime(time() + (defined($addition) ? 60 * $addition : 0)); return sprintf('%0.2d%0.2d%0.2d%0.2d%0.2d', $year % 100, $mon + 1, $mday, $hour, $min); } sub normalize_long_string{ my ($self, $str, $id) = @_; return $self->normalize_string( $str, $id, 47 ); } sub normalize_short_string{ my ($self, $str, $id) = @_; return $self->normalize_string( $str, $id, 25 ); } sub replace_danger{ my ($self, $str) = @_; #danger: " ", ":", ">", "<", "|", "&", "!" #replace: "_", "-", "-gt-","-lt-","_", "-and-", "_" if ( $str =~ /[\ :><\|&!]/s ) { $str =~ s/\ /_/sg; $str =~ s/:/-/sg; $str =~ s/>/-gt-/sg; $str =~ s/{iconv}->convert( $str ) if exists $self->{iconv}; my $res = $res_orig; $res = $self->replace_danger( $res_orig ); if( length($res) > $max_length ){ $res = substr( $res, 0, $max_length - length($id) - 1 ) . "_" . $id; } elsif ($res_orig ne $res or $res =~ /_?\d{10}$/) { my $newLen = length($res); $newLen = $max_length - length($id) - 1 if $newLen + length($id) + 1 > $max_length; $res = substr( $res, 0, $newLen ) . "_" . $id; } return $res; } sub normalize_id_string{ my ($self, $str, $id, $max_length) = @_; my $res_orig = $str; $res_orig = $self->{iconv}->convert( $str ) if exists $self->{iconv}; my $res = $self->replace_danger( $res_orig ); if( $max_length and length($res) > $max_length ){ $res = substr( $res, 0, $max_length ); } return $res; } 1;