NAME¶
abs2rel - convert an absolute path to a relative path
rel2abs - convert a relative path to an absolute path
realpath - convert a logical path to a physical path (resolve symlinks)
splitpath - split a path in to volume, directory and filename components
joinpath - join volume, directory, and filename components to form a path
splitdirs - split directory specification in to component names
joindirs - join component names in to a directory specification
setfstype - set the file system type
SYNOPSIS¶
use File::PathConvert qw(realpath abs2rel rel2abs setfstype splitpath
joinpath splitdirs joindirs $resolved);
$relpath = abs2rel($abspath);
$abspath = abs2rel($abspath, $base);
$abspath = rel2abs($relpath);
$abspath = rel2abs($relpath, $base);
$path = realpath($logpath) || die "resolution stopped at $resolved";
( $volume, $directory, $filename )= splitpath( $path ) ;
( $volume, $directory, $filename )= splitpath( $path, 'nofile' ) ;
$path= joinpath( $volume, $directory, $filename ) ;
@directories= splitdirs( $directory ) ;
$directory= joindirs( @directories ) ;
DESCRIPTION¶
File::PathConvert provides functions to convert between absolute and relative
paths, and from logical paths to physical paths on a variety of filesystems,
including the URL 'filesystem'.
Paths are decomposed internally in to volume, directory, and, sometimes filename
portions as appropriate to the operation and filesystem, then recombined. This
preserves the volume and filename portions so that they may be returned, and
prevents them from interfering with the path conversions.
Here are some examples of path decomposition. A '****' in a column indicates the
column is not used in "abs2rel" and "rel2abs" functions
for that filesystem type.
FS VOLUME Directory filename
======= ======================= =============== =============
URL http: /a/b/ c?query
http://fubar.com /a/b/ c?query
//p.d.q.com /a/b/c/ ?query
VMS Server::Volume: [a.b] c
Server"access spec":: [a.b] c
Volume: [a.b] c
Win32 A: \a\b\c ****
\\server\Volume \a\b\c ****
\\server\Volume \a/b/c ****
Unix **** \a\b\c ****
MacOS Volume:: a:b:c ****
Many more examples abound in the test.pl included with this module.
Only the VMS and URL filesystems indicate if the last name in a path is a
directory or file. For other filesystems, all non-volume names are assumed to
be directory names. For URLs, the last name in a path is assumed to be a
filename unless it ends in '/', '/.', or '/..'.
Other assumptions are made as well, especially MacOS and VMS. THESE MAY CHANGE
BASED ON PROGRAMMER FEEDBACK!
The conversion routines "abs2rel", "rel2abs", and
"realpath" are the main focus of this package. "splitpath"
and "joinpath" are provided to allow volume oriented filesystems
(almost anything non-unixian, actually) to be accomodated.
"splitdirs" and "joindirs" provide directory path grammar
parsing and encoding, which is especially useful for VMS.
- setfstype
- This is called automatically on module load to set the filesystem type
according to $^O. The user can call this later set the filesystem type
manually. If the name is not recognized, unix defaults are used. Names
matching /^URL$/i, /^VMS$/i, /^MacOS$/i, or /^(ms)?(win|dos)/32|nt)?$/i
yield the appropriate (hopefully) filesystem settings. These strings may
be generalized in the future.
Examples:
File::PathConvert::setfstype( 'url' ) ;
File::PathConvert::setfstype( 'Win32' ) ;
File::PathConvert::setfstype( 'HAL9000' ) ; # Results in Unix default
- abs2rel
- "abs2rel" converts an absolute path name to a relative path:
converting /1/2/3/a/b/c relative to /1/2/3 returns a/b/c
$relpath= abs2rel( $abspath ) ;
$relpath= abs2rel( $abspath, $base ) ;
If $abspath is already relative, it is returned unchanged. Otherwise the
relative path from $base to $abspath is returned. If $base is undefined
the current directory is used.
The volume and filename portions of $base are ignored if present. If
$abspath and $base are on different volumes, the volume from $abspath is
used.
No filesystem calls are made except for getting the current working
directory if $base is undefined, so symbolic links are not checked for or
resolved, and no check is done for existance.
Examples
# Unix
'a/b/c' == abs2rel( 'a/b/c', $anything )
'a/b/c' == abs2rel( '/1/2/3/a/b/c', '/1/2/3' )
# DOS
'a\\b/c' == abs2rel( 'a\\b/c', $anything )
'a\\b/c' == abs2rel( '/1\\2/3/a\\b/c', '/1/2/3' )
# URL
'http:a/b/c' == abs2rel( 'http:a/b/c', $anything )
'http:a/b/c' == abs2rel( 'http:/1/2/3/a/b/c',
'ftp://t.org/1/2/3/?z' )
'http:a/b/c?q' == abs2rel( 'http:/1/2/3/a/b/c/?q',
'ftp://t.org/1/2/3?z' )
'http://s.com/a/b/c?q' == abs2rel( 'http://s.com/1/2/3/a/b/c?q',
'ftp://t.org/1/2/3/?z')
- rel2abs
- "rel2abs" makes converts a relative path name to an absolute
path: converting a/b/c relative to /1/2/3 returns /1/2/3/a/b/c.
$abspath= rel2abs( $relpath ) ;
$abspath= rel2abs( $relpath, $base ) ;
If $relpath is already absolute, it is returned unchanged. Otherwise
$relpath is taken to be relative to $base and the resulting absolute path
is returned. If $base is not supplied, the current working directory is
used.
The volume portion of $relpath is ignored. The filename portion of $base is
also ignored. The volume from $base is returned if present. The filename
portion of $abspath is returned if present.
No filesystem calls are made except for getting the current working
directory if $base is undefined, so symbolic links are not checked for or
resolved, and no check is done for existance.
"rel2abs" will not return a path of the form "./file".
Examples
# Unix
'/a/b/c' == rel2abs( '/a/b/c', $anything )
'/1/2/3/a/b/c' == rel2abs( 'a/b/c', '/1/2/3' )
# DOS
'\\a\\b/c' == rel2abs( '\\a\\b/c', $anything )
'/1\\2/3\\a\\b/c' == rel2abs( 'a\\b/c', '/1\\2/3' )
'C:/1\\2/3\\a\\b/c' == rel2abs( 'D:a\\b/c', 'C:/1\\2/3' )
'\\\\s\\v/1\\2/3\\a\\b/c' == rel2abs( 'D:a\\b/c', '\\\\s\\v/1\\2/3' )
# URL
'http:/a/b/c?q' == rel2abs( 'http:/a/b/c?q', $anything )
'ftp://t.org/1/2/3/a/b/c?q'== rel2abs( 'http:a/b/c?q',
'ftp://t.org/1/2/3?z' )
- realpath
- "realpath" makes a canonicalized absolute pathname and resolves
all symbolic links, extra ``/'' characters, and references to /./ and /../
in the path. "realpath" resolves both absolute and relative
paths. It returns the resolved name on success, otherwise it returns undef
and sets the valiable $File::PathConvert::resolved to the pathname that
caused the problem.
All but the last component of the path must exist.
This implementation is based on 4.4BSD realpath(3). It is not tested
under other operating systems at this time.
If '/sys' is a symbolic link to '/usr/src/sys':
chdir('/usr');
'/usr/src/sys/kern' == realpath('../sys/kern');
'/usr/src/sys/kern' == realpath('/sys/kern');
- splitpath
- To be written...
- joinpath
- To be written...
Note that "joinpath( splitpath( $path ) )" usually yields path.
URLs with directory components ending in '/.' or '/..' will be fixed up to
end in '/./' and '/../'.
- splitdirs
- To be written...
- joindirs
BUGS¶
"realpath" is not fully multiplatform.
LIMITATIONS¶
- •
- In URLs, paths not ending in '/' are split such that the last name in the
path is a filename. This is not intuitive: many people use such URLs for
directories, and most servers send a redirect. This may cause programmers
using this package to code in bugs, it may be more pragmatic to always
assume all names are directory names. (Note that the query portion is
always part of the filename).
- •
- If the relative and base paths are on different volumes, no error is
returned. A silent, hopefully reasonable assumption is made.
- •
- No detection of unix style paths is done when other filesystems are
selected, like File::Basename does.
AUTHORS¶
Barrie Slaymaker <rbs@telerama.com> Shigio Yamaguchi
<shigio@wafu.netgate.net>