Find::File error: Invalid Top Directory

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • ezechiel
    New Member
    • Jul 2009
    • 53

    Find::File error: Invalid Top Directory

    hi, I have the following error on a win server:
    "Invalid Top Directory perl/lib/file/find.pm line 598

    Here's the code and I'll explain what I found until now:
    Code:
    #!/usr/bin/perl
    #
    use strict;
    use warnings;
    use File::Find;
    use MSDOS::Attrib qw(get_attribs set_attribs);
    
    (my $sec, my $min, my $hour, my $mday, my $mon, my $year, my $wday, my $yday, my $isdst)=localtime(time);
    $year = $year + 1900;           # $year 0 = real year 1900
    $mon = $mon + 1;                # $month 0 = January
    
    open(LOG, ">>./atd_files_$year-$mon-$mday\.txt")  or die "Can't open LOG: $!";
    print LOG ("\n*****************************************      NEW LAUNCH      *****************************************\n") or die "Can't write to LOG: $!";;
    printf LOG " Script started at:\n %4d-%02d-%02d %02d:%02d:%02d\n\n", $year,$mon,$mday,$hour,$min,$sec or die "Can't write to LOG: $!";
    
    my $homedir = "E:/test_dir";
    opendir (IMD, $homedir) or die "Couldn't find dir: IMD ($!)";
    my @thefiles= readdir(IMD);
    closedir(IMD);
    
    my @dirs;
    my $x=0;
    my $n = 0;
    
    foreach my $f (@thefiles){
            if (-d $f && $f !~ /^\.+/){
                    print "$f\n";
                    $dirs[$x]=$f;
                    $x++;
            }
    }
    
    #print "@dirs\n";
    find(\&wanted,  @dirs);
    
    sub wanted {
            if (/Project\.atd/){
                    my $attrib = get_attribs($File::Find::name);    
                    if ( $attrib =~ /.H.+/){            
                            $n++;
                            print "$File::Find::name\n";
                    }
            }
    }
    
    print ("\n\nTotal: $n files\n");
    
    print ("\a");
    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)=localtime(time);
    printf LOG "\n\n Script ended at:\n %4d-%02d-%02d %02d:%02d:%02d\n", $year+1900,$mon+1,$mday,$hour,$min,$sec or die "Can't write to LOG: $!";
    print LOG ("\n*****************************************      END LAUNCH      *****************************************\n") or die "Can't write to LOG: $!";
    So, the problem is the $homedir

    If I put "c:/blabla/blibli" as homedir, everything's ok.

    I tested the same script on a 2000pro with "c:/balbla" and "d:/blabla" everything's ok.

    But as soon as I put "E:/blabla" on the server, I got the error. Tested with different directories on E:, everytime I got an error. Not on C: or D:
    anyone got an idea? (is it a bad thing to edit with Windows Notepad?? I usually use Jext)

    Additional info:
    I also got the error with
    C:/ ; C:/ADMIN but not with C:/ADMIN/Analyst_Project atd_RightsHidde n

    I'm totally lost now!!
  • ezechiel
    New Member
    • Jul 2009
    • 53

    #2
    Another edit:
    on my local machine, where everything was working, it didn't worked with
    $homedir = "c:/" or eany other dir

    But it works with $homedir = "c:"

    Ok, well, I found another error in my script..
    ยจ$homedir is not working at all.. except if $homedir = the directory where the script is located, then the script functions.

    I also noticed a problem with Attrib..
    When I do a print $attrib after the getattrib, it displays nothing :s

    Comment

    • ezechiel
      New Member
      • Jul 2009
      • 53

      #3
      Another edit:
      But it works with $homedir = "c:" (well, it doesn't work properly but it doesn't give an error)

      I made a check: 15 target files, non hidden, all in log. Changed 1 to hidden.
      The log still lists 15 files.

      Could be two reasons:
      - attrib function is not working properly
      - the hidden attribute "H" is not in the second place as I saw on a site. But print $attrib should at least return something in stead of nothing..

      I'm completely lost now.. Just a beginner, so maybe I use Find::File and MSDOS::Atrib wrong?? If you need more info, don't hesitate!

      Comment

      • ezechiel
        New Member
        • Jul 2009
        • 53

        #4
        Update: (sorry about all those updates, but I continue searching)

        about attrib..: attrib is working properly
        it should be this:
        Code:
        my $myfile = "$homedir/$File::Find::name";
        my $attrib = get_attribs($myfile);
        so, the only question left is the File::Find error (as stated in the subject ^^ )

        Comment

        • RonB
          Recognized Expert Contributor
          • Jun 2009
          • 589

          #5
          Your posts are all over the map with what is or isn't working and no detail on what changes you made to the script between those posts.

          There are a number of problems with your script, but we'll start out with the"Invalid Top Directory" error.

          Which var is it working on when you receive this error and exactly what is the value of that var?

          Have you checked that the value it's referring to is actually a directory and that you have proper permissions to access that directory?

          Comment

          • ezechiel
            New Member
            • Jul 2009
            • 53

            #6
            (If I could edit my posts after an hour, there wouldn't be 4 posts ^^)

            So, every change I made has been detailed (changes of the $homedir var and changes of the Attrib part). I don't see what I forgot?

            The value I'm working on for $homedir is actually a directory (not a mapped drive) and permissions have been set. I posted what worked and what not, and the reason I think why (may be completely wrong). What I understood so far is that the script is only working if the script is in the same directory as $homedir.

            I never worked with File::Find before and it's a quite complete module and I just tried to understand what i needed to.

            If you need any other info, shoot. I'm glad that someone who has the knowledge can show me the way.

            Comment

            • RonB
              Recognized Expert Contributor
              • Jun 2009
              • 589

              #7
              Lets start at the beginning and clean up the script.

              Add this to the list of modules to load.
              Code:
              use POSIX qw(strftime);
              Change this:
              Code:
              (my $sec, my $min, my $hour, my $mday, my $mon, my $year, my $wday, my $yday, my $isdst)=localtime(time);
              $year = $year + 1900;           # $year 0 = real year 1900
              $mon = $mon + 1;                # $month 0 = January
               
              open(LOG, ">>./atd_files_$year-$mon-$mday\.txt")  or die "Can't open LOG: $!";
              print LOG ("\n*****************************************      NEW LAUNCH      *****************************************\n") or die "Can't write to LOG: $!";;
              printf LOG " Script started at:\n %4d-%02d-%02d %02d:%02d:%02d\n\n", $year,$mon,$mday,$hour,$min,$sec or die "Can't write to LOG: $!";
              To this:
              Code:
              my $logfile = strftime("atd_files_%Y-%m-%d.txt", localtime);
              open my $LOG, '>>', $logfile or die "Can't open <$logfile> $!";
              
              print $LOG "\n", '*' x 25, '      NEW LAUNCH      ', '*' x 25, "\n";
              Get rid of this unnecessary and inefficient code (which is the source of your problem).
              Code:
              opendir (IMD, $homedir) or die "Couldn't find dir: IMD ($!)";
              my @thefiles= readdir(IMD);
              closedir(IMD);
               
              my @dirs;
              my $x=0;
              my $n = 0;
               
              foreach my $f (@thefiles){
                      if (-d $f && $f !~ /^\.+/){
                              print "$f\n";
                              $dirs[$x]=$f;
                              $x++;
                      }
              }
              And change your call to the find function to this:
              Code:
              find(\&wanted,  $homedir);
              Change this:
              Code:
              ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)=localtime(time);
              printf LOG "\n\n Script ended at:\n %4d-%02d-%02d %02d:%02d:%02d\n", $year+1900,$mon+1,$mday,$hour,$min,$sec or die "Can't write to LOG: $!";
              print LOG ("\n*****************************************      END LAUNCH      *****************************************\n") or die "Can't write to LOG: $!";
              To this:
              Code:
              print $LOG strftime("\n\n Script ended at:\n %Y-%m-%d %H:%M:%S\n", localtime),
                         "\n", '*' x 25, '      END LAUNCH      ', '*' x 25, "\n";

              Comment

              • ezechiel
                New Member
                • Jul 2009
                • 53

                #8
                Well, all I have to say is .. thank you very much!!!!

                It works great and the script is 2x smaller.
                And POSIX strftime is easier to work with than the other one.

                And I also learned new things about logging and the print command!
                Thanks again!!! This is what I call a great answer to a problem ^^

                Comment

                • RonB
                  Recognized Expert Contributor
                  • Jun 2009
                  • 589

                  #9
                  Originally posted by ezechiel
                  Well, all I have to say is .. thank you very much!!!!

                  It works great and the script is 2x smaller.
                  And POSIX strftime is easier to work with than the other one.

                  And I also learned new things about logging and the print command!
                  Thanks again!!! This is what I call a great answer to a problem ^^
                  You're welcome.

                  The wanted sub could be cleaned up a little, but it's not too bad, so I left it alone.

                  But if you're interested, here's the cleaned up version.
                  Code:
                  sub wanted {
                      return unless /Project\.atd/;
                      
                      my $hidden = substr(get_attribs($File::Find::name), 1, 1);    
                  
                      if( $hidden eq 'H' ) {
                          $n++;
                          print "$File::Find::name\n";
                      }
                  }

                  Comment

                  • ezechiel
                    New Member
                    • Jul 2009
                    • 53

                    #10
                    ok, thanks for the info. I'll check out the substr() function.

                    About this one:
                    Code:
                    open my $LOG, '>>', $logfile or die "Can't open <$logfile> $!";
                    Don't I need to close the log at the end? I suppose it is like this?:
                    Code:
                    close $LOG;

                    Comment

                    • RonB
                      Recognized Expert Contributor
                      • Jun 2009
                      • 589

                      #11
                      Filehandles that use a lexical var instead of a bareword will automatically close when they go out of scope. However, it is best practice to explicitly close them when they are no longer needed.

                      Comment

                      • ezechiel
                        New Member
                        • Jul 2009
                        • 53

                        #12
                        ok,
                        thanks for all this precious info Ron ;)
                        It helped me a lot!

                        Comment

                        Working...