http://www.perlmonks.org?node_id=388824

Current Conundrum

Why Doesn't This Work?

Typical, eh? This is supposed to start at $ARGV[0] and search for file or dir names with weird characters in them, where 'weird' is defined by a buddy of mine. The problem is that it doesn't recurse. When it hits the first subdirectory, the script dies. Ideas?
#!/usr/bin/perl use warnings; use strict; if ( not defined $ARGV[0] ) { print "No search directory given.\n"; exit; } else { checkNames($ARGV[0]); } # exit; sub checkNames { use warnings; use strict; my $thisdir = shift; my $thisfile; if ( $thisdir =~ /[^0-9A-Za-z\-\.\/]/ ) { print "Directory $thisdir contains strange characters. +\n"; } opendir(THISDIR, $thisdir) or die "Couldn't read from $thisdir +.\n"; NAMES: while ( $thisfile = readdir(THISDIR) ) { if ( -d $thisfile ) { # Skip the . and .. directories. if ( $thisfile =~ /^\.{1,2}$/ ) { next NAMES; } print "Recursing into $thisdir/$thisfile.\n"; checkNames("$thisdir/$thisfile"); } if ( -f $thisfile ) { if ( $thisfile =~ /[^0-9A-Za-z\-\.]/ ) { print "File $thisdir/$thisfile contain +s strange characters.\n"; next NAMES; } } if ( not -d $thisfile and not -f $thisfile ) { # If it isn't a file and it isn't a directory, + ignore it. next NAMES; } } closedir(THISDIR); }

Previous Perl Conundrums

Shorten SNMP Query Loop

Limbic~Region suggested something similar to this (modified again):

$mib = 'someMibObject'; $vb = SNMP::Varbind->new([$mib]); while ( $vb->tag eq $mib ) { $var = $sess->getnext($vb); # Get the next instance. last if $sess->{ErrorNum}; # Do something with $vb->iid and/or $var } if ( $sess->{ErrorNum} ) { # We might do something more interesting than print here. }

Dang. Still have a problem. The tag vs. mib test changes when the getnext() query is made. So to have the test in the while() statment, the query would have to be at the bottom of the loop. But in that case, the whole loop executes once against uninitialized values for vb and sess. Grrr...

MAC Address Converter

# Here are the ideas. Remember that $mac = 'addr' is # supposed to be part of the 'given'. My apologies if I # forgot anyone's suggestion. # # Change '00:01:02:04:08:0A' to '0.1.2.4.8.10': $mac = '00:01:02:04:08:0A';
By PodMaster:
$mac =~ s/(..)(:)?/hex($1).($2?'.':'')/ge;
By shenme:
$mac =~ s/([0-9A-F]+|:)/$1 eq ':' ? '.' : hex($1)/ge;
What I did:
$mac = join '.', map hex($_), split(/:/, $mac);
Benchmark results using cmpthese('1_000_000',...):
Rate Shenme PodMaster My Way Shenme 38212/s -- -31% -50% PodMaster 55710/s 46% -- -28% My Way 76982/s 101% 38% --
All suggestions submitted produced correct results.

New MAC Converter

# Convert any known MAC format to any other known format. sub ConvertMac($$$) { use strict; use warnings; my $mac = shift; my $form = shift; my $debug = shift; if ( $debug > 4 ) { print "\t\t\t\tConvertMac: Converting $mac to $form.\n"; } # First, convert the MAC to the common XX:XX:XX:XX:XX:XX format. START: { # Suppose it's just flat hex? if ( $mac =~ /^$nosepmacpattern$/ ) { # Just convert it and we're done. $mac = join ':', map sprintf("%02X", ord($_)), split //, p +ack('H12', $mac); # We can escape, since $nosepmacpattern enforces the lengt +h, and the above formats it. last START; } # Convert dotted-decimal to hex first (ignore the dots). if ( $mac =~ /^$decmacpattern$/ ) { $mac =~ s/(\d+)/sprintf("%02X", $1)/eg; } # Now convert hex separated by anything to our standard format +. $mac = join ':', map sprintf("%02X", hex($_)), split /[^[:xdig +it:]]/, $mac; # Test for valid data (suppose >2 hex digits between separator +s or >6 items). if ( $mac !~ /^$colonmacpattern$/ ) { return('Error'); } # Don't return here, even if ( $form eq 'colon'). See below. } # Now, convert to the form requested. FINISH: { # This is the most common, so we'll put it first. if ( $form eq 'colon' ) { # Don't return here either. Look below. last FINISH; } # This is really easy. if ( $form eq 'nosep' ) { $mac =~ s/://g; $mac = lc($mac); last FINISH; } if ( $form eq 'blank' ) { $mac =~ s/:/ /g; last FINISH; } if ( $form eq 'dash' ) { $mac =~ s/:/-/g; last FINISH; } if ( $form eq 'dec' ) { $mac = join '.', map hex($_), split(/:/, $mac); last FINISH; } if ( $form eq 'invert' ) { $mac = join ':', map uc(unpack('H*', pack('b*', unpack('B* +', pack('H*', $_))))), split(/:/, $mac); last FINISH; } if ( $form eq 'varcolon' ) { $mac =~ s/0([[:xdigit:]])/$1/g; $mac = lc($mac); last FINISH; } } if ( $debug > 4 ) { print "\t\t\t\t\tConvertMac: Returned value is $mac.\n"; } # Always return here so the debug stuff always runs and so if we e +ven want to do # anything else down here, we won't circumvent it by escaping earl +y. return($mac); }