I'm not a great coder. I can usually get things done by using a combination of perl & unix utils, but I'm trying to do a project to help teach myself more. The part I'm working on now is stepping through the filesystem, starting at / listing the directory, and for each item, testing if its a directory or a file, if it's a file it does a stat() and if it's a directory, it lists it and does the same process over again.

The problem is, instead of listing the subdirectories, it combines the parents list with the childs.

For example: listing root gives "bin, boot ... var" instead of listing /bin/ it tries to list /bin/bin, /bin/boot ... /bin/var/

I've been looking at this for hours, and every time i think I make progress I end up going two steps back.

I'm sure the problem will be obvious to someone more versed than I am, and I would appreciate the help. I haven't cleaned this up too much, but if you've got any comments on general coding style, etc. please let me know, I'm here to learn, I don't care if I come off like an idiot.

thanks in advance,
Nick

#! /usr/bin/perl use Digest::MD5 qw(md5 md5_hex md5_base64); use strict; use diagnostics; use warnings; our $debug = 0; sub dir { print "----------------- dir($_[0]) -----------------\n"; if ( !defined( $_[0] ) ) { die("Nothing passed to the dir function\n"); } my $path = $_[0]; foreach my $file ( lsdir("/") ) { #--------------------------------------------------------- # Step through the results of the lsdir # and determine if it is a) a directory # or b) a file. For each one, run it's # respective function. #--------------------------------------------------------- print "$file\n" if ( 0 == $debug ); #my $holder = "$path/$file/"; #print "HOLDER:\t$holder\n" if ( 0 == $debug ); my $isdir_result = isdir("$path/$file") if ( 0 == $debug ); print "ISDIR RESULTS:\t$isdir_result\n" if ( 0 == $debug ); if ( 0 == isdir("$path/$file") ) { print "Dir:\t/$path/$file/\n"; if ( '/' eq $path ) { # if it's the root directory, just use the file print "$file is a directory.\n" if ( 0 == $debug ); print "instance 1: dir($file)\n"; dir("/$file"); } else { #otherwise, just use the path print "$file is a file.\n" if ( 0 == $debug ); print "instance 2: dir($file)\n"; if ( $file !~ m/^\// ){ $file = "/" . $file; } dir($path); } } elsif ( 1 == isdir("$path/$file") ) { print "File:\t/$file\n"; my %file_info = file("/$file"); if ( 0 == $debug ) { foreach my $key ( keys %file_info ) { } } } } } sub file { print "o0o0o0o0o0o file($_[0]) o0o0o0o0o0o\n"; my $file = $_[0]; my %attrib; $attrib{name} = $file; # stat file ( $attrib{dev}, $attrib{ino}, $attrib{mode}, $attrib{nlink}, $attrib{uid}, $attrib{gid}, $attrib{rdev}, $attrib{size}, $attrib{atime}, $attrib{mtime}, $attrib{ctime}, $attrib{blksize}, $attrib{blocks} ) = stat($file); # compute md5 open( FILE, $file ) or print "Couldn't open $file!"; if ( -e $file ) { binmode(FILE); my $md5 = Digest::MD5->new; while (<FILE>) { $md5->add($_); } close(FILE); $attrib{md5} = $md5->b64digest; } else { print "What the hell.... $file doesn't exist?\n"; } # give it back return (%attrib); } sub isdir { print "/\/\/\/\/\/\ isdir() /\/\/\/\/\/\ \n"; print "isdir($_[0])\n"; my $file = $_[0]; if ( -d "$file" ) { print "ISDIR = YES\n" if ( 0 == $debug ); return(0); } else { print "ISDIR = NO\n" if ( 0 == $debug ); return(1); } } sub lsdir { print "************ lsdir($_[0]) **************\n"; my $dir = $_[0]; my @files; opendir( DIRHANDLE, "$dir" ) || die "Cannot opendir /some/path +: $!"; foreach my $file ( sort readdir(DIRHANDLE) ) { push( @files, $file ) unless ( $file =~ m/^(\.){1,2}$/ ); print $file, "\n" if ( 2 == $debug ); } return @files; } my $path = "/"; print $path; dir("$path"); #|| die( "Couldn't run dir($path)");
Output:

/----------------- dir(/) ----------------- ************ lsdir(/) ************** bin ////// isdir() ////// isdir(//bin) ISDIR = YES ISDIR RESULTS: 0 ////// isdir() ////// isdir(//bin) ISDIR = YES Dir: ///bin/ bin is a directory. instance 1: dir(bin) ----------------- dir(/bin) ----------------- ************ lsdir(/) ************** bin ////// isdir() ////// isdir(/bin/bin) ISDIR = NO ISDIR RESULTS: 1 ////// isdir() ////// isdir(/bin/bin) ISDIR = NO ////// isdir() ////// isdir(/bin/bin) ISDIR = NO File: /bin o0o0o0o0o0o file(/bin) o0o0o0o0o0o boot ////// isdir() ////// isdir(/bin/boot) ISDIR = NO ISDIR RESULTS: 1 ////// isdir() ////// isdir(/bin/boot) ISDIR = NO ////// isdir() ////// isdir(/bin/boot) ISDIR = NO File: /boot o0o0o0o0o0o file(/boot) o0o0o0o0o0o dbmsrv.prt ////// isdir() ////// isdir(/bin/dbmsrv.prt) ISDIR = NO ISDIR RESULTS: 1 ////// isdir() ////// isdir(/bin/dbmsrv.prt) ISDIR = NO ////// isdir() ////// isdir(/bin/dbmsrv.prt) ISDIR = NO File: /dbmsrv.prt o0o0o0o0o0o file(/dbmsrv.prt) o0o0o0o0o0o dev ////// isdir() ////// isdir(/bin/dev) ISDIR = NO ISDIR RESULTS: 1 ////// isdir() ////// isdir(/bin/dev) ISDIR = NO ////// isdir() ////// isdir(/bin/dev) ISDIR = NO File: /dev o0o0o0o0o0o file(/dev) o0o0o0o0o0o etc

2004-11-25 Edited by Arunbear: Changed title from 'My brain hurts', as per Monastery guidelines


In reply to Directory traversal problem by nbernstein

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.