Re: why does perl critic not like @_

2014-08-19 Thread Robert W Weaver
John wrote:

> I have just started using perl critic to analyse my code.
>
> I have often used @_ as a temporary array like this:
[..]
> Critic complains with 'Always unpack @_ first', why?
> What is so wrong with this usage?

anthony.okusa...@usbank.com gave an excellent response to what perl critic
means by 'always unpack @_ first'.

What I'd add is that Critic correctly identified the problem, but gave the
wrong flag.  The real problem here is
247. Don’t be clever.
People use @_ to pass parameters between subroutines.  Use of @_ for
temporary variables (like heavy use of $_) is too clever.

Better would be

  my @row_ary = $h_wk->selectrow_array("SELECT COUNT(*) FROM v_internals");

or even @temp_ary = to be more clear.  When people (and modules like
Perl::Critic) see @_, they think subroutine variables.

--woody

--

 Dr. Robert "Woody" GBS Cybersecurity & 
 Weaver Privacy 

 IT Security Architect  Cell: 301-524-8138  


--
What is wanted is not the will to believe, but the will to find out,
which is the exact opposite.
-- Bertrand Russell, "Skeptical Essays", 1928___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Perl-Win32-Users Digest, Vol 70, Issue 2

2012-06-05 Thread Robert W Weaver
perl-win32-users-boun...@listserv.activestate.com wrote on 06/05/2012 
03:00:02 PM:
> A non-text attachment was scrubbed...
> Name: pullFromEventLog.pl

It was a text attachment, you silly little program...  Well, I don't know 
how to get my mailer to send text only, so I can't blame it much.

Its only 250 lines, so hopefully the list will not mind if I post it 
directly.

#!c:\perl\bin\perl.exe
# vim:sw=2:et:ic:sm:syn=perl:nu
#
# $Id: pullFromEventLog.pl,v 1.4 2009/12/28 14:24:57 edf78qd Exp edf78qd $
#
# $Log: pullFromEventLog.pl,v $
# Revision 1.4  2009/12/28 14:24:57  edf78qd
# Cleaned up the CIM into a standard mysql datetime format before 
insertion.
#
# Revision 1.3  2009/09/24 22:05:48  edf78qd
# Added some docs
#
# Revision 1.2  2009/09/21 13:36:09  edf78qd
# made it a stand-alone, so that it would run as a child process.
# Added some instrumentation to log.$$.log
#
# Revision 1.1  2009/09/18 19:04:42  edf78qd
# Initial revision
#

=pod

Database structure for table logentries: most of these come straight from
windows event log fields (as seen below).  I just add "host" and "string"
at the end (for the FQDN host containing log entry, and the string that 
the
host is in).

+--+--+--+-+-++
| Field| Type | Null | Key | Default | Extra|
+--+--+--+-+-++
| logID| int(10) unsigned | NO   | PRI | NULL| 
auto_increment |
| Category | int(10) unsigned | YES  | | NULL||
| CategoryString   | tinytext | YES  | | NULL||
| ComputerName | tinytext | YES  | | NULL||
| Data | text | YES  | | NULL||
| EventCode| int(10) unsigned | YES  | | NULL||
| EventIdentifier  | int(10) unsigned | YES  | | NULL||
| EventType| int(11)  | YES  | | NULL||
| InsertionStrings | text | YES  | | NULL||
| LogFile  | tinytext | YES  | | NULL||
| Message  | text | YES  | | NULL||
| RecordNumber | int(10) unsigned | YES  | | NULL||
| SourceName   | tinytext | YES  | | NULL||
| TimeGenerated| datetime | YES  | | NULL||
| TimeWritten  | datetime | YES  | | NULL||
| Type | tinytext | YES  | | NULL||
| User | tinytext | YES  | | NULL||
| Host | tinytext | YES  | | NULL||
| string   | tinytext | YES  | | NULL||
+--+--+--+-+-++

=cut
use strict;
use Win32::OLE qw(in);
use Getopt::Std;
use DBI;
my $now   = time;
my $DEBUG = 0;
$| = 1;
our %opts;
getopts( 'hu:p:s:H:', \%opts );

if ( $opts{'h'} ) {
  print <', "log.$$.log" or die "can't open log.$$.log: $_";
}
print "Process $$ to $FQDN (" . localtime(time) . ")\n";
print F "Process $$ to $FQDN (" . localtime(time) . ")\n" if $DEBUG;
my $locatorObj = Win32::OLE->new('WbemScripting.SWbemLocator')
  || die "Error creating locator object: "
  . Win32::OLE->LastError() . "\n";
