Net-FTP-Recursive

 view release on metacpan or  search on metacpan

Recursive.pm  view on Meta::CPAN

    #while loop is needed to make it start over after each
    #match (as it will need to go back for parts of the
    #regex).  It's probably possible to write a regex to do it
    #without the while loop, but I don't think that making it
    #less readable is a good idea.  :)

    while ( $remote_pwd =~ s#(?:^|/)\.(?:/|$)#/# ) {}
    while ( $remote_pwd =~ s#(?:/[^/]+)?/\.\.(?:/|$)#/# ){}

    #the %linkMap will store as keys the absolute paths
    #to the links and the values will be the "real"
    #absolute paths to those locations (to take care of
    #../-type links

    $filename =~ s#/$##;
    $remote_pwd =~ s#/$##;

    $pwd =~ s#(?<!/)$#/#; #make sure there's a / on the end
    $linkMap{$pwd . $filename} = $remote_pwd;

    $remote_pwd; #return the result
}

=begin comment

  This subroutine takes two absolute paths and basically
  'links' them together.  The idea is that all of the paths
  that are created for the symlinks should be relative
  paths.  This is the sub that does that.

  There are essentially 6 cases:

    -Different root hierarchy:
    /tmp/testdata/blah -> /usr/local/bin/blah
    -Current directory:
    /tmp/testdata/blah -> /tmp/testdata
    -A file in the current directory:
    /tmp/testdata/blah -> /tmp/testdata/otherblah
    -Lower in same hierarchy:
    /tmp/testdata/blah -> /tmp/testdata/dir/otherblah
    -A higher directory along the same path (part of link abs path) :
    /tmp/testdata/dir/dir2/otherblah -> /tmp/testdata/dir
    -In same hierarchy, somewhere else:
    /tmp/testdata/dir/dir2/otherblah -> /tmp/testdata/dir/file

  The last two cases are very similar, the only difference
  will be that it will create '../' for the first rather
  than the possible '../../dir'.  The last case will indeed
  get the '../file'.

=end comment

=cut

sub convert_to_relative{
    my($link_loc, $realfile) = (shift, shift);
    my $i;
    my $result;
    my($new_realfile, $new_link, @realfile_parts, @link_parts);

    @realfile_parts = split m#/#, $realfile;
    @link_parts = split m#/#, $link_loc;

    for ( $i = 0; $i < @realfile_parts; $i++ ) {
        last unless $realfile_parts[$i] eq $link_parts[$i];
    }

    $new_realfile = join '/', @realfile_parts[$i..$#realfile_parts];
    $new_link = join '/', @link_parts[$i..$#link_parts];

    if( $i == 1 ){
        $result = $realfile;
    }
    elsif ( $i > $#realfile_parts and $i == $#link_parts  ) {
        $result = '.';
    }
    elsif ( $i == $#realfile_parts and $i == $#link_parts ) {
        $result = $realfile_parts[$i];
    }
    elsif ( $i >= $#link_parts  ) {
        $result = join '/', @realfile_parts[$i..$#realfile_parts];
    }
    else {
        $result = '../' x ($#link_parts - $i);
        $result .= join '/', @realfile_parts[$i..$#realfile_parts]
          if $#link_parts - $i > 0;
    }

    return $result;
}


package Net::FTP::Recursive::File;

use vars qw/@ISA/;
use Carp;

@ISA = ();

sub new{
    my $pkg = shift;

    my $self = { plainfile => 0,
                 directory => 0,
                 'symlink' => 0,
                 @_
               };

    croak 'Must set a filename when creating a File object!'
      unless defined $self->{filename};

    if( $self->{'symlink'} and not $self->{linkname} ){
        croak 'Must set a linkname when creating a File object for a symlink!';
    }

    bless $self, $pkg;
}

sub linkname{
    return $_[0]->{linkname};
}



( run in 1.827 second using v1.01-cache-2.11-cpan-71847e10f99 )