home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume24
/
mkid2
/
part02
/
unsymlink.c
< prev
Wrap
C/C++ Source or Header
|
1991-10-09
|
3KB
|
86 lines
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
extern void cannoname();
/* unsymlink is a routine that resolves all symbolic links in
* a file name, transforming a name to the "actual" file name
* instead of the name in terms of symbolic links.
*
* If it can resolve all links and discover an actual file
* it returns a pointer to its argument string and transforms
* the argument in place to the actual name.
*
* If no such actual file exists, or for some reason the links
* cannot be resolved, it returns a NULL pointer and leaves the
* name alone.
*/
char *
unsymlink(n)
char * n;
{
char newname[MAXPATHLEN];
char partname[MAXPATHLEN];
char linkname[MAXPATHLEN];
char * s;
char * d;
char * lastcomp;
int linksize;
struct stat statb;
/* Just stat the file to automagically do all the symbolic
* link verification checks and make sure we have access to
* directories, etc.
*/
if (stat(n, &statb) != 0) return(NULL) ;
strcpy(newname, n);
/* Now loop, lstating each component to see if it is a symbolic
* link. For symbolic link components, use readlink() to get
* the real name, put the read link name in place of the
* last component, and start again.
*/
cannoname(newname) ;
s = &newname[0] ;
d = &partname[0] ;
if (*s == '/') {
*d++ = *s++ ;
}
lastcomp = d ;
for ( ; ; ) {
if ((*s == '/') || (*s == '\0')) {
/* we have a complete component name in partname, check it out */
*d = '\0' ;
if (lstat(partname, &statb) != 0) return(NULL) ;
if ((statb.st_mode & S_IFMT) == S_IFLNK) {
/* This much of name is a symbolic link, do a readlink
* and tack the bits and pieces together
*/
linksize = readlink(partname, linkname, MAXPATHLEN) ;
if (linksize < 0) return(NULL) ;
linkname[linksize] = '\0' ;
strcpy(lastcomp, linkname) ;
lastcomp += linksize ;
strcpy(lastcomp, s) ;
strcpy(newname, partname) ;
cannoname(newname) ;
s = &newname[0] ;
d = &partname[0] ;
if (*s == '/') {
*d++ = *s++ ;
}
lastcomp = d ;
} else {
/* Not a symlink, just keep scanning to next component */
if (*s == '\0') break ;
*d++ = *s++ ;
lastcomp = d ;
}
} else {
*d++ = *s++ ;
}
}
strcpy(n, newname) ;
return(n) ;
}