$locatorObj->{Security_}->{impersonationlevel} = 3;
#  $locatorObj->{Security_}->{setdebugpriviledge} = 1;
my $rv= 0;
my $serverObj = $locatorObj->ConnectServer(# connect to WMI server
  $FQDN,   # on this host
  'root\cimv2',# this namespace
  $opts{'u'},  # user
  $opts{'p'}
  )# password
  || ( $rv = 1 );
if ($rv) {
  print "Process $$ had an error connecting to $FQDN: "
. Win32::OLE->LastError() . "\n";
  print F "Process $$ had an error connecting to $FQDN: "
. Win32::OLE->LastError() . "\n"
if $DEBUG;
  exit;
}
my $dbh = DBI->connect( 'DBI:mysql:eventlogs', 'woody', '' )
  or die "Can't connect to mysql: $!";
my $sth = $dbh->prepare(
  "SELECT lastEntry FROM newestlogs WHERE Host LIKE '$FQDN'")
  or die "Can't prepare search for max: " . $dbh->errstr();
$sth->execute()
  or die "Can't execute search for max: " . $dbh->errstr();
my $ref= $sth->fetchrow_arrayref;
my $searchTime = convert2CIM( $$ref[0] );
my $preparestr =
"INSERT INTO logentries VALUES (0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
?, ?, ?, '$FQDN', '$opts{'s'}')";
$sth = $dbh->prepare($preparestr)
  or die "Can't prepare insert: " . $dbh->errstr();
my $once  = 0;
my $count = 0;
print "looking for log entries since $searchTime\n";
print F "looking for log entries since $searchTime\n" if $DEBUG;
my $newestLogDate;

