Re: why does perl critic not like @_
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
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
"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
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?
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?
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
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 ???
[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
"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
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