#!perl -w use strict; # How far into directories should the program probe? my($LinkDirDepthLimit) = 15; main(); # =========================================================================== sub main { my($Count, @Results) = LinkDir("C:\\Windows\\Favorites"); my($Line); foreach $Line (@Results) { print $Line; } } # =========================================================================== # LinkDir # # Arguments: Directory name and current depth # Can omit depth, it's used internally for smart indenting. # # Returns: The number of links found and an array of HTML code # The HTML code can be just printed in a simple foreach loop # # LinkDir is recursive. (Yippee). It stops digging after $LinkDirDepthLimit levels. sub LinkDir($, $) { local *THISDIR; # This sucker is recursive, so scoping the directory pointer is key my($DirName, $Depth) = @_; if(!defined $Depth) { $Depth = 0; } my($FileName); my(@Lines); my($ChildLinks) = 0; my($Title) = ($DirName =~ /([^\\]+)$/o); if($Title eq "ActiveChannel") { # ACTIVE CHANNEL? EEEEEEW return 0, @Lines; } if($Depth > $LinkDirDepthLimit) { # This deep? I'm suspicious that something isn't cool. return 0, @Lines; } if(!opendir(THISDIR, $DirName)) { print STDERR "Unable to open directory '$DirName' because of $!\n"; return 0, @Lines; } my(@Files) = sort readdir(THISDIR); closedir(THISDIR); my(@FilesTry); my(@DirsTry); foreach $FileName (@Files) { if($FileName =~ /^\.\.?$/o) { next; } # Skip . and .. my($FullFileName) = $DirName."\\".$FileName; if(-d $FullFileName) { push @DirsTry, $FullFileName; } else { push @FilesTry, $FullFileName; } } foreach $FileName (@DirsTry) { my($SubChildLinks, @ChildLines) = LinkDir($FileName, $Depth + 1); push @Lines, @ChildLines; $ChildLinks += $SubChildLinks; } foreach $FileName (@FilesTry) { my($Line) = ProcessFile($FileName, $Depth + 1); if(defined $Line) { push @Lines, $Line; $ChildLinks++; } } my(@RetLines); if($ChildLinks != 0) { push @RetLines, Indenter($Depth)."

$Title

\n\n"; push @RetLines, Indenter($Depth)."
\n\n"; push @RetLines, @Lines; push @RetLines, Indenter($Depth)."
\n\n"; } return $ChildLinks, @RetLines; } # =========================================================================== # # ProcessFile # # Arguments: Filename (full!) to file to scan and depth in tree. # # Returns: A string of the URL found, or undef if none is found # # called by LinkDir sub ProcessFile($, $) { my($FileName, $Depth) = @_; my($Title) = ($FileName =~ /([^\\]+)\.url/o); if(!defined $Title) { return undef; } # No URL extension? Skip that. if(!open(FILE, $FileName)) { print STDERR "Unable to open file '$FileName' because of $!\n"; return undef; } my($Line); while($Line = ) { chomp $Line; my($URL) = ($Line =~ /^URL=(.+)$/o); if(!defined $URL) { next; } # Not this line? Skip if($URL =~ /^file:\/\/.:\\/) { next; } # Skip local hard drive links close(FILE); return Indenter($Depth)."
$Title\n\n"; } close(FILE); return undef; } # =========================================================================== # Indenter # # Arguments: a number # # Indenter returns an indent of spaces. sub Indenter($) { return " " x ($_[0] * 4); }