foreach my $obj (
  in $serverObj->ExecQuery(
"SELECT * FROM WIN32_NTLogEvent WHERE (TimeGenerated > '$searchTime')",
'WQL',
48
  )
  ) {
  $count++;
  if ( not $once ) {
print "DB call f

RE: Perl-Win32-Users Digest, Vol 70, Issue 1

2012-06-05 Thread Robert W Weaver
"Barry Brevik"  wrote on 06/04/2012 06:34:07 PM:
> Thank you for the detailed response, even if it is depressing.

Don't think of it as depressing, think of it as an opportunity.  Gathering 
all your logs could provide more insight into your environment.

Attached is a toy I wrote.

The idea is to have a central point (in this case, my laptop) with a 
little mysql node on it.  I then create a table,
+--+--+--+-+-++
| Field| Type | Null | Key | Default | Extra|
+--+--+--+-+-++
| logID| int(10) unsigned | NO   | PRI | NULL| 
auto_increment |
| Category | int(10) unsigned | YES  | | NULL||
| CategoryString   | tinytext | YES  | | NULL||
| ComputerName | tinytext | YES  | | NULL||
| Data | text | YES  | | NULL||
| EventCode| int(10) unsigned | YES  | | NULL||
| EventIdentifier  | int(10) unsigned | YES  | | NULL||
| EventType| int(11)  | YES  | | NULL||
| InsertionStrings | text | YES  | | NULL||
| LogFile  | tinytext | YES  | | NULL||
| Message  | text | YES  | | NULL||
| RecordNumber | int(10) unsigned | YES  | | NULL||
| SourceName   | tinytext | YES  | | NULL||
| TimeGenerated| datetime | YES  | | NULL||
| TimeWritten  | datetime | YES  | | NULL||
| Type | tinytext | YES  | | NULL||
| User | tinytext | YES  | | NULL||
| Host | tinytext | YES  | | NULL||
| string   | tinytext | YES  | | NULL||
+--+--+--+-+-++

One runs the toy periodically, with $0 -H  
across all the possible client machines, and build up this DB.  IIRC, I 
had a watchdog program that would maintain a table of all the clients, and 
then poll this for all the "TimeWritten" and poll the clients based upon 
the order of the TimeWritten.  That way, I could have five or six 
instances of the toy running, cover all my clients, and still not hang 
dead on missing machines.  Then, at your leisure, you can ask questions 
like "what machines have event ID 528 or 540 and logon type 2?"  These 
would be the local clients.  The more interesting query would be "are 
there network logins from sources that I don't know about" -- the debian 
laptop that someone is using a remote login from, for example, that you 
hadn't expected.  Designing that SQL query is left as an exercise.. :-)

--woody

-- 
Dr. Robert "Woody" Weaver
GBS Cybersecurity & Privacy
IT Security Architect
Cell: 301-524-8138

-- 
I have hardly ever known a mathematician who was capable of reasoning.
-- Plato

pullFromEventLog.pl
Description: Binary data
___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Perl-Win32-Users Digest, Vol 70, Issue 1

2012-06-04 Thread Robert W Weaver
perl-win32-users-boun...@listserv.activestate.com wrote on 06/04/2012 
03:00:03 PM:
> I have a need to determine which client machine a given user (or all
> users) has logged into the domain from.
> 
> I'm willing to back into it by starting with all client machines. I'm

If you can access via WMI, there is a mib Win32_SystemUsers that is 
helpful.  I'm including some code from another project.  Build @Hosts with 
the client machines.  This just outputs the data in tab delimited format 
(this was just for a dozen machines and that made sense) but throwing into 
a DB for queries might make sense.
Sample output:
hostuserdomain
FredGuest   Fred
FredAdministrator   Fred
Fredpingsweep   Fred
FredSUPPORT_388945a0Fred
FredBob AD
FredAlice   AD
FredChuck   AD
FredDaveAD

That is, Administrator logged into the machine Fred locally, user Bob 
logged into the machine from the domain, etc.  This is answering the 
question of "to".

On the other hand, if you are really asking the question "from", you have 
to go to the event logs; there, you can get if a login was local or via 
the network.  The problem, of course, is that it is very transitory; on 
machine B you can find out that person logged in from machine A, but then 
you have to go back to see who logged into A at that time.

print join( "\t", 'host', 'user', 'domain' ), "\n";
foreach my $server (@Hosts) {
  warn "Connecting to $server\n";
  my $locatorObj = Win32::OLE->new('WbemScripting.SWbemLocator')
|| die "Error creating locator object: "
. Win32::OLE->LastError() . "\n";
  $locatorObj->{Security_}->{impersonationlevel} = 3;
  my $serverObj = $locatorObj->ConnectServer(# connect to WMI server
$server, # on this host
'\root\cimv2',   # this namespace
$opts{'u'},  # user
$opts{'p'}
)# password
|| die "Error connecting to $server: "
. Win32::OLE->LastError() . "\n";
  warn "Connected.\n";
  my $users = 0;
  foreach my $obj ( in $serverObj->InstancesOf('Win32_SystemUsers') ) {
$users++;
my $group = $obj->{GroupComponent};
my $part  = $obj->{PartComponent};
my $host  = pullRefs($group);
my $user  = pullRefs($part);
my ( $tmp, $subpart ) = split( /,/, $part );
my $domain = pullRefs($subpart);
print join( "\t", $host, $user, $domain ), "\n";
  }
  warn "$users users found.\n";
} ## end foreach my $server (@Hosts)

sub pullRefs {
  my $str = shift;
  my $tmp;
  my $rv;
  ( $tmp, $rv, $tmp ) = split( /\"/, $str );
  return $rv;
}

-- 
Dr. Robert "Woody" Weaver
GBS Cybersecurity & Privacy
IT Security Architect
Cell: 301-524-8138

-- 
"Anything else you wish to draw to my attention, Mr. Holmes ?"
"The curious incident of the stable dog in the nighttime."
"But the dog did nothing in the nighttime."
"That was the curious incident."
-- A. Conan Doyle, "Silver Blaze"


___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


RE: Isn't there a way to set variables in a loop?

2012-01-30 Thread Robert W Weaver
Ken Slater  wrote:
> You could just store the names in an array, but I'm assuming you need to
> access a specific file at some point.

I just wanted to follow up and perhaps clarify that.  What I read is
>  What I want to do is stick the
> same drive letter/directory path on the front of several filenames.

but what I'm hearing is that you want to prepend text to several 
variables, not just the filenames.

One way to do that is via eval, e.g.

my $foo = 'hello foo';
my $bar = 'hello bar';
my $baz = 'hello baz';

my @vars = qw( foo bar baz);

foreach my $var (@vars) {
  my $x = "\$$var = 'why, ' . \$$var . \"\\n\";";
  eval $x;
}

print $foo, $bar, $baz;


This prepends 'why, ' and postpends a crlf to each of the variables foo, 
bar, and baz.  eval allows you to break the fourth wall.

--woody

-- 
Dr. Robert "Woody" Weaver
Security, Privacy, Wireless, and Information Assurance
IT Security Architect
Cell: 301-524-8138

-- 
Q: How many Martians does it take to screw in a light bulb?
A: One and a half.___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


perl won't alarm?

2011-02-23 Thread Robert W Weaver

I have code that executes an external command, vis:

  eval {
local $SIG{ALRM} = sub { die "alarm\n" };
alarm $TIMEOUT;
$text = `$pre_command$host $post_command` || ( $connectOk = 0 );
alarm 0;
$errStr = $^E;
  };

The command hangs for a reason I don't understand (its a PsExec of opmnctl
@cluster status -app on a windows oracle server).  Unfortunately, the block
above never exits.

Is there a way I can protect my routine from hanging system calls?


--
   
 Dr. Robert "Woody" Security, Privacy, Wireless, and   
 Weaver Information Assurance  
   
 IT Security Architect  Cell: 301-524-8138 
   


--
I have great faith in fools -- self confidence my friends call it.
-- Edgar Allan Poe

___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Perl-Win32-Users Digest, Vol 28, Issue 8

2008-11-20 Thread Robert W Weaver

Foo JH <[EMAIL PROTECTED]>, on 20 Nov 2008 10:40:13 +0800 wrote:
> Fish, David wrote:
> > Hello!  The problem I am having is I am pulling data from a table in a
> > certain order and loading it into the hash array but when I read the
> > hash array it comes out in a different order than it is written.  What
I
[..]
> Wouldn't a stack (essentially just an array) be better than a hash?

Not necessarily.  A hash is a good solution if there is an issue with
de-duping.

If there is no de-duping, then pushing into a stack, and "foreach"ing the
values after they have all been entered is probably best.  However, you
might be able to avoid the storage, by doing whatever you were going to do
as you read them instead of reading them all in at once and then
processing.

If there is de-duping, then hashes make a lot of sense.  If you were going
to do all the processing at the end, push them into the hash, and add a
integer that is incremented on first insert, then finally run over the
stack sorting on that integer key.  But again, if you can process them as
you read them, read the item, see if its in the hash, and if not then
insert it and process it.

--woody___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: printing html with hardcoded page breaks ???

2008-05-21 Thread Robert W Weaver
[EMAIL PROTECTED] wrote on 05/21/2008
03:00:25 PM:
> Date: Tue, 20 May 2008 16:39:53 -0500
> From: Mike Schleif <[EMAIL PROTECTED]>
> Subject: printing html with hardcoded page breaks ???

> How can I build a web page that, when printed, breaks the web page into
> multiple printed pages, which break at specific pages?

Obviously, this is not a perl question.

There is no general purpose answer.  However, you can come close with style
sheets.  See http://www.wpdfd.com/forums/wpdfd/layout/page_break/ for
examples and discussion.

--
   
 Dr. Robert "Woody" Weaver Security, Privacy, Wireless, and Information
   Assurance   
   
 IT Security Architect Cell: 301-524-8138  
   


--
"Never ascribe to malice that which is caused by greed and ignorance."
-- Cal Keegan___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: Perl-Win32-Users Digest, Vol 19, Issue 15

2008-02-25 Thread Robert W Weaver

"David Golden" <[EMAIL PROTECTED]> wrote on 02/23/2008 03:00:19 PM:

> Well, it was written to be clever, not maintainable. :-)

Point taken.  I did mention that I was probably going to far in what was
just a game. :-)

