home *** CD-ROM | disk | FTP | other *** search
- #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) ;
- }
-