xref: /dflybsd-src/contrib/binutils-2.34/libiberty/make-relative-prefix.c (revision b52ef7118d1621abed722c5bbbd542210290ecef)
1*fae548d3Szrj /* Relative (relocatable) prefix support.
2*fae548d3Szrj    Copyright (C) 1987-2020 Free Software Foundation, Inc.
3*fae548d3Szrj 
4*fae548d3Szrj This file is part of libiberty.
5*fae548d3Szrj 
6*fae548d3Szrj GCC is free software; you can redistribute it and/or modify it under
7*fae548d3Szrj the terms of the GNU General Public License as published by the Free
8*fae548d3Szrj Software Foundation; either version 2, or (at your option) any later
9*fae548d3Szrj version.
10*fae548d3Szrj 
11*fae548d3Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*fae548d3Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*fae548d3Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*fae548d3Szrj for more details.
15*fae548d3Szrj 
16*fae548d3Szrj You should have received a copy of the GNU General Public License
17*fae548d3Szrj along with GCC; see the file COPYING.  If not, write to the Free
18*fae548d3Szrj Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19*fae548d3Szrj 02110-1301, USA.  */
20*fae548d3Szrj 
21*fae548d3Szrj /*
22*fae548d3Szrj 
23*fae548d3Szrj @deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, @
24*fae548d3Szrj   const char *@var{bin_prefix}, const char *@var{prefix})
25*fae548d3Szrj 
26*fae548d3Szrj Given three paths @var{progname}, @var{bin_prefix}, @var{prefix},
27*fae548d3Szrj return the path that is in the same position relative to
28*fae548d3Szrj @var{progname}'s directory as @var{prefix} is relative to
29*fae548d3Szrj @var{bin_prefix}.  That is, a string starting with the directory
30*fae548d3Szrj portion of @var{progname}, followed by a relative pathname of the
31*fae548d3Szrj difference between @var{bin_prefix} and @var{prefix}.
32*fae548d3Szrj 
33*fae548d3Szrj If @var{progname} does not contain any directory separators,
34*fae548d3Szrj @code{make_relative_prefix} will search @env{PATH} to find a program
35*fae548d3Szrj named @var{progname}.  Also, if @var{progname} is a symbolic link,
36*fae548d3Szrj the symbolic link will be resolved.
37*fae548d3Szrj 
38*fae548d3Szrj For example, if @var{bin_prefix} is @code{/alpha/beta/gamma/gcc/delta},
39*fae548d3Szrj @var{prefix} is @code{/alpha/beta/gamma/omega/}, and @var{progname} is
40*fae548d3Szrj @code{/red/green/blue/gcc}, then this function will return
41*fae548d3Szrj @code{/red/green/blue/../../omega/}.
42*fae548d3Szrj 
43*fae548d3Szrj The return value is normally allocated via @code{malloc}.  If no
44*fae548d3Szrj relative prefix can be found, return @code{NULL}.
45*fae548d3Szrj 
46*fae548d3Szrj @end deftypefn
47*fae548d3Szrj 
48*fae548d3Szrj */
49*fae548d3Szrj 
50*fae548d3Szrj #ifdef HAVE_CONFIG_H
51*fae548d3Szrj #include "config.h"
52*fae548d3Szrj #endif
53*fae548d3Szrj 
54*fae548d3Szrj #ifdef HAVE_STDLIB_H
55*fae548d3Szrj #include <stdlib.h>
56*fae548d3Szrj #endif
57*fae548d3Szrj #ifdef HAVE_UNISTD_H
58*fae548d3Szrj #include <unistd.h>
59*fae548d3Szrj #endif
60*fae548d3Szrj #ifdef HAVE_SYS_STAT_H
61*fae548d3Szrj #include <sys/stat.h>
62*fae548d3Szrj #endif
63*fae548d3Szrj 
64*fae548d3Szrj #include <string.h>
65*fae548d3Szrj 
66*fae548d3Szrj #include "ansidecl.h"
67*fae548d3Szrj #include "libiberty.h"
68*fae548d3Szrj 
69*fae548d3Szrj #ifndef R_OK
70*fae548d3Szrj #define R_OK 4
71*fae548d3Szrj #define W_OK 2
72*fae548d3Szrj #define X_OK 1
73*fae548d3Szrj #endif
74*fae548d3Szrj 
75*fae548d3Szrj #ifndef DIR_SEPARATOR
76*fae548d3Szrj #  define DIR_SEPARATOR '/'
77*fae548d3Szrj #endif
78*fae548d3Szrj 
79*fae548d3Szrj #if defined (_WIN32) || defined (__MSDOS__) \
80*fae548d3Szrj     || defined (__DJGPP__) || defined (__OS2__)
81*fae548d3Szrj #  define HAVE_DOS_BASED_FILE_SYSTEM
82*fae548d3Szrj #  define HAVE_HOST_EXECUTABLE_SUFFIX
83*fae548d3Szrj #  define HOST_EXECUTABLE_SUFFIX ".exe"
84*fae548d3Szrj #  ifndef DIR_SEPARATOR_2
85*fae548d3Szrj #    define DIR_SEPARATOR_2 '\\'
86*fae548d3Szrj #  endif
87*fae548d3Szrj #  define PATH_SEPARATOR ';'
88*fae548d3Szrj #else
89*fae548d3Szrj #  define PATH_SEPARATOR ':'
90*fae548d3Szrj #endif
91*fae548d3Szrj 
92*fae548d3Szrj #ifndef DIR_SEPARATOR_2
93*fae548d3Szrj #  define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
94*fae548d3Szrj #else
95*fae548d3Szrj #  define IS_DIR_SEPARATOR(ch) \
96*fae548d3Szrj 	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
97*fae548d3Szrj #endif
98*fae548d3Szrj 
99*fae548d3Szrj #define DIR_UP ".."
100*fae548d3Szrj 
101*fae548d3Szrj static char *save_string (const char *, int);
102*fae548d3Szrj static char **split_directories	(const char *, int *);
103*fae548d3Szrj static void free_split_directories (char **);
104*fae548d3Szrj 
105*fae548d3Szrj static char *
save_string(const char * s,int len)106*fae548d3Szrj save_string (const char *s, int len)
107*fae548d3Szrj {
108*fae548d3Szrj   char *result = (char *) malloc (len + 1);
109*fae548d3Szrj 
110*fae548d3Szrj   memcpy (result, s, len);
111*fae548d3Szrj   result[len] = 0;
112*fae548d3Szrj   return result;
113*fae548d3Szrj }
114*fae548d3Szrj 
115*fae548d3Szrj /* Split a filename into component directories.  */
116*fae548d3Szrj 
117*fae548d3Szrj static char **
split_directories(const char * name,int * ptr_num_dirs)118*fae548d3Szrj split_directories (const char *name, int *ptr_num_dirs)
119*fae548d3Szrj {
120*fae548d3Szrj   int num_dirs = 0;
121*fae548d3Szrj   char **dirs;
122*fae548d3Szrj   const char *p, *q;
123*fae548d3Szrj   int ch;
124*fae548d3Szrj 
125*fae548d3Szrj   if (!*name)
126*fae548d3Szrj     return NULL;
127*fae548d3Szrj 
128*fae548d3Szrj   /* Count the number of directories.  Special case MSDOS disk names as part
129*fae548d3Szrj      of the initial directory.  */
130*fae548d3Szrj   p = name;
131*fae548d3Szrj #ifdef HAVE_DOS_BASED_FILE_SYSTEM
132*fae548d3Szrj   if (name[1] == ':' && IS_DIR_SEPARATOR (name[2]))
133*fae548d3Szrj     {
134*fae548d3Szrj       p += 3;
135*fae548d3Szrj       num_dirs++;
136*fae548d3Szrj     }
137*fae548d3Szrj #endif /* HAVE_DOS_BASED_FILE_SYSTEM */
138*fae548d3Szrj 
139*fae548d3Szrj   while ((ch = *p++) != '\0')
140*fae548d3Szrj     {
141*fae548d3Szrj       if (IS_DIR_SEPARATOR (ch))
142*fae548d3Szrj 	{
143*fae548d3Szrj 	  num_dirs++;
144*fae548d3Szrj 	  while (IS_DIR_SEPARATOR (*p))
145*fae548d3Szrj 	    p++;
146*fae548d3Szrj 	}
147*fae548d3Szrj     }
148*fae548d3Szrj 
149*fae548d3Szrj   dirs = (char **) malloc (sizeof (char *) * (num_dirs + 2));
150*fae548d3Szrj   if (dirs == NULL)
151*fae548d3Szrj     return NULL;
152*fae548d3Szrj 
153*fae548d3Szrj   /* Now copy the directory parts.  */
154*fae548d3Szrj   num_dirs = 0;
155*fae548d3Szrj   p = name;
156*fae548d3Szrj #ifdef HAVE_DOS_BASED_FILE_SYSTEM
157*fae548d3Szrj   if (name[1] == ':' && IS_DIR_SEPARATOR (name[2]))
158*fae548d3Szrj     {
159*fae548d3Szrj       dirs[num_dirs++] = save_string (p, 3);
160*fae548d3Szrj       if (dirs[num_dirs - 1] == NULL)
161*fae548d3Szrj 	{
162*fae548d3Szrj 	  free (dirs);
163*fae548d3Szrj 	  return NULL;
164*fae548d3Szrj 	}
165*fae548d3Szrj       p += 3;
166*fae548d3Szrj     }
167*fae548d3Szrj #endif /* HAVE_DOS_BASED_FILE_SYSTEM */
168*fae548d3Szrj 
169*fae548d3Szrj   q = p;
170*fae548d3Szrj   while ((ch = *p++) != '\0')
171*fae548d3Szrj     {
172*fae548d3Szrj       if (IS_DIR_SEPARATOR (ch))
173*fae548d3Szrj 	{
174*fae548d3Szrj 	  while (IS_DIR_SEPARATOR (*p))
175*fae548d3Szrj 	    p++;
176*fae548d3Szrj 
177*fae548d3Szrj 	  dirs[num_dirs++] = save_string (q, p - q);
178*fae548d3Szrj 	  if (dirs[num_dirs - 1] == NULL)
179*fae548d3Szrj 	    {
180*fae548d3Szrj 	      dirs[num_dirs] = NULL;
181*fae548d3Szrj 	      free_split_directories (dirs);
182*fae548d3Szrj 	      return NULL;
183*fae548d3Szrj 	    }
184*fae548d3Szrj 	  q = p;
185*fae548d3Szrj 	}
186*fae548d3Szrj     }
187*fae548d3Szrj 
188*fae548d3Szrj   if (p - 1 - q > 0)
189*fae548d3Szrj     dirs[num_dirs++] = save_string (q, p - 1 - q);
190*fae548d3Szrj   dirs[num_dirs] = NULL;
191*fae548d3Szrj 
192*fae548d3Szrj   if (dirs[num_dirs - 1] == NULL)
193*fae548d3Szrj     {
194*fae548d3Szrj       free_split_directories (dirs);
195*fae548d3Szrj       return NULL;
196*fae548d3Szrj     }
197*fae548d3Szrj 
198*fae548d3Szrj   if (ptr_num_dirs)
199*fae548d3Szrj     *ptr_num_dirs = num_dirs;
200*fae548d3Szrj   return dirs;
201*fae548d3Szrj }
202*fae548d3Szrj 
203*fae548d3Szrj /* Release storage held by split directories.  */
204*fae548d3Szrj 
205*fae548d3Szrj static void
free_split_directories(char ** dirs)206*fae548d3Szrj free_split_directories (char **dirs)
207*fae548d3Szrj {
208*fae548d3Szrj   int i = 0;
209*fae548d3Szrj 
210*fae548d3Szrj   if (dirs != NULL)
211*fae548d3Szrj     {
212*fae548d3Szrj       while (dirs[i] != NULL)
213*fae548d3Szrj 	free (dirs[i++]);
214*fae548d3Szrj 
215*fae548d3Szrj       free ((char *) dirs);
216*fae548d3Szrj     }
217*fae548d3Szrj }
218*fae548d3Szrj 
219*fae548d3Szrj /* Given three strings PROGNAME, BIN_PREFIX, PREFIX, return a string that gets
220*fae548d3Szrj    to PREFIX starting with the directory portion of PROGNAME and a relative
221*fae548d3Szrj    pathname of the difference between BIN_PREFIX and PREFIX.
222*fae548d3Szrj 
223*fae548d3Szrj    For example, if BIN_PREFIX is /alpha/beta/gamma/gcc/delta, PREFIX is
224*fae548d3Szrj    /alpha/beta/gamma/omega/, and PROGNAME is /red/green/blue/gcc, then this
225*fae548d3Szrj    function will return /red/green/blue/../../omega/.
226*fae548d3Szrj 
227*fae548d3Szrj    If no relative prefix can be found, return NULL.  */
228*fae548d3Szrj 
229*fae548d3Szrj static char *
make_relative_prefix_1(const char * progname,const char * bin_prefix,const char * prefix,const int resolve_links)230*fae548d3Szrj make_relative_prefix_1 (const char *progname, const char *bin_prefix,
231*fae548d3Szrj 			const char *prefix, const int resolve_links)
232*fae548d3Szrj {
233*fae548d3Szrj   char **prog_dirs = NULL, **bin_dirs = NULL, **prefix_dirs = NULL;
234*fae548d3Szrj   int prog_num, bin_num, prefix_num;
235*fae548d3Szrj   int i, n, common;
236*fae548d3Szrj   int needed_len;
237*fae548d3Szrj   char *ret = NULL, *ptr, *full_progname;
238*fae548d3Szrj   char *alloc_ptr = NULL;
239*fae548d3Szrj 
240*fae548d3Szrj   if (progname == NULL || bin_prefix == NULL || prefix == NULL)
241*fae548d3Szrj     return NULL;
242*fae548d3Szrj 
243*fae548d3Szrj   /* If there is no full pathname, try to find the program by checking in each
244*fae548d3Szrj      of the directories specified in the PATH environment variable.  */
245*fae548d3Szrj   if (lbasename (progname) == progname)
246*fae548d3Szrj     {
247*fae548d3Szrj       char *temp;
248*fae548d3Szrj 
249*fae548d3Szrj       temp = getenv ("PATH");
250*fae548d3Szrj       if (temp)
251*fae548d3Szrj 	{
252*fae548d3Szrj 	  char *startp, *endp, *nstore;
253*fae548d3Szrj 	  size_t prefixlen = strlen (temp) + 1;
254*fae548d3Szrj 	  size_t len;
255*fae548d3Szrj 	  if (prefixlen < 2)
256*fae548d3Szrj 	    prefixlen = 2;
257*fae548d3Szrj 
258*fae548d3Szrj 	  len = prefixlen + strlen (progname) + 1;
259*fae548d3Szrj #ifdef HAVE_HOST_EXECUTABLE_SUFFIX
260*fae548d3Szrj 	  len += strlen (HOST_EXECUTABLE_SUFFIX);
261*fae548d3Szrj #endif
262*fae548d3Szrj 	  if (len < MAX_ALLOCA_SIZE)
263*fae548d3Szrj 	    nstore = (char *) alloca (len);
264*fae548d3Szrj 	  else
265*fae548d3Szrj 	    alloc_ptr = nstore = (char *) malloc (len);
266*fae548d3Szrj 
267*fae548d3Szrj 	  startp = endp = temp;
268*fae548d3Szrj 	  while (1)
269*fae548d3Szrj 	    {
270*fae548d3Szrj 	      if (*endp == PATH_SEPARATOR || *endp == 0)
271*fae548d3Szrj 		{
272*fae548d3Szrj 		  if (endp == startp)
273*fae548d3Szrj 		    {
274*fae548d3Szrj 		      nstore[0] = '.';
275*fae548d3Szrj 		      nstore[1] = DIR_SEPARATOR;
276*fae548d3Szrj 		      nstore[2] = '\0';
277*fae548d3Szrj 		    }
278*fae548d3Szrj 		  else
279*fae548d3Szrj 		    {
280*fae548d3Szrj 		      memcpy (nstore, startp, endp - startp);
281*fae548d3Szrj 		      if (! IS_DIR_SEPARATOR (endp[-1]))
282*fae548d3Szrj 			{
283*fae548d3Szrj 			  nstore[endp - startp] = DIR_SEPARATOR;
284*fae548d3Szrj 			  nstore[endp - startp + 1] = 0;
285*fae548d3Szrj 			}
286*fae548d3Szrj 		      else
287*fae548d3Szrj 			nstore[endp - startp] = 0;
288*fae548d3Szrj 		    }
289*fae548d3Szrj 		  strcat (nstore, progname);
290*fae548d3Szrj 		  if (! access (nstore, X_OK)
291*fae548d3Szrj #ifdef HAVE_HOST_EXECUTABLE_SUFFIX
292*fae548d3Szrj                       || ! access (strcat (nstore, HOST_EXECUTABLE_SUFFIX), X_OK)
293*fae548d3Szrj #endif
294*fae548d3Szrj 		      )
295*fae548d3Szrj 		    {
296*fae548d3Szrj #if defined (HAVE_SYS_STAT_H) && defined (S_ISREG)
297*fae548d3Szrj 		      struct stat st;
298*fae548d3Szrj 		      if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode))
299*fae548d3Szrj #endif
300*fae548d3Szrj 			{
301*fae548d3Szrj 			  progname = nstore;
302*fae548d3Szrj 			  break;
303*fae548d3Szrj 			}
304*fae548d3Szrj 		    }
305*fae548d3Szrj 
306*fae548d3Szrj 		  if (*endp == 0)
307*fae548d3Szrj 		    break;
308*fae548d3Szrj 		  endp = startp = endp + 1;
309*fae548d3Szrj 		}
310*fae548d3Szrj 	      else
311*fae548d3Szrj 		endp++;
312*fae548d3Szrj 	    }
313*fae548d3Szrj 	}
314*fae548d3Szrj     }
315*fae548d3Szrj 
316*fae548d3Szrj   if (resolve_links)
317*fae548d3Szrj     full_progname = lrealpath (progname);
318*fae548d3Szrj   else
319*fae548d3Szrj     full_progname = strdup (progname);
320*fae548d3Szrj   if (full_progname == NULL)
321*fae548d3Szrj     goto bailout;
322*fae548d3Szrj 
323*fae548d3Szrj   prog_dirs = split_directories (full_progname, &prog_num);
324*fae548d3Szrj   free (full_progname);
325*fae548d3Szrj   if (prog_dirs == NULL)
326*fae548d3Szrj     goto bailout;
327*fae548d3Szrj 
328*fae548d3Szrj   bin_dirs = split_directories (bin_prefix, &bin_num);
329*fae548d3Szrj   if (bin_dirs == NULL)
330*fae548d3Szrj     goto bailout;
331*fae548d3Szrj 
332*fae548d3Szrj   /* Remove the program name from comparison of directory names.  */
333*fae548d3Szrj   prog_num--;
334*fae548d3Szrj 
335*fae548d3Szrj   /* If we are still installed in the standard location, we don't need to
336*fae548d3Szrj      specify relative directories.  Also, if argv[0] still doesn't contain
337*fae548d3Szrj      any directory specifiers after the search above, then there is not much
338*fae548d3Szrj      we can do.  */
339*fae548d3Szrj   if (prog_num == bin_num)
340*fae548d3Szrj     {
341*fae548d3Szrj       for (i = 0; i < bin_num; i++)
342*fae548d3Szrj 	{
343*fae548d3Szrj 	  if (strcmp (prog_dirs[i], bin_dirs[i]) != 0)
344*fae548d3Szrj 	    break;
345*fae548d3Szrj 	}
346*fae548d3Szrj 
347*fae548d3Szrj       if (prog_num <= 0 || i == bin_num)
348*fae548d3Szrj 	goto bailout;
349*fae548d3Szrj     }
350*fae548d3Szrj 
351*fae548d3Szrj   prefix_dirs = split_directories (prefix, &prefix_num);
352*fae548d3Szrj   if (prefix_dirs == NULL)
353*fae548d3Szrj     goto bailout;
354*fae548d3Szrj 
355*fae548d3Szrj   /* Find how many directories are in common between bin_prefix & prefix.  */
356*fae548d3Szrj   n = (prefix_num < bin_num) ? prefix_num : bin_num;
357*fae548d3Szrj   for (common = 0; common < n; common++)
358*fae548d3Szrj     {
359*fae548d3Szrj       if (strcmp (bin_dirs[common], prefix_dirs[common]) != 0)
360*fae548d3Szrj 	break;
361*fae548d3Szrj     }
362*fae548d3Szrj 
363*fae548d3Szrj   /* If there are no common directories, there can be no relative prefix.  */
364*fae548d3Szrj   if (common == 0)
365*fae548d3Szrj     goto bailout;
366*fae548d3Szrj 
367*fae548d3Szrj   /* Two passes: first figure out the size of the result string, and
368*fae548d3Szrj      then construct it.  */
369*fae548d3Szrj   needed_len = 0;
370*fae548d3Szrj   for (i = 0; i < prog_num; i++)
371*fae548d3Szrj     needed_len += strlen (prog_dirs[i]);
372*fae548d3Szrj   needed_len += sizeof (DIR_UP) * (bin_num - common);
373*fae548d3Szrj   for (i = common; i < prefix_num; i++)
374*fae548d3Szrj     needed_len += strlen (prefix_dirs[i]);
375*fae548d3Szrj   needed_len += 1; /* Trailing NUL.  */
376*fae548d3Szrj 
377*fae548d3Szrj   ret = (char *) malloc (needed_len);
378*fae548d3Szrj   if (ret == NULL)
379*fae548d3Szrj     goto bailout;
380*fae548d3Szrj 
381*fae548d3Szrj   /* Build up the pathnames in argv[0].  */
382*fae548d3Szrj   *ret = '\0';
383*fae548d3Szrj   for (i = 0; i < prog_num; i++)
384*fae548d3Szrj     strcat (ret, prog_dirs[i]);
385*fae548d3Szrj 
386*fae548d3Szrj   /* Now build up the ..'s.  */
387*fae548d3Szrj   ptr = ret + strlen(ret);
388*fae548d3Szrj   for (i = common; i < bin_num; i++)
389*fae548d3Szrj     {
390*fae548d3Szrj       strcpy (ptr, DIR_UP);
391*fae548d3Szrj       ptr += sizeof (DIR_UP) - 1;
392*fae548d3Szrj       *(ptr++) = DIR_SEPARATOR;
393*fae548d3Szrj     }
394*fae548d3Szrj   *ptr = '\0';
395*fae548d3Szrj 
396*fae548d3Szrj   /* Put in directories to move over to prefix.  */
397*fae548d3Szrj   for (i = common; i < prefix_num; i++)
398*fae548d3Szrj     strcat (ret, prefix_dirs[i]);
399*fae548d3Szrj 
400*fae548d3Szrj  bailout:
401*fae548d3Szrj   free_split_directories (prog_dirs);
402*fae548d3Szrj   free_split_directories (bin_dirs);
403*fae548d3Szrj   free_split_directories (prefix_dirs);
404*fae548d3Szrj   free (alloc_ptr);
405*fae548d3Szrj 
406*fae548d3Szrj   return ret;
407*fae548d3Szrj }
408*fae548d3Szrj 
409*fae548d3Szrj 
410*fae548d3Szrj /* Do the full job, including symlink resolution.
411*fae548d3Szrj    This path will find files installed in the same place as the
412*fae548d3Szrj    program even when a soft link has been made to the program
413*fae548d3Szrj    from somwhere else. */
414*fae548d3Szrj 
415*fae548d3Szrj char *
make_relative_prefix(const char * progname,const char * bin_prefix,const char * prefix)416*fae548d3Szrj make_relative_prefix (const char *progname, const char *bin_prefix,
417*fae548d3Szrj 		      const char *prefix)
418*fae548d3Szrj {
419*fae548d3Szrj   return make_relative_prefix_1 (progname, bin_prefix, prefix, 1);
420*fae548d3Szrj }
421*fae548d3Szrj 
422*fae548d3Szrj /* Make the relative pathname without attempting to resolve any links.
423*fae548d3Szrj    '..' etc may also be left in the pathname.
424*fae548d3Szrj    This will find the files the user meant the program to find if the
425*fae548d3Szrj    installation is patched together with soft links. */
426*fae548d3Szrj 
427*fae548d3Szrj char *
make_relative_prefix_ignore_links(const char * progname,const char * bin_prefix,const char * prefix)428*fae548d3Szrj make_relative_prefix_ignore_links (const char *progname,
429*fae548d3Szrj 				   const char *bin_prefix,
430*fae548d3Szrj 				   const char *prefix)
431*fae548d3Szrj {
432*fae548d3Szrj   return make_relative_prefix_1 (progname, bin_prefix, prefix, 0);
433*fae548d3Szrj }
434*fae548d3Szrj 
435