10f7f3352SJulian Elischer.\" 20f7f3352SJulian Elischer.\" Copyright (c) 1997 Shigio Yamaguchi. All rights reserved. 30f7f3352SJulian Elischer.\" Copyright (c) 1999 Tama Communications Corporation. All rights reserved. 40f7f3352SJulian Elischer.\" 50f7f3352SJulian Elischer.\" Redistribution and use in source and binary forms, with or without 60f7f3352SJulian Elischer.\" modification, are permitted provided that the following conditions 70f7f3352SJulian Elischer.\" are met: 80f7f3352SJulian Elischer.\" 1. Redistributions of source code must retain the above copyright 90f7f3352SJulian Elischer.\" notice, this list of conditions and the following disclaimer. 100f7f3352SJulian Elischer.\" 2. Redistributions in binary form must reproduce the above copyright 110f7f3352SJulian Elischer.\" notice, this list of conditions and the following disclaimer in the 120f7f3352SJulian Elischer.\" documentation and/or other materials provided with the distribution. 130f7f3352SJulian Elischer.\" 140f7f3352SJulian Elischer.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 150f7f3352SJulian Elischer.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 160f7f3352SJulian Elischer.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 170f7f3352SJulian Elischer.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 180f7f3352SJulian Elischer.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 190f7f3352SJulian Elischer.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 200f7f3352SJulian Elischer.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 210f7f3352SJulian Elischer.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 220f7f3352SJulian Elischer.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 230f7f3352SJulian Elischer.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 240f7f3352SJulian Elischer.\" SUCH DAMAGE. 250f7f3352SJulian Elischer.\" 26948168c7SGordon Bergling.Dd August 7, 2022 270f7f3352SJulian Elischer.Dt ABS2REL 3 280f7f3352SJulian Elischer.Os 290f7f3352SJulian Elischer.Sh NAME 300f7f3352SJulian Elischer.Nm abs2rel 310f7f3352SJulian Elischer.Nd make a relative path name from an absolute path name 320f7f3352SJulian Elischer.Sh SYNOPSIS 330f7f3352SJulian Elischer.Ft "char *" 340f7f3352SJulian Elischer.Fn abs2rel "const char *path" "const char *base" "char *result" "size_t size" 350f7f3352SJulian Elischer.Sh DESCRIPTION 360f7f3352SJulian ElischerThe 370f7f3352SJulian Elischer.Fn abs2rel 380f7f3352SJulian Elischerfunction makes a relative path name from an absolute path name 390f7f3352SJulian Elischer.Fa path 400f7f3352SJulian Elischerbased on a directory 410f7f3352SJulian Elischer.Fa base 420f7f3352SJulian Elischerand copies the resulting path name into the memory referenced by 430f7f3352SJulian Elischer.Fa result . 440f7f3352SJulian ElischerThe 450f7f3352SJulian Elischer.Fa result 460f7f3352SJulian Elischerargument must refer to a buffer capable of storing at least 470f7f3352SJulian Elischer.Fa size 480f7f3352SJulian Elischercharacters. 490f7f3352SJulian Elischer 500f7f3352SJulian ElischerThe resulting path name may include symbolic links. 510f7f3352SJulian ElischerThe 520f7f3352SJulian Elischer.Fn abs2rel 530f7f3352SJulian Elischerfunction doesn't check whether or not any path exists. 540f7f3352SJulian Elischer.Sh "RETURN VALUES" 550f7f3352SJulian ElischerThe 560f7f3352SJulian Elischer.Fn abs2rel 570f7f3352SJulian Elischerfunction returns relative path name on success. 580f7f3352SJulian ElischerIf an error occurs, 590f7f3352SJulian Elischerit returns 600f7f3352SJulian Elischer.Dv NULL . 6109451711SGordon Bergling.Sh EXAMPLES 6209451711SGordon Bergling char result[MAXPATHLEN]; 6309451711SGordon Bergling char *path = abs2rel("/usr/src/sys", "/usr/local/lib", result, MAXPATHLEN); 6409451711SGordon Bergling 6509451711SGordon Berglingyields: 6609451711SGordon Bergling 6709451711SGordon Bergling path == "../../src/sys" 6809451711SGordon Bergling 6909451711SGordon BerglingSimilarly, 7009451711SGordon Bergling 7109451711SGordon Bergling path1 = abs2rel("/usr/src/sys", "/usr", result, MAXPATHLEN); 7209451711SGordon Bergling path2 = abs2rel("/usr/src/sys", "/usr/src/sys", result, MAXPATHLEN); 7309451711SGordon Bergling 7409451711SGordon Berglingyields: 7509451711SGordon Bergling 7609451711SGordon Bergling path1 == "src/sys" 7709451711SGordon Bergling path2 == "." 780f7f3352SJulian Elischer.Sh ERRORS 790f7f3352SJulian ElischerThe 800f7f3352SJulian Elischer.Fn abs2rel 810f7f3352SJulian Elischerfunction may fail and set the external variable 820f7f3352SJulian Elischer.Va errno 830f7f3352SJulian Elischerto indicate the error. 840f7f3352SJulian Elischer.Bl -tag -width Er 850f7f3352SJulian Elischer.It Bq Er EINVAL 860f7f3352SJulian ElischerThe 870f7f3352SJulian Elischer.Fa base 880f7f3352SJulian Elischerdirectory isn't an absolute path name or the 890f7f3352SJulian Elischer.Fa size 900f7f3352SJulian Elischerargument is zero. 910f7f3352SJulian Elischer.It Bq Er ERANGE 920f7f3352SJulian ElischerThe 930f7f3352SJulian Elischer.Fa size 940f7f3352SJulian Elischerargument is greater than zero but smaller than the length of the pathname plus 1. 950f7f3352SJulian Elischer 96*d21e322dSGraham Percival.El 9709451711SGordon Bergling.Sh SEE ALSO 9809451711SGordon Bergling.Xr rel2abs 3 9909451711SGordon Bergling.Sh AUTHORS 10009451711SGordon Bergling.An Shigio Yamaguchi (shigio@tamacom.com) 1010f7f3352SJulian Elischer.Sh BUGS 1020f7f3352SJulian ElischerIf the 1030f7f3352SJulian Elischer.Fa base 1040f7f3352SJulian Elischerdirectory includes symbolic links, 1050f7f3352SJulian Elischerthe 1060f7f3352SJulian Elischer.Fn abs2rel 1070f7f3352SJulian Elischerfunction produces the wrong path. 1080f7f3352SJulian ElischerFor example, if '/sys' is a symbolic link to '/usr/src/sys', 1090f7f3352SJulian Elischer 1100f7f3352SJulian Elischer char *path = abs2rel("/usr/local/lib", "/sys", result, MAXPATHLEN); 1110f7f3352SJulian Elischer 1120f7f3352SJulian Elischeryields: 1130f7f3352SJulian Elischer 1140f7f3352SJulian Elischer path == "../usr/local/lib" /* It's wrong!! */ 1150f7f3352SJulian Elischer 1160f7f3352SJulian ElischerYou should convert the base directory into a real path in advance. 1170f7f3352SJulian Elischer.Pp 1180f7f3352SJulian Elischer 1190f7f3352SJulian Elischer path = abs2rel("/sys/kern", realpath("/sys", resolvedname), result, MAXPATHLEN); 1200f7f3352SJulian Elischer 1210f7f3352SJulian Elischeryields: 1220f7f3352SJulian Elischer 1230f7f3352SJulian Elischer path == "../../../sys/kern" /* It's correct but ... */ 1240f7f3352SJulian Elischer 1253d265fceSGordon BerglingThat is correct, but a little redundant. 1263d265fceSGordon BerglingIf you wish get the simple answer 'kern', do the following. 1270f7f3352SJulian Elischer 1280f7f3352SJulian Elischer path = abs2rel(realpath("/sys/kern", r1), realpath("/sys", r2), 1290f7f3352SJulian Elischer result, MAXPATHLEN); 1300f7f3352SJulian Elischer 1310f7f3352SJulian ElischerThe 1320f7f3352SJulian Elischer.Fn realpath 1330f7f3352SJulian Elischerfunction assures correct result, but don't forget that 1340f7f3352SJulian Elischer.Fn realpath 1350f7f3352SJulian Elischerrequires that all but the last component of the path exist. 136