Concept99 has asked for the wisdom of the Perl Monks concerning the following question:

I have a script that will accept user directory paths as input, and then output the size of every user's folder. Everything was working fine until the script hit a user that had a folder with over 20 identical subfolders. The folder names were identical with 8 characters and in caps: "STUFFCOM". When the script hit this, it ended and reported the following: Can't cd to \\server\d$\dept\users\r_johnson/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM/STUFFCOM../../../../../../../../../../../../../../../../../../../../../.. at C:/Perl/lib/File/Find.pm line 535, <IN> line 1. I have figured a way around this, and that was to reduce the number of subfolders to 19. My question is why would I be receiving this error, and why does reducing the number of subfolders fix the problem? Here is the code for my program:

#!/usr/bin/perl use File::Find; use strict; use Time::localtime; use File::Spec; my $cur = File::Spec->curdir; my $up = File::Spec->updir; my $dirtot; my ($dir, @parts, $error, $starttime, $runtime, $endtime, $runmin, $ye +ar, $month, $day, $tm, $date,$rootdir,$userdir,$slash); $tm = localtime; $year = $tm->year+1900; $month = $tm->mon+1; $day = $tm->mday; $date = "$month-$day-$year"; $slash = "//"; #Opens the input and output files open(IN, "< websize_input.txt") or die("Couldn't open websize_input.tx +t\n"); open(OUT, "> websize_out.csv") or die("Couldn't open websize_output.cs +v\n"); #Separates the newline delimited rows chomp ( @parts = <IN> ); #Used to calculate how long the program took to run $starttime = (time); #Prints headings print OUT "Path,User,MB,Date,Error?\n"; #Displays total for subdirectories foreach my $start (@parts) { my @dirs = &find_subdirs($start); foreach my $dir (@dirs) { ($rootdir,$userdir) = split /$slash/,$dir; print "\tWalking $dir\n"; my $total = 0; find sub { $total += -s }, $dir; $dirtot = $dirtot + $total; #Used for determining tota +l directory size $total = ($total / 1024) / 1024; #Converts to MB $total = sprintf("%0.2f", $total); #Formats output to 2 de +cimals print OUT"$rootdir,$userdir,$total,$date,$!\n"; } $dirtot = ($dirtot / 1024) / 1024; #Converts to MB $dirtot = sprintf("%0.2f", $dirtot); #Formats total to 2 deci +mals print STDERR "$start: No subdirectories\n" unless @dirs; } print "\nOutput created."; sub find_subdirs { my $start = shift; unless(opendir(D, $start)) { warn "$start: $!\n"; next; } my @dirs = map { -d "$start/$_" && !-l "$start/$_" && $_ ne $cur && $_ ne $up ? "$start//$_" : () } readdir(D); closedir(D); @dirs; }


I'd appreciate any help you can provide!

Replies are listed 'Best First'.
Re: File::Find subdirectory limit?
by BrowserUk (Patriarch) on Jun 26, 2003 at 19:37 UTC

    This is almost certainly that you are hitting the limits of the Win32 apis. They have a hard coded limit on the size of a path/filename. On my NT box this is 241 characters.

    The actual path is fine being below this limit, but when you add all the /../s, it pushes it over the limit and the api just rejects it. At least it checks. MS have rather a bad history of not checking for buffer overruns:)

    The problem lies with the File::Find modules use of this code, join('/',('..') x ($CdLvl-$Level)) which then gets appended to the full path of the current place in the directory structure. I'm not quite sure why they do this instead of </code>$currentpath = substr( $current_path, 0, rindex( '/', ($CdLvl-$Level) ) );</code>?

    Isn't there a no-chdir option on File::Find? That would avoid the situation occuring maybe?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: File::Find subdirectory limit?
by tilly (Archbishop) on Jun 26, 2003 at 19:40 UTC
    Guessing time.

    Some system calls have an upper limits (hundreds to thousands of chars) on the length of the path that you can pass them. You normally never run into them, but it sounds like you might have in this case.