145 |
} |
} |
146 |
|
|
147 |
#ifdef S_ISLNK |
#ifdef S_ISLNK |
148 |
/* Use realpath() to resolve all sym links within 'fullpath'. */ |
/* Use realpath() to resolve all sym links within 'fullpath'. |
149 |
static __inline__ char *ult_softlink (char *fullpath) |
* Returns a newly allocated string. |
150 |
|
*/ |
151 |
|
static char *ult_softlink (const char *fullpath) |
152 |
{ |
{ |
153 |
char resolved_path[PATH_MAX]; |
char resolved_path[PATH_MAX]; |
154 |
|
|
165 |
if (debug) |
if (debug) |
166 |
fprintf (stderr, "ult_softlink: (%s)\n", resolved_path); |
fprintf (stderr, "ult_softlink: (%s)\n", resolved_path); |
167 |
|
|
168 |
return strcpy (fullpath, resolved_path); |
return xstrdup (resolved_path); |
169 |
} |
} |
170 |
#endif /* S_ISLNK */ |
#endif /* S_ISLNK */ |
171 |
|
|
172 |
/* test `buffer' to see if it contains a .so include, if so and it's not an |
/* Test 'buffer' to see if it contains a .so include. If so and it's not an |
173 |
absolute filename, copy it into `basename' at `rel' and return 1 */ |
* absolute filename, return newly allocated string whose contents are the |
174 |
static __inline__ int test_for_include (char *buffer, char *rel) |
* include. |
175 |
|
*/ |
176 |
|
static char *test_for_include (const char *buffer) |
177 |
{ |
{ |
178 |
/* strip out any leading whitespace (if any) */ |
/* strip out any leading whitespace (if any) */ |
179 |
while (isspace ((int) *buffer)) |
while (isspace ((int) *buffer)) |
198 |
* follow any absolute inclusions in our quest for the |
* follow any absolute inclusions in our quest for the |
199 |
* ultimate source file */ |
* ultimate source file */ |
200 |
if (*buffer != '/') { |
if (*buffer != '/') { |
201 |
/* copy filename into rel address */ |
const char *end = buffer; |
202 |
while (*buffer && !isspace ((int) *buffer)) |
while (*end && !isspace (*end)) |
203 |
*(rel++) = *(buffer++); |
++end; |
204 |
|
return xstrndup (buffer, end - buffer); |
|
*rel = '\0'; |
|
|
return 1; |
|
205 |
} |
} |
206 |
} |
} |
207 |
return 0; |
return NULL; |
208 |
} |
} |
209 |
|
|
210 |
/* |
/* |
217 |
*/ |
*/ |
218 |
char *ult_src (const char *name, const char *path, struct stat *buf, int flags) |
char *ult_src (const char *name, const char *path, struct stat *buf, int flags) |
219 |
{ |
{ |
220 |
static char basename[2048]; /* must be static */ |
static char *basename; /* must be static */ |
221 |
static short recurse; /* must be static */ |
static short recurse; /* must be static */ |
|
static char *relative; /* must be static */ |
|
222 |
|
|
223 |
/* initialise the function */ |
/* initialise the function */ |
224 |
|
|
225 |
/* as ult_softlink() & ult_hardlink() do all of their respective |
/* as ult_softlink() & ult_hardlink() do all of their respective |
226 |
* resolving in one call, only need to sort them out once |
* resolving in one call, only need to sort them out once |
227 |
*/ |
*/ |
228 |
|
|
229 |
if (recurse == 0) { |
if (recurse == 0) { |
230 |
struct stat new_buf; |
struct stat new_buf; |
231 |
(void) strcpy (basename, name); |
if (basename) |
232 |
relative = basename + strlen (path) + 1; |
free (basename); |
233 |
|
basename = xstrdup (name); |
234 |
|
|
235 |
if (debug) |
if (debug) |
236 |
fprintf (stderr, "\nult_src: File %s in mantree %s\n", |
fprintf (stderr, "\nult_src: File %s in mantree %s\n", |
249 |
#ifdef S_ISLNK |
#ifdef S_ISLNK |
250 |
/* Permit semi local (inter-tree) soft links */ |
/* Permit semi local (inter-tree) soft links */ |
251 |
if (flags & SOFT_LINK) { |
if (flags & SOFT_LINK) { |
252 |
if (S_ISLNK (buf->st_mode)) |
if (S_ISLNK (buf->st_mode)) { |
253 |
/* Is a symlink, resolve it. */ |
/* Is a symlink, resolve it. */ |
254 |
if (!ult_softlink (basename)) |
char *softlink = ult_softlink (basename); |
255 |
|
if (softlink) { |
256 |
|
free (basename); |
257 |
|
basename = softlink; |
258 |
|
} else |
259 |
return NULL; |
return NULL; |
260 |
|
} |
261 |
} |
} |
262 |
#endif /* S_ISLNK */ |
#endif /* S_ISLNK */ |
263 |
|
|
277 |
|
|
278 |
if (flags & SO_LINK) { |
if (flags & SO_LINK) { |
279 |
char buffer[1024], *bptr; |
char buffer[1024], *bptr; |
|
int val; |
|
280 |
FILE *fp; |
FILE *fp; |
281 |
#ifdef COMP_SRC |
#ifdef COMP_SRC |
282 |
struct compression *comp; |
struct compression *comp; |
301 |
free (comp->file); |
free (comp->file); |
302 |
if (!filename) |
if (!filename) |
303 |
return NULL; |
return NULL; |
304 |
(void) strcat (basename, "."); |
basename = strappend (basename, ".", comp->ext, |
305 |
(void) strcat (basename, comp->ext); |
NULL); |
306 |
drop_effective_privs (); |
drop_effective_privs (); |
307 |
fp = fopen (filename, "r"); |
fp = fopen (filename, "r"); |
308 |
regain_effective_privs (); |
regain_effective_privs (); |
329 |
fclose(fp); |
fclose(fp); |
330 |
|
|
331 |
if (buffer) { |
if (buffer) { |
332 |
/* Restore the original path from before |
char *include = test_for_include (buffer); |
333 |
* ult_softlink() etc., in case it went outside the |
if (include) { |
334 |
* mantree. |
char *ult; |
335 |
*/ |
|
336 |
char *basename_copy = xstrdup (basename); |
/* Restore the original path from before |
337 |
(void) strcpy (basename, path); |
* ult_softlink() etc., in case it went |
338 |
(void) strcat (basename, "/"); |
* outside the mantree. |
339 |
val = test_for_include (buffer, relative); |
*/ |
340 |
if (!val) |
free (basename); |
341 |
(void) strcpy (basename, basename_copy); |
basename = strappend (NULL, path, "/", include, |
342 |
free (basename_copy); |
NULL); |
343 |
} else |
free (include); |
344 |
val = EOF; |
|
345 |
|
if (debug) |
346 |
if (val == 1) { /* keep on looking... */ |
fprintf (stderr, |
347 |
char *ult; |
"ult_src: points to %s\n", |
348 |
|
basename); |
349 |
if (debug) |
|
350 |
fprintf (stderr, "ult_src: points to %s\n", |
recurse++; |
351 |
basename); |
ult = ult_src (basename, path, NULL, flags); |
352 |
|
recurse--; |
|
recurse++; |
|
|
ult = ult_src (basename, path, NULL, flags); |
|
|
recurse--; |
|
353 |
|
|
354 |
return ult; |
return ult; |
355 |
|
} |
356 |
} |
} |
357 |
} |
} |
358 |
|
|