From: lwall@netlabs.com (Larry Wall)
Newsgroups: comp.lang.perl
Subject: Re: got a symlink checker/chaser for crontab?
Date: 27 Aug 92 06:34:17 GMT
Organization: NetLabs, Inc.

In article <17544@autodesk.COM> dansmith@Autodesk.COM (Daniel Smith) writes:
: 
: 	I often tie together filesystems with symlinks, so that
: something like /usr/local/src will contain links which point all
: over the place.  Every so often, I try to cd somewhere I haven't
: been for weeks, only to find that the link has "dried up".
: 
: 	Well... I basically want a script that will take
: "find / -type l -print" and check the links to see if they resolve.  It's
: something I'd run once a day out of crontab.  Rather than reinventing
: what must be a somewhat common wheel, I thought I'd ask here first.
: The script would produce a list of symlinks in need of updating/deletion,
: which presumably would get piped into mail.

Well, this isn't exactly it, but you might be able to hack it into what
you want.

Larry

#!/usr/bin/perl
'di';
'ig00';
#
# $Header: sl,v 1.1 90/08/11 13:51:00 lwall Locked $
#
# $Log:	sl,v $
# Revision 1.1  90/08/11  13:51:00  lwall
# Initial revision
# 

die "Usage: sl [filenames]\n" unless @ARGV;

$| = 1;
chop($cwd = `pwd`) || die "Can't find current directory: $!\n" if $#ARGV > 0;

print "\n";
foreach $name (@ARGV) {
    @indent = ();
    print "$name:\n";
    @path = split(m;/;, $name);
    if (@path && $path[0] eq '') {
	chdir '/';
	shift @path;
	print '/';
	$indent = 1;
    }
    while (@path) {
	$elem = shift @path;
	$new = readlink($elem);
	if (defined $new) {
	    print "$elem -> $new\n";
	    $new =~ s!^\./!!;
	    unshift(@path,split(m;/;, $new));
	    if (@path && $path[0] eq '') {
		chdir '/';
		shift @path;
		print '/';
		$indent = 1;
		@indents = ();
	    }
	    elsif (@path && @indents && $path[0] eq '..') {
		$indent = pop(@indents);
		chdir '..' || die "\n\nCan't chdir to ..: $!\n";;
		shift @path;
		print "\t" x ($indent / 8), ' ' x ($indent % 8);
	    }
	    else {
		print "\t" x ($indent / 8), ' ' x ($indent % 8);
	    }
	}
	else {
	    print $elem;
	    push(@indents,$indent);
	    $indent += length($elem) + 1;
	    if (@path) {
		print '/';
		chdir $elem || die "\n\nCan't chdir to $elem: $!\n";;
	    }
	}
    }
    print "\n\n";
    $indent = 0;
    chdir $cwd || die "Can't cd back: $!\n" if $cwd ne '';
}
##############################################################################

	# These next few lines are legal in both Perl and nroff.

.00;			# finish .ig
 
'di			\" finish diversion--previous line must be blank
.nr nl 0-1		\" fake up transition to first page again
.nr % 0			\" start at page 1
'; __END__ ############# From here on it's a standard manual page ############
.TH SL 1 "July 30, 1990"
.AT 3
.SH NAME
sl \- show translation of symbolic link to actual filename
.SH SYNOPSIS
.B sl [filenames]
.SH DESCRIPTION
.I Sl
traverses the pathnames supplied on the command line, and for each one,
tells you if it had to follow any symbolic links to find the actual filename.
Example:
.nf

	$ sl /usr/lib/libXw.a

	/usr/lib/libXw.a:
	/usr/lib/libXw.a -> /usr/lib/X11/libXw.a
	/usr/lib/X11 -> /X11/lib
	/X11 -> /usr/local/X11R4
	/usr/local/X11R4/lib/libXw.a

.fi
.SH ENVIRONMENT
No environment variables are used by
.I sl.
.SH FILES
None.
.SH AUTHOR
Larry Wall
.SH "SEE ALSO"
ls -l
.SH DIAGNOSTICS
Complains if it can't chdir to the directories it's trying to traverse.
.SH BUGS
.ex