> In response to Conway: clever algorithms are good; clever code is not so
good.

(sidebar: I used to teach this stuff.  I had one student that used the
names of dead russian authors for ALL variables.  Finally learned the joys
of sed and perltidy.)

Clever algortithms, depending on how you mean that, is the whole game,
except for those grunts who only make a money off coding.  What makes
coding a human art instead of a mechanical subject is creative play with
ideas -- that whole data structures + algorithms thing.

>   my $regex = join q{}, map { $num2chars[$_] } @digits;
>
> That seems pretty straightforward code to me, rather than clever code.

I don't think I disagree; but then I remember one class I took as a grad
student: we have a visiting prof, and he was putting a proof up on the
board.  Threw up an introductory lemma, and announced "the proof is clear."
The hosting professor took issue: a lively 30 minute discussion followed,
where it was decided that indeed, the proof was obvious.

obsSyntaxPoint -- its straightforward, but in the code you wrote above, you
forgot the [] -- so the regex will miss the grouping.. unless I"m missing
something.  What you had in your earlier post was
my $regex = join q{}, map { "[$num2chars[$_]]" } split //, , 7;
^ ^
And yes, once you *think* about it, its elegant.  Its clever.   You have
natively translated the algorithmic idea into perl code.  You've made it at
least reasonably straightforward by using explicit  join -- map -- splits
instead of using obscure scalar vs. list properties.  (Although, why not qr
it?)  And I like it much better than using a tr// which you have to put
inside an eval.  Which makes it a good solution for a game.

