This project is to develop utilities which make conversion between an absolute path name and a relative path name.
Download: PathConvert.tar.gz

GitHub

What's New

2016/11/23
Pathconvert library was adopted by FreeBSD core (libpathconv).
2006/7/11
Removed bash script 'abs2rel' because it is not maintained well.
2005/12/19
Added LGPL version of C library.
2005/8/9
Mac OS X seems to use rel2abs.
2004/8/29
Replaced Makefile with more generic one and fixed README.
2004/2/9
A bug in rel2abs() was fixed.
2002/2/14
Abs2rel() function was adopted by GNU Global source code tagging system.
1999/2/15
File::PathConvert module was merged into File::Spec of Perl 5.005_55.
1999/2/3
Added File-PathConvert-0.85 written by Barrie Slaymaker.

Motive

There are two methods to specify a file or a directory in UNIX file system. One is 'absolute path' and the other is 'relative path'. We can select more suitable method among them but we don't have any standardized measure for converting them each other.

This project intends to make UNIX file system more useful by offering some converting tools between an absolute path and a relative path.

Result

This project's results are followings:

PathConvert library for C language

Two functions are available.

abs2rel(): Convert an absolute path into a relative path.

abs2rel(target, base directory, result buffer, buffer length)

char result[MAXPATHLEN];
abs2rel("/usr/src/sys", "/usr/local/lib", result, MAXPATHLEN);
printf("path1 = %s\n", result);
abs2rel("/usr/src/sys", "/usr", result, MAXPATHLEN);
printf("path2 = %s\n", result);
abs2rel("/usr/src/sys", "/usr/src/sys", result, MAXPATHLEN);
printf("path3 = %s\n", result);
(Result of above program)
path1 = ../../src/sys
path2 = src/sys
path3 = .
rel2abs(): Convert a relative path into an absolute path.

rel2abs(target, base directory, result buffer, buffer length)

char result[MAXPATHLEN];
rel2abs("../../src/sys", "/usr/local/lib", result, MAXPATHLEN);
printf("path1 = %s\n", result);
rel2abs("src/sys", "/usr", result, MAXPATHLEN);
printf("path2 = %s\n", result);
rel2abs(".", "/usr/src/sys", result, MAXPATHLEN);
printf("path3 = %s\n", result);
(Result of above program)
path1 = /usr/src/sys
path2 = /usr/src/sys
path3 = /usr/src/sys

Custom lndir command

Lndir duplicates a directory tree by making symbolic links to the original files. This command is derived from X11 and slightly modified to accept an absolute path name and generate relative symbolic links.

Execution image

% mkdir /tmp/sys_shadow
% lndir /usr/src/sys /tmp/sys_shadow
/usr/src/sys/compile:
/usr/src/sys/conf:
/usr/src/sys/ddb:
/usr/src/sys/dev:
	.
	.
	.
% cd /tmp/sys_shadow
% ls -lL Makefile
-rw-r--r--  1 root  wheel  190 Jun 14  1996 Makefile
% ls -l Makefile
lrwxr-xr-x  1 owner  wheel  26 Dec 29 14:18 Makefile -> ../../usr/src/sys/Makefile

The custom lndir generates relative symbolic links from an absolute path argument. Original version generates absolute symbolic links. Shadow tree constructed by relative symbolic links is useful because we can move it easily and we can mount it from other machine remotely.

Custom ln command

This is a modified version of ln(1). We added two options, -a(--absolute) and -r(--relative) to the original ln to make possible to specify the type of symbolic link.

It is convenient in the following case:

  • You want to make a relative symbolic link with an absolute path specification.
  • You want to make an absolute symbolic link with a relative path specification.

Ex1: Making a relative symbolic link by using an absolute path name.

% cd /home/owner
% ln -sfr /etc/hosts .
% ls -l hosts
lrwxr-xr-x  1 owner  users  15 Nov 21 15:36 hosts -> ../../etc/hosts

Ex2: Making a symbolic link in other than current directory

% cd /usr/src/sys
% ls -l kern/tty.c
-rw-r--r--  1 root  wheel  56525 Jul  3 09:27 kern/tty.c
% ln -sfr kern/tty.c /home/owner/tmp		# relative
% ls -l /home/owner/tmp/tty.c
lrwxrwxrwx  1 owner  users  31 Jul 13 13:28 /home/owner/tmp/tty.c -> ../../../usr/src/sys/kern/tty.c
% ln -sfa kern/tty.c /home/owner/tmp		# absolute
% ls -l /home/owner/tmp/tty.c
lrwxrwxrwx  1 owner  users  31 Jul 13 13:28 /home/owner/tmp/tty.c -> /usr/src/sys/kern/tty.c
% ln -sf kern/tty.c /home/owner/tmp		# no specification
% ls -l /home/owner/tmp/tty.c
lrwxrwxrwx  1 owner  users  10 Jul 13 18:08 /home/owner/tmp/tty.c -> kern/tty.c

In original ln(1), all done is copy the exact source path string into the link as-is. So, in the last example above, the symbolic link has a incorrect value.

Ex3. Making a symbolic link of non existent file.

% cd /usr/src/sys
% ls -l kern/noexist.c
ls: kern/noexist.c: No such file or directory
% ln -sr kern/noexist.c /home/owner/tmp
% ls -l /home/owner/tmp/noexist.c
lrwxrwxrwx  1 owner  users  36 Jul 13 17:53 /home/owner/tmp/noexist.c -> ../../../usr/src/sys/kern/noexist.c
(correct symbolic link though does not exist.)

It is not a bug but a specification to be able to create symbolic links of a file which does not exist. In some jobs, it is convenient to create only symbolic links before creating files which are linked by the symbolic links. The implementation of the -a and -r option follows this way.

Ex4: create a shadow tree using relative symbolic links

% cd /usr/src/sys
% set obj=/usr/obj`pwd`
% mkdir -p $obj
% find * -type d -exec mkdir $obj/'{}' ';'
% find * -type f -exec ln -sr '{}' $obj/'{}' ';'

This code does the same job as lndir above.

File::PathConvert module for perl5

Perl version of abs2rel() and rel2abs().

This module was merged into File::Spec module which is included by perl-5.6. Please see File::Spec module

Copyright 2024, Tama Communications Corporation.