>  It's great that you're enjoying Perl Best Practices, but many of those
> recommendations do require some healthy skepticism and Damian's
> introduction (I think) makes the point that they are just one opinion

Very true.  I read an interview where they asked him about the differences
between his 2^8 and Wall's 5*8, and his comment was that both held up.
What I find is that while there are a couple of things that I disagree with
(e.g. the use of postfix selectors) I think the point is that you have to
have *something*.  [I usually start with Weinburg's Ten Commandments, but
that isn't coding specific.] Conway's are well thought out, reasonably
consensual, and based on more experience than I (and probably thee).  But
consider the audience for the game -- it strikes me that these are more
likely to be someone either new to perl or relatively new to programming.
These are the kinds of problems that you ask of students half way through a
semester.  And they would do very well indeed to learn style from PBP.

--woody

--
   
 Dr. Robert "Woody" WeaverSecurity, Privacy, Wireless, and IT  
  Governance   
   
 IT Security ArchitectPhone: 240-782-4260  
   


--
There are still some other things to do, so don't think if I didn't fix
your favorite bug that your bug report is in the bit bucket. (It may be,
but don't think it. :-) Larry Wall in <[EMAIL PROTECTED]>___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs


Re: discussing good style

2008-02-22 Thread Robert W Weaver

Dave Golden wrote:
> Jan Dubois wrote:
> > So any feedback on the style /content would be welcome.
> I really liked that you discussed good style and some defensive
> coding, even though that wasn't required by the competition.

> "open or die" -- I personally think it's good style to die with at
> least "$!" so there's some feedback as to what happened.

It strikes me that commentary at this level should be of two types --
interesting or unusual algorithms or data structures for solving the
problem, and stylistic recommendations.

For the latter, I've been plowing through Conway's book,
_Perl_Best_Practices_.  It seems to me you can't talk about style without
at least a nod to it.

For example, on error checking IO, Conway's dicta is "Never open, close, or
print to a file without checking the outcome."  And he offers

open my $out, '>', $out_file or croak "Couldn't open '$out_file':
$OS_ERROR";

($OS_ERROR you may be asking yourself?  Conway is a big fan of 'use
English' instead of potentially obscure mnemonics.  Sadly, since I've used
$! when what I really meant was $dbh->errstr(), he is probably right.)  He
also points out that there is a perhaps better way "Make failed builtins
throw exceptions too" with the use of 'use Fatal'.  This is pretty cool.
Now

#!perl -w

use strict;
use Fatal qw(open);

open my $fh, '<', 'foo.bar';
print "Hi, Mom!\n";

when executed, yields

C:\Documents and Settings\Administrator\My Documents\random perl>test.pl
Can't open(GLOB(0x226268), <, foo.bar): No such file or directory at (eval
1) line 3
main::__ANON__('GLOB(0x226268)', '<', 'foo.bar') called at
C:\Documentsand Settings\Administrator\My Documents\random perl\test.pl
line 5

Very, very smart.  Add something like 'use Fatal qw( open close );' into
your boilerplate (I can't bring myself to trap every bloody print statement
like Conway suggests) seems like a pretty sound idea.

Or, in terms of Dubois' style,

chomp(my $number = <>);

This looks ugly to my eye.  His point was "don't do $number = chomp(<>)"
pointing out that some people are confused about what chomp returns.  But
why not

my $number = <>;
chomp($number);

Its more clear, I think, and allows for slightly cleaner debugging if
needed.  But that is pretty small potatoes compared with the key logic of
his approach

eval "tr/$letters\L$letters\E/$digits$digits/";

He correctly points out that tr doesn't support interpolation at run time,
so we have to put this inside an eval... but isn't the correct conclusion
is that this is probably too complicated for what is essentially a really
easy task?  Or the very clever approach of building a custom regex via join
q{}, map { "[$num2chars[$_]]" } split //, , 7; -- okay, but again, I
think I'd argue that clever is probably bad. Conway has a dicta for that,
too: "Don't be clever."  His observation is that while Perl provides
endless opportunities for cleverness, its the natural enemy of maintainable
code.

I think my approach would have been to set up a hash table mapping chars to
digits, then do what David did with his regex via hash lookups.

But then, perhaps I'm being silly.  This is only a game.  But I do want to
give a big thumbs up to Conway's book.

--woody

--
Let me assure you that to us here at First National, you're not just a
number. Youre two numbers, a dash, three more numbers, another dash and
another number. -- James Estes___
Perl-Win32-Users mailing list
Perl-Win32-Users@listserv.ActiveState.com
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs