<?xml version="1.0" encoding="UTF-8"?>



<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">

    <channel>
        <title>sourcecode</title>
        <link>http://prlmnks.org/list/</link>
        <description>RSS feeds from perlmonks.org</description>
        <language>en</language>
        <ttl>5</ttl>

        

<item>
    <title>Reaped: SATISH (NodeReaper)</title>
    <link>http://prlmnks.org/html/580500.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/580500.html</guid>

    <description>
        This node was taken out by the &lt;a href=&quot;/out/node/NodeReaper&quot;&gt;NodeReaper&lt;/a&gt; on &lt;a href=&quot;/out/localtime/2006-10-25 09-27-23&quot;&gt;2006-10-25 09-27-23&lt;/a&gt;&lt;BR&gt;Reason:  &amp;#91;&lt;a href=&quot;/out/node/jdporter&quot;&gt;jdporter&lt;/a&gt;]: reap. no content. (looks like a test post)&lt;p&gt;You may view &lt;a href=&quot;/out/href/?node=Visit%20Reaped%20Nodes&amp;amp;nodenum=580500&quot;&gt;the original node and the consideration vote tally&lt;/a&gt;.&lt;/p&gt;
    </description>
</item>

        

<item>
    <title>Reaped: SF_form_secure (NodeReaper)</title>
    <link>http://prlmnks.org/html/579997.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/579997.html</guid>

    <description>
        This node was taken out by the &lt;a href=&quot;/out/node/NodeReaper&quot;&gt;NodeReaper&lt;/a&gt; on &lt;a href=&quot;/out/localtime/2006-10-23 09-03-01&quot;&gt;2006-10-23 09-03-01&lt;/a&gt;&lt;BR&gt;Reason:  &amp;#91;&lt;a href=&quot;/out/node/Corion&quot;&gt;Corion&lt;/a&gt;]: Reap: Duplicate of &lt;a href=&quot;/html/579995.html&quot;&gt;SF_form_secure&lt;/a&gt;&lt;p&gt;You may view &lt;a href=&quot;/out/href/?node=Visit%20Reaped%20Nodes&amp;amp;nodenum=579997&quot;&gt;the original node and the consideration vote tally&lt;/a&gt;.&lt;/p&gt;
    </description>
</item>

        

<item>
    <title>SF_form_secure (SFLEX)</title>
    <link>http://prlmnks.org/html/579995.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/579995.html</guid>

    <description>
        What are you waiting for?&lt;br /&gt;Start using it!&lt;br /&gt;Befor that A.D.D. sets in.
    </description>
</item>

        

<item>
    <title>Tk Photo Slideshow, with scrolling and scaling (jdporter)</title>
    <link>http://prlmnks.org/html/579154.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/579154.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;use Tk;use Tk::JPEG;use Tk::Pane;use strict;use warnings;my $dir = shift || &#39;.&#39;;chdir $dir or die &quot;Can&#39;t go do $dir - $!\n&quot;;my $filespec = &quot;*.jpg&quot;;my @files = glob $filespecor die &quot;No files matching $filespec in $dir !\n&quot;;my $ii = -1; # image indexmy $mw = new MainWindow;my $scrolled = $mw-&gt;Scrolled( &#39;Pane&#39;, -scrollbars =&gt; &#39;osoe&#39;, -width =&gt; 640, -height =&gt; 480, )-&gt;pack( -expand =&gt; 1, -fill =&gt; &#39;both&#39;, );my $imagit = $scrolled-&gt;Label-&gt;pack( -expand =&gt; 1, -fill =&gt; &#39;both&#39;, );my( $xscroll, $yscroll ) = $scrolled-&gt;Subwidget( &#39;xscrollbar&#39;, &#39;yscrollbar&#39; );my( $last_x, $last_y );my $img2;$mw-&gt;bind( &#39;&lt;Prior&gt;&#39; =&gt; \&amp;prev_image );$mw-&gt;bind( &#39;&lt;Up&gt;&#39;    =&gt; \&amp;prev_image );$mw-&gt;bind( &#39;&lt;Left&gt;&#39;  =&gt; \&amp;prev_image );$mw-&gt;bind( &#39;&lt;Next&gt;&#39;  =&gt; \&amp;next_image );$mw-&gt;bind( &#39;&lt;Down&gt;&#39;  =&gt; \&amp;next_image );$mw-&gt;bind( &#39;&lt;Right&gt;&#39; =&gt; \&amp;next_image );$imagit-&gt;bind( &#39;&lt;Button1-ButtonRelease&gt;&#39; =&gt; sub { undef $last_x } );$imagit-&gt;bind( &#39;&lt;Button1-Motion&gt;&#39; =&gt; [ \&amp;drag, Ev(&#39;X&#39;), Ev(&#39;Y&#39;), ] );sub drag{my( $w, $x, $y ) = @_;if ( defined $last_x ){my( $dx, $dy ) = ( $x-$last_x, $y-$last_y );my( $xf1, $xf2 ) = $xscroll-&gt;get;my( $yf1, $yf2 ) = $yscroll-&gt;get;my( $iw, $ih ) = ( $img2-&gt;width, $img2-&gt;height );if ( $dx &lt; 0 ){$scrolled-&gt;xview( moveto =&gt; $xf1-($dx/$iw) );}else{$scrolled-&gt;xview( moveto =&gt; $xf1-($xf2*$dx/$iw) );}if ( $dy &lt; 0 ){$scrolled-&gt;yview( moveto =&gt; $yf1-($dy/$ih) );}else{$scrolled-&gt;yview( moveto =&gt; $yf1-($yf2*$dy/$ih) );}}( $last_x, $last_y ) = ( $x, $y );}=podImage scaling here is designed to strike a balancebetween not wanting to scroll too much and notwanting to lose too much resolution by downsampling.The heuristic is:1. if the image fits within the scrolled pane in oneor both dimensions (that is, only zero or one scrollbarwould be shown), no downsampling is done.2. otherwise (i.e. if two scrollbars would be needed),the downsampling factor is incremented (from 1) untilcondition #1 (above) is met.(Of course, we don&#39;t actually increment and check likethat; we calculate the desired factor algebraically.)This way, when you do have to scroll, it will often beon one axis only; and the distance you&#39;ll have to scroll will be minimized (or rather, optimized).Another approach would be to downsample the picturesufficiently such that the image always fits entirelywithin the pane, and scrolling won&#39;t be necessary, butI&#39;d rather give minimization of resolution loss slightly more weight than eliminating the need to scroll.=cutsub factor{my( $n, $m ) = @_;($n&gt;$m) ? int($n/$m) : 1}sub min{my( $n, $m ) = @_;$n &lt; $m ? $n : $m}sub show_image{my $imgfile = $files[$ii];$mw-&gt;configure( -title =&gt; &quot;($ii) - - - - - - -&quot; );my $img1 = $mw-&gt;Photo( &#39;fullscale&#39;,-format =&gt; &#39;jpeg&#39;,-file =&gt; $imgfile,);# it&#39;s possible to manipulate an image during reading# from disk, but unfortunately you don&#39;t get quite as# much control as you do when copying one image to another,# and some of the things we need to do we can only do# during copy, not reading.my $factor = min(factor( $img1-&gt;width, $scrolled-&gt;width ),factor( $img1-&gt;height, $scrolled-&gt;height ),);$img2 = $mw-&gt;Photo( &#39;resized&#39; );$img2-&gt;copy( $img1, -shrink, -subsample =&gt; $factor, $factor );$imagit-&gt;configure(-image =&gt; &#39;resized&#39;,-width =&gt; $img2-&gt;width,-height =&gt; $img2-&gt;height,);$mw-&gt;configure( -title =&gt; &quot;($ii) $imgfile&quot; );}sub prev_image{$ii = ( $ii + @files - 1 ) % @files;show_image();}sub next_image{$ii = ( $ii + 1 ) % @files;show_image();}$mw-&gt;after( 100, \&amp;next_image );MainLoop;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Module Finder (innominate)</title>
    <link>http://prlmnks.org/html/579097.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/579097.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl use strict;use warnings;use File::Find;if(my $m = shift){find(sub{/$m/i ? print&quot;$File::Find::name\n&quot; : 0},@INC);}else {print &quot;Please enter a single search string as an argument!\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>pexec.pl: snippet runner (Hue-Bond)</title>
    <link>http://prlmnks.org/html/578318.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/578318.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse warnings;use strict;use Gtk2;## todo: change mnemonic into an accelerator (^D)## todo: do another one for quitting (^Q)## bug (fixed by forking): halts on infinite loops :^Pmy ($window, $vbox, $ptext, $but, $label);my $font = &#39;Monospace 10&#39;;my $perl = &#39;/usr/bin/perl&#39;;sub do_run {    my $pid;    my $buf = $ptext-&gt;get_buffer;    local $SIG{&#39;CHLD&#39;} = &#39;IGNORE&#39;;    warn &quot;fork: $!&quot; and return unless defined ($pid = fork);    if ($pid) { ## parent        $ptext-&gt;grab_focus;        return;     }    ## child    $pid = open my $fd, &#39;|-&#39;, $perl, &#39;-t&#39; or die &quot;fork: $!&quot;;    print &quot;\n$perl PID: $pid\n&quot;;  ## for easy killing    print $fd $buf-&gt;get_text ($buf-&gt;get_bounds, 1);    close $fd;    exit;   }Gtk2-&gt;init;$window = Gtk2::Window-&gt;new (&#39;toplevel&#39;);$vbox   = Gtk2::VBox-&gt;new (0, 0); $ptext  = Gtk2::TextView-&gt;new;$but    = Gtk2::Button-&gt;new;$label  = Gtk2::Label-&gt;new_with_mnemonic (&#39;_Run!&#39;);$but-&gt;signal_connect (clicked =&gt; \&amp;do_run);$but-&gt;add ($label);$but-&gt;set_size_request (50, 30);$ptext-&gt;set_size_request (50, 20);$ptext-&gt;set_border_width (4);$ptext-&gt;modify_font (Gtk2::Pango::FontDescription-&gt;from_string ($font));$ptext-&gt;get_buffer-&gt;set_text (&lt;&lt;_DEF_TEXT_);use warnings;use strict;use Data::Dumper;\$ENV{&#39;PATH&#39;} = \$ENV{&#39;CDPATH&#39;} = &#39;/usr/bin:/bin&#39;;_DEF_TEXT_$vbox-&gt;add ($ptext);$vbox-&gt;pack_end ($but, 0, 0, 0);$window-&gt;signal_connect (destroy =&gt; sub { Gtk2-&gt;main_quit; });$window-&gt;set_default_size (700, 400);$window-&gt;add ($vbox);$window-&gt;show_all;Gtk2-&gt;main;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>linked-port: find given linked libraries (&quot;shared objects&quot;) in FreeBSD Ports (parv)</title>
    <link>http://prlmnks.org/html/578262.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/578262.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/local/bin/perl$VERSION = &#39;0.01&#39;;use warnings; use strict;use Data::Dumper;$Data::Dumper::Useqq = 1;$Data::Dumper::Indent = 1;$Data::Dumper::Sortkeys = 1;$Data::Dumper::Terse = 0;$Data::Dumper::Purity = $Data::Dumper::Deepcopy = 1;$Data::Dumper::Deparse = 1;use Getopt::Long;my %opt =  (    &#39;ports-data&#39; =&gt; q{/var/db/pkg}  , &#39;file-list&#39;  =&gt; &#39;+CONTENTS&#39;  , &#39;ports&#39; =&gt; []  , &#39;libs&#39;  =&gt; []  );GetOptions(  &#39;d|dir|ports-data=s&#39; =&gt; \$opt{&#39;ports-data&#39;}, &#39;p|ports=s@&#39; =&gt; $opt{&#39;ports&#39;}, &#39;l|libs=s@&#39; =&gt; $opt{&#39;libs&#39;})  or die;#  Search for files for ALL the installed ports.push @{ $opt{&#39;ports&#39;} } , &#39;.&#39; unless scalar @{ $opt{&#39;ports&#39;} };push @{ $opt{&#39;libs&#39;} } , @ARGV if scalar @ARGV;my $possibly_linked =  get_files  (    {      &#39;list-maker&#39; =&gt; [ qw{ pkg_info -L } ]    , &#39;ports&#39; =&gt; find_ports( $opt{&#39;ports&#39;} )    , &#39;keep&#39;  =&gt;        qr{ (?: /(?: s?bin | libexec ) / .+ | /perl\d+/.+?[^/]+\.so )$ }x    }  );my $linked =  find_libs  (    {      &#39;libs-lister&#39; =&gt; q{ldd}    , &#39;ports&#39; =&gt; $possibly_linked    , &#39;keep&#39; =&gt; ( map qr{$_}i , join &#39;|&#39; , @{ $opt{&#39;libs&#39;} } )[0]    }  );print Dumper( $linked );exit;sub find_libs{  my ( $find ) = @_;  my %linked;  my $parse = qr{^ \s* lib[-.,_a-zA-Z0-9]+ \s+ =&gt; \s+ .+ };  foreach my $port ( keys %{ $find-&gt;{&#39;ports&#39;} } )  {    foreach my $file (  @{ $find-&gt;{&#39;ports&#39;}-&gt;{ $port } } )    {      #  Stringification is needed to send ldd(1) errors to /dev/null; otherwise      #  &quot;2&gt;/dev/null: No such file or directory&quot; error message is produced by      #  ldd(1).      my $cmd =        join &#39; &#39; , $find-&gt;{&#39;libs-lister&#39;} , $file , &#39;2&gt;/dev/null&#39;;      open my $ph , &#39;-|&#39; , $cmd or die &quot;Cannot open pipe: $!&quot;;      my $skip = quotemeta $file;      $skip = qr{^$skip:};      while ( my $line = &lt;$ph&gt; )      {        next unless $line =~ m/$find-&gt;{&#39;keep&#39;}/;        next if $line =~ m/$skip/;        $line =~ s/^\s+//;        chomp $line;        push @{ $linked{ $port }-&gt;{ $file } } , $line      }    }  }  return { %linked };}sub get_files{  my ( $find ) = @_;  my %files;  foreach my $p ( @{ $find-&gt;{&#39;ports&#39;} } )  {    open my $ph , &#39;-|&#39; , @{ $find-&gt;{&#39;list-maker&#39;} } , $p      or die &quot;Cannot open pipe: $!&quot;;    while ( my $file = &lt;$ph&gt; )    {      next unless $file =~ m/$find-&gt;{&#39;keep&#39;}/ ;      chomp $file;      push @{ $files{ $p } } , $file ;    }  }  return { %files };}sub find_ports{  my ( $re ) = @_;  ($re) = map qr{$_}i, join &#39;|&#39; , @{ $re };  my ($dh , $close ) = open_dir( $opt{&#39;ports-data&#39;} );  my @ports;  while ( my $port = readdir $dh )  {    next unless $port =~ m/$re/;    my $path = join &#39;/&#39; , $opt{&#39;ports-data&#39;} , $port;    next      unless -d $path          &amp;&amp; -f join &#39;/&#39; , $path , $opt{&#39;file-list&#39;}        ;    push @ports , $port;  }  $close-&gt;();  chomp @ports;  return [ sort @ports ];}sub open_dir{  my ( $dir ) = @_;  opendir my $dh , $dir or die &quot;Cannot open $dir: $!&quot;;  return ( $dh , sub { closedir $dh or die &quot;Cannot close $dir: $!&quot;; } );}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Attachment Search for TWiki (Melly)</title>
    <link>http://prlmnks.org/html/577627.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/577627.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -wTuse strict;use CGI qw(:standard);use File::Find;# base pathsmy $searchpath = &#39;/var/www/twiki/pub/&#39;;my $doc_url = &#39;/twiki/pub/&#39;;my $twiki_url = &#39;/twiki/bin/view/&#39;;my $return_url = &#39;/&#39;; # link back to main twiki# twikis that can be searched, incl. Allmy @twikis = qw(  All CV Customers Dev Implementation Info Product Proton  RENLStar Sales Sandbox Support);# for popup_menu values=array element# (stops user adding another directory)my %twikis;foreach(0..$#twikis){  $twikis{$_} = $twikis[$_];}# will hold final list of twikis to search (1 twiki unless All)my @twikipaths;# params from formmy $mode = param(&#39;mode&#39;); # cgi app modemy $isregex = param(&#39;isregex&#39;); # regex searchmy $cs = param(&#39;cs&#39;); # case-sensitivemy $fname_only = param(&#39;fname_only&#39;); # filenames only# searchterm - allow anything, but eval regex ($msg for regex errs)my ($msg, $searchterm) = (&#39;&#39;,&#39;&#39;);$searchterm = $1 if (defined param(&#39;searchterm&#39;) &amp;&amp;  param(&#39;searchterm&#39;) =~ /(.+)/);if($isregex){  eval {&#39;foobar&#39; =~ /$searchterm/};  if($@){    $isregex = 0;    $@ =~ /([^;]*)/;    $msg = &quot;&lt;em&gt;Bad Regex - non-Regex search performed: $1      (if you entered &#39;*&#39;, you probably meant &#39;.*&#39;)&lt;/em&gt;&lt;br&gt;&quot;;  }}# search_ext - allow anything, but eval (always regex)my $search_ext = &#39;doc&#39;;$search_ext = $1 if (defined param(&#39;search_ext&#39;) &amp;&amp;  param(&#39;search_ext&#39;) =~ /(.+)/);eval{ &#39;foobar&#39; =~ /$search_ext/};if($@){  $search_ext = &#39;doc&#39;;  $@ =~ /([^;]*)/;  $msg .= &quot;&lt;em&gt;Bad Extension Regex - searching for .doc: $1&lt;/em&gt;&quot;;}# for displaymy $nice_ext = &#39;.&#39; . (lc $search_ext);my $title;# translate array element from param to twiki namemy $twiki = $twikis[0];$twiki = $twikis[$1] if (defined param(&#39;twiki&#39;) &amp;&amp;  param(&#39;twiki&#39;) =~ /^(\d+)$/) and defined $twikis[$1];# for list of files found in searchmy @matched_files;# no search, just formif(!$mode or $searchterm =~ /^\s*$/ or !$twiki){  $mode = 0;  $title = &#39;Twiki Attachment Search&#39;;  &amp;SearchTop($title);  &amp;SearchEnd();}# form + search + search resultselsif($mode){  # build list of twikis to search  if($twiki eq &#39;All&#39;){    foreach(@twikis){      push @twikipaths, $searchpath . $_ . &#39;/&#39; if $_ ne &#39;All&#39;;    }  }  else{    push @twikipaths, $searchpath . $twiki . &#39;/&#39;;  }  # handle regex/non-regex search, run search and print results  $searchterm = quotemeta $searchterm if !$isregex;  &amp;DoSearch();  $title = &#39;Twiki Attachment Search Results&#39;;  &amp;SearchTop($title)  &amp;SearchResults();  &amp;SearchEnd();}# page topsub SearchTop(){  my $title = $_[0];  my $title2;  $title2 = &quot;(Search for: $searchterm)&quot; if $mode;  $title2 .= &quot;(Extension: $nice_ext)&quot;;  $title2 .= &quot;&lt;br&gt;(Twiki: $twiki)&quot;;  $title2 .= $isregex ? &#39;(regex)&#39; : &#39;(non-regex)&#39;;  $title2 .= $cs ? &#39;(case-sensitive)&#39; : &#39;(case-insensitive)&#39;;  $title2 .= $fname_only ? &#39;(filenames only)&#39; : &#39;(filenames and content)&#39;;  print header();  print start_html($title);  &amp;SearchForm($title, $title2);}# page endsub SearchEnd(){  print end_html();}# search form, use numeric vals for twikissub SearchForm(){  print h2($_[0]);  print h4($_[1]);  print p(    a({-href=&gt;$return_url},&#39;Back to TWiki&#39;)  );  print p(&quot;&lt;em&gt;WARNING - Searching may take some time,    especially if you search all Twikis (although \&quot;Filenames Only\&quot; should    be okay).&lt;/em&gt;&lt;br&gt;&quot;,    &quot;To return a list of all docs, use \&quot;.*\&quot;    as a Regex  with the \&quot;Filenames Only\&quot; and \&quot;All\&quot; options.&lt;br&gt;    The extension regex is not case-sensitive.&quot;);  print start_form(&#39;GET&#39;);  print p(&quot;Search For: &quot;, textfield(&#39;searchterm&#39;, &#39;&#39;,35), &#39;.&#39;,    textfield(&#39;search_ext&#39;, &#39;doc&#39;,7),&#39;(extension regex)&#39;  );  print p(    a({-href=&gt;&#39;http://tinyurl.com/pcpbq&#39;,-target=&gt;&#39;_new&#39;},&quot;Regex: &quot;),    checkbox(&#39;isregex&#39;,0,1, &#39;&#39;),    &quot;Case Sensitive: &quot;, checkbox(&#39;cs&#39;,0,1,&#39;&#39;),    &quot;Filenames Only: &quot;, checkbox(&#39;fname_only&#39;,0,1,&#39;&#39;)  );  print p(&quot;In TWikis: &quot;,popup_menu(&#39;twiki&#39;,[0..$#twikis],0,\%twikis),    hidden(&#39;mode&#39;, 1));  print p(submit(&#39;Search&#39;), &#39; &#39;, CGI::reset());  print endform;}# handle search results (mainly building urls)sub SearchResults(){  print h4(&#39;Warning&#39;), &#39;&lt;p&gt;&#39;, $msg, &#39;&lt;/p&gt;&#39; if $msg;  my @filesout;  foreach(@matched_files){    my $file = $_;    if($file =~ m#^$searchpath([^/]*)(.*)/(.*)#){      my $shorttwiki = $1 . $2;      my $twikilink =  $twiki_url . $shorttwiki;      my $filelink = $doc_url . $shorttwiki . &#39;/&#39; . $3;      my $filename = $3;      push @filesout, [$shorttwiki, $twikilink, $filelink, $filename];    }  }  print table({-border=&gt;1},    Tr([      th([&#39;Document&#39;, &#39;On TWiki&#39;]),      map{        td([            a({-href=&gt;$$_[2]},$$_[3]), a({-href=&gt;$$_[1]},$$_[0])        ])      } @filesout    ])  );}# perform search, checking if fname_only, cs, etc.,# stripping non-printable asciisub DoSearch{  my $path = $searchpath;  $path .= $twiki;  find({wanted=&gt;\&amp;wanted,    untaint=&gt;1,untaint_pattern=&gt;&#39;^([\040-\176]*)$&#39;,untaint_skip=&gt;1},    @twikipaths);  sub wanted{    # ,v files are twiki attachment versions -    # we only check current version    if($_ !~ /,v$/i and /.+\.$search_ext$/i){      if($cs &amp;&amp; /$searchterm/){        push @matched_files, $File::Find::name;      }      elsif(!$cs &amp;&amp; /$searchterm/i){        push @matched_files, $File::Find::name;      }      elsif(!$fname_only){        open(DOC, $File::Find::name)||          die &quot;Couldn&#39;t open $File::Find::name:$!\n&quot;;        THISFILE: while(my $line = &lt;DOC&gt;){          $line =~ s/[^\011\012\015\040-\176]//g;          if($cs &amp;&amp; $line =~ /$searchterm/){            close DOC;            push @matched_files, $File::Find::name;            last THISFILE;          }          elsif(!$cs &amp;&amp; $line =~ /$searchterm/i){            close DOC;            push @matched_files, $File::Find::name;            last THISFILE;          }        }      }    }  }}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>file-search: File search with minimum scrolling of output (parv)</title>
    <link>http://prlmnks.org/html/576937.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/576937.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/local/bin/perl$VERSION = &#39;0.01&#39;;use warnings; use strict;use File::Spec;use Pod::Usage;use Getopt::Long qw(:config gnu_compat no_ignore_case no_debug);my %default_opt =  (    &#39;show-default-opt&#39; =&gt; undef  , &#39;verbose&#39; =&gt; undef  , &#39;ignore-case&#39; =&gt; undef  , &#39;invert-match&#39; =&gt; undef  , &#39;bin-search&#39; =&gt; undef  , &#39;recursive&#39; =&gt; undef  , &#39;line-numbers&#39; =&gt; 1  , &#39;number-width&#39; =&gt; 4  , &#39;collapse-space&#39; =&gt; 1  , &#39;blank-line&#39; =&gt; undef  , &#39;highlight&#39; =&gt; 1  , &#39;cleanse-path&#39; =&gt; 1  , &#39;realpath&#39; =&gt; undef  , &#39;strip-curdir&#39; =&gt; 1  );my %opt = %default_opt;my ( $pattern , @files ) = process_args();my $re_flags = &#39;x&#39;;$re_flags .= &#39;i&#39; if $opt{&#39;ignore-case&#39;};($pattern) = map qr($_) , &quot;(?$re_flags)$pattern&quot; ;#  Used elsewhere in multiple places.my $spec = &#39;File::Spec&#39;;foreach my $file ( @files ){  search_file( $file , $pattern , \%opt );}exit;sub search_file{  my ( $file , $pattern , $opt ) = @_;  unless ( defined $pattern )  {    die &quot;Pattern is not defined\n&quot;;    return;  }  return if -l $file ;  if ( -d _ )  {    search_directory( $file , $pattern , $opt ) if $opt-&gt;{&#39;recursive&#39;} ;    return;  }  unless ( -T $file || $opt-&gt;{&#39;bin-search&#39;} )  {    warn &quot;Failed &#39;ASCII test&#39;, skipped $file\n&quot; if $opt-&gt;{&#39;verbose&#39;};    return;  }  if ( ! -f _ )  {    warn &quot;Non-regular file, skipped $file\n&quot; if $opt-&gt;{&#39;verbose&#39;};    return;  }  my $save;  return unless real_search( $file , \$save , $opt );  my $alt = get_alternate_name( $file , $opt ) || $file ;  $alt = make_term_bold( $alt , qr{.+} ) if $opt-&gt;{&#39;highlight&#39;} ;  printf &quot;==&gt;&gt;&gt;  %s\n&quot; , $alt;  print $save ;  print &quot;\n&quot;;}sub search_directory{  my ( $dir , $re , $opt ) = @_;  my $dh;  unless ( opendir $dh , $dir )  {    warn &quot;Cannot open directory $dir: $!&quot;;    return;  }  while ( my $file = readdir $dh )  {    next if $file eq $spec-&gt;curdir or $file eq $spec-&gt;updir ;    search_file( $spec-&gt;catfile( $dir , $file ) , $re , $opt );  }  return;}sub real_search{  my ( $file , $save , $opt ) = @_;  my ( $in , $close ) = open_file( $file );  return unless $in;  my ( $lines , $matches );  my $space = qr{ [ \t]+ }x;  my $result = result_format( $opt );  while ( my $line = &lt;$in&gt; )  {    if ( $opt-&gt;{&#39;invert-match&#39;} )    {      next if $line =~ m/$pattern/;    }    else    {      next if $line !~ m/$pattern/;    }    $lines++;    if ( $opt-&gt;{&#39;collapse-space&#39;} )    {      $line =~ s/^$space//;      $line =~ s/$space+$//;      $line =~ s/$space/ /g;    }    if ( !$opt-&gt;{&#39;invert-match&#39;}  &amp;&amp; $opt-&gt;{&#39;highlight&#39;} )    {      $line = make_term_bold( $line , $pattern );    }    $$save .= $result-&gt;( $. , $line );  }  $close-&gt;();  return $lines;}sub result_format{  my ( $opt ) = @_;  my $line_fmt = &#39;%&#39; . $opt-&gt;{&#39;number-width&#39;} . &quot;d  %s&quot;;  my $newline = $opt-&gt;{&#39;blank-line&#39;} ? &quot;\n&quot; : &#39;&#39;;  return    $opt-&gt;{&#39;line-numbers&#39;}    ? sub { sprintf $line_fmt , $_[0] , $_[1]  . $newline }    : sub { $_[1] . $newline } ;}sub make_term_bold{  my ( $in , $re ) = @_;  my ( $bold , $norm ) = ( &quot;\e[1m&quot; , &quot;\e[0m&quot; );  $in =~ s/($re)/$bold$1$norm/g;  return $in;}sub get_alternate_name{  my ( $name , $opt ) = @_;  return unless $opt;  if ( $opt-&gt;{&#39;realpath&#39;} || $opt-&gt;{&#39;strip-curdir&#39;} )  {    require Cwd;    import Cwd qw( abs_path getcwd );    $name = abs_path( $name );    $name = strip_current_dir( $name ) if $opt-&gt;{&#39;strip-curdir&#39;};    return $name;  }  return $name if !$opt-&gt;{&#39;cleanse-path&#39;};  return $spec-&gt;canonpath( $name );}sub strip_current_dir{  my ( $path ) = @_;  my $curdir = quotemeta getcwd();  $path =~ s{^ $curdir / }//x;  return $path;}sub open_file{  my ( $file ) = @_;  my $fh;  unless ( open $fh , &#39;&lt;&#39; , $file )  {    warn &quot;Cannot open $file: $!&quot;;    return;  }  return ( $fh , sub { close $fh or die &quot;Cannot close $file: $!&quot; } ) ;}sub process_args{  GetOptions  (    &#39;h|help&#39; =&gt; \$opt{&#39;help&#39;}  , &#39;D|show-default-opt&#39; =&gt; \$opt{&#39;show-default-opt&#39;}  , &#39;S|show-set-opt&#39;     =&gt; \$opt{&#39;show-set-opt&#39;}  , &#39;q|quiet&#39;  =&gt; sub { $opt{&#39;verbose&#39;} = undef }  , &#39;verbose+&#39; =&gt; \$opt{&#39;verbose&#39;}  , &#39;v|invert-match&#39; =&gt; \$opt{&#39;invert-match&#39;}  , &#39;i|ignore-case!&#39; =&gt; \$opt{&#39;ignore-case&#39;}  , &#39;r|recursive!&#39; =&gt; \$opt{&#39;recursive&#39;}  , &#39;B|bin-search&#39; =&gt; \$opt{&#39;bin-search&#39;}  , &#39;n|line-numbers!&#39;  =&gt; \$opt{&#39;line-numbers&#39;}  , &#39;w|number-width=i&#39; =&gt; \$opt{&#39;number-width&#39;}  , &#39;C|collapse-space!&#39;    =&gt; \$opt{&#39;collapse-space&#39;}  , &#39;b|blank-line!&#39; =&gt; \$opt{&#39;blank-line&#39;}  , &#39;H|highlight!&#39;  =&gt; \$opt{&#39;highlight&#39;}  , &#39;c|cleanse-path!&#39; =&gt; \$opt{&#39;cleanse-path&#39;}  , &#39;R|realpath!&#39;     =&gt; \$opt{&#39;realpath&#39;}  , &#39;s|strip-curdir!&#39; =&gt; \$opt{&#39;strip-curdir&#39;}  )    || die pod2usage(&#39;-exitval&#39;  =&gt; 2 , &#39;-verbose&#39;  =&gt; 1);  show_options( $opt{&#39;show-set-opt&#39;} ? \%opt : \%default_opt , &#39;exit&#39; )    if $opt{&#39;show-default-opt&#39;} or $opt{&#39;show-set-opt&#39;} ;  pod2usage(&#39;-exitval&#39; =&gt; 0 , &#39;-verbose&#39; =&gt; 3)    if $opt{&#39;help&#39;};  #  Check if any arguments remain which will be file names  pod2usage( &#39;-msg&#39; =&gt; &#39;&#39;            , &#39;-exitval&#39; =&gt; 1            , &#39;-verbose&#39; =&gt; 1          )    if scalar @ARGV &lt; 2;  return @ARGV;}sub show_options{  my ( $opt , $exit ) = @_;  my $out;  my $max = ( sort { $b &lt;=&gt; $a } map length( $_ ) , keys %{ $opt } )[0];  $max++;  my $fmt = &#39;%&#39; . $max . &quot;s: %s\n&quot;;  foreach my $k ( sort keys %{ $opt } )  {    my $v = $opt-&gt;{ $k };    $out .=      sprintf $fmt        , $k , ( !$v ? &#39;no&#39; : $v == 1 ? &#39;yes&#39; : $v ) ;  }  print $out;  exit 0 if $exit;}__END__=pod=head1 NAMEfile-search - Search for regular expressions in text files.=head1 SYNOPSISTo see default options ...  file-search -show-default-optTo search case-insensitively, recursively, highlight text matched,and preserve spaces &amp; tabs ...  file-search \    -ignore-case -recursive -highlight -nocollapse-space \    &#39;(pat|s)tern&#39; \    file(s) | directory(ies)=head1 DESCRIPTIONThe main reason for existence of this program is to minimizehorizontal scrolling by displaying the file name only once (on a lineof its own) before display of the lines matched, and by collapsingtabs and multiple spaces.  Other reasons are to strip the currentdirectory from the file name paths, and to have matched texthighlighted.Below are first few lines of output ofC&lt;file-search collapse file-search&gt; with default options, namelyhighlight the matched text (actual escpace character has been replacedby &#39;\e&#39; solely to keep this file &quot;text&quot;) ...  ==&gt;&gt;&gt;  \e[1mfile-search\e[0m    23  , &#39;\e[1mcollapse\e[0m-space&#39; =&gt; 1   131  if ( $opt-&gt;{&#39;\e[1mcollapse\e[0m-space&#39;} )   230  , &#39;C|\e[1mcollapse\e[0m-space!&#39; =&gt; \$opt{&#39;\e[1mcollapse\e[0m-space&#39;}   ...After the options have been taken into account, first parameter istaken to be a Perl regular experssion, and rest as the files to searchfor.  Directories are skipped if I&lt;-recursive&gt; option is not given.=head1 OPTIONSSome of the options can be negated by prefixing it with &quot;no&quot; as listedbelow; the last option will override preivous one.  For exmaple, IfI&lt;-norecursive&gt; is followed by I&lt;-recursive&gt;, files will berecursively searched when a directory is encountered.=head2 General Options=over 4=item B&lt;-help&gt; | B&lt;-h&gt;Shows this message.=item B&lt;-quiet&gt; | B&lt;-q&gt;Produce grave error messages only.=item B&lt;-show-default-opt&gt; | B&lt;-D&gt;Show default options.=item B&lt;-show-set-opt&gt; | B&lt;-S&gt;Show options given on command line.=item B&lt;-verbose&gt;Produce extra messages.  Specifying it multiple times causes more outputaccordingly.=back=head2 Search &amp; Display Options=over 4=item B&lt;-bin-search&gt; | B&lt;-B&gt;Search through binary files (as determined by L&lt;-T&gt; function).=item B&lt;-blank-line&gt; | B&lt;-b&gt;Put a blank line after each line where the pattern matches.B&lt;-noblank-line&gt; turns off this option.=item B&lt;-cleanse-path&gt; | B&lt;-c&gt;Do sane path clean up (for the file name to De displayed) withouttouching the file system.  See L&lt;File::Spec::canonpath()&gt;.B&lt;-nocleanse-path&gt; turns off this option.=item B&lt;-collapse-space&gt; | B&lt;-C&gt;Display lines after removing multiple spaces and tabs.B&lt;-nocollapse-space&gt; turns off this option.=item B&lt;-highlight&gt; | B&lt;-H&gt;Highlight the text which matches given pattern.B&lt;-nohighlight&gt; turns off this option.=item B&lt;-ignore-case&gt; | B&lt;-i&gt;Do case-insensitive pattern matching.B&lt;-noignore-case&gt; turns off this option.=item B&lt;-invert-match&gt; | B&lt;-v&gt;Show lines which do not match the given pattern(s).=item B&lt;-line-numbers&gt; | B&lt;-n&gt;Show line numbers.B&lt;-noline-numbers&gt; turns off this option.=item B&lt;-number-width&gt; I&lt;number&gt; | B&lt;-w&gt; I&lt;number&gt;Number of characters to use to format line numbers.=item B&lt;-realpath&gt; | B&lt;-R&gt;Display real path of a file.  See L&lt;realpath(3)&gt;.B&lt;-norealpath&gt; turns off this option.=item B&lt;-recursive&gt; | B&lt;-r&gt;If a directory is given as one of the files, search through all the files in it.B&lt;-norecursive&gt; turns off this option.=item B&lt;-strip-curdir&gt; | B&lt;-s&gt;Remove current directory path from file names displayed.B&lt;-nostrip-curdir&gt; turns off this option.=back=head1 DEPENDENCY=over 2=item *Cwd=item *File::Spec=item *Getopt::Long=back=head1 TO DO=over 2=item *Ability to see context of given number of lines.=item *Possibly use Term::* module(s) to highlight.=back=head1 BUGS=over 2=item *When highlighting is used, raw sequence is inserted in the output.That seems to work well for L&lt;xterm(1)&gt; in my environment, but may notelsewhere.  Piping output to C&lt;less -R&gt; seems to work too underCygwin-X in L&lt;xterm(1)&gt;.=back=head1 SEE ALSOL&lt;grep(1)&gt;=head1 AUTHOR, LICENSE, DISTRIBUTION, ETC.Parv, parv_@yahoo.comMODIFIED:  Oct 07 2006This software is free to be used in any form only if proper credit isgiven.  I am not responsible for any kind of damage or loss.  Use itat your own risk.=cut&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Zedulator - a tiled, integrated CB/PM/Web client (jZed)</title>
    <link>http://prlmnks.org/html/576148.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/576148.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -wuse strict;print &quot;\nEnter a pmurl or nothing for www.perlmonks.org : &quot;;my $pmurl = &lt;&gt;;chomp($pmurl);my %v;($v{main},$v{search},$v{talk},$v{help})= split /\n\n/, join &#39;&#39;, &lt;DATA&gt;;print &quot;\nmodifying pmurl to $pmurl ... \n&quot; if $pmurl;$v{main} =~ s/www.perlmonks.org/$pmurl/g if $pmurl;for my $section(qw(help main search talk)) {    my $fn = &quot;zedulator.$section.html&quot;;       $fn =~ s/\.main//;    print &quot;creating $fn ... \n&quot;;    open(my $fh,&quot;&gt;$fn&quot;);    print $fh  $v{$section};    close $fh;}print &quot;all done! ... \n&quot;;__DATA__&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Frameset//EN&quot;&gt;&lt;html&gt;&lt;head&gt;    &lt;title&gt;Perlmonks zedulator&lt;/title&gt;    &lt;!--         jZed&#39;s hack of tye&#39;s hack of fullpage chat    --&gt;    &lt;link type= &quot;text/css&quot; rel=&quot;stylesheet&quot;          href= &quot;http://www.perlmonks.org/css/common.css&quot;    /&gt;    &lt;link rel=&quot;icon&quot; href=&quot;http://www.perlmonks.org/favicon.ico&quot; /&gt;    &lt;script language=&quot;JavaScript&quot;&gt;&lt;!--    var zed = {        shortcut : {            &quot;cb60&quot;      : &quot;http://mini-cb60.flux8.com/&quot;,            &quot;cbhistory&quot; : &quot;http://nbpfaus.net/~pfau/cbhistory.cgi?site=PM&quot;,            &quot;nn&quot;        : &quot;http://www.perlmonks.org/?node=newest nodes&quot;,            &quot;zed&quot;       : &quot;zedulator.help.html&quot;,            &quot;float&quot;     : &quot;javascript:parent.zed.popupwin(470,360)&quot;            /* add your own shortcuts here */        },        search : function(form) {            var url = form.display_node.value;            var pos = url.indexOf(&quot;/&quot;);            if(pos==0){                var action_name = url.substring(1,url.length);                url = this.shortcut[action_name] || action_name;                form.action = url;            }            else {                form.action=&quot;http://www.perlmonks.org/?&quot;            }            if( url == undefined ) { return false; }            form.node.value = url;            form.display_node.value = &#39;&#39;;        },        talk : function(form) {            var url = form.display_message.value;            if( url == undefined ) { return false; }            form.action=&quot;http://www.perlmonks.org/?&quot;            form.message.value = url;            form.display_message.value = &#39;&#39;;        },        popupwin : function(w,h) {            var remote;            var main;            window.name = &quot;main&quot;;            settings = &#39;height=&#39;+h+&#39;,width=&#39;+w+&#39;,scrollbars=auto,toolbar=no,&#39;                   +&#39;location=no,status=yes,menubar=no,left=0,top=0&#39;;            remote = window.open(&#39;zedulator.html&#39;,&#39;remote&#39;,settings);        }    };    // --&gt;&lt;/script&gt;&lt;/head&gt;&lt;frameset rows=&quot;30,24,*&quot;&gt;    &lt;frameset cols=&quot;50%,50%&quot;&gt;        &lt;frame  id=&quot;talk&quot; scrolling=&quot;no&quot; src=&quot;zedulator.talk.html&quot; /&gt;        &lt;frame  id=&quot;search&quot; scrolling=&quot;no&quot; src=&quot;zedulator.search.html&quot; /&gt;    &lt;/frameset&gt;    &lt;frameset cols=&quot;50%,50%&quot;&gt;        &lt;frame src=&quot;http://www.perlmonks.org/?displaytype=raw;type=superdoc;node=privatemessages&quot; /&gt;        &lt;frame src=&quot;http://www.perlmonks.org/?displaytype=raw;node=showotherusers&quot; /&gt;    &lt;/frameset&gt;    &lt;frameset rows=&quot;50%,50%&quot;&gt;       &lt;frame src=&quot;http://www.perlmonks.org/?displaytype=raw;node=showchatmessages;&quot; scrolling=&quot;auto&quot; /&gt;       &lt;frame name=&quot;browse_frame&quot; src=&quot;zedulator.help.html&quot; scrolling=&quot;auto&quot; /&gt;    &lt;/frameset&gt;    &lt;noframes&gt;       &lt;p&gt;No Frames?           &lt;a href=&quot;http://www.perlmonks.org/?displaytype=raw;node=showchatmessages&quot;&gt;Chat Here&lt;/a&gt;       &lt;/p&gt;    &lt;/noframes&gt;&lt;/frameset&gt;&lt;/html&gt;&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;&lt;html&gt;&lt;head&gt; &lt;title&gt;Zedulator Search&lt;/title&gt;&lt;/head&gt;&lt;body bgColor=&quot;black&quot;&gt;&lt;form id=&quot;search_form&quot;      method=&quot;get&quot;      enctype=&quot;application/x-www-form-urlencoded&quot;      target=&quot;browse_frame&quot;      onSubmit=&quot;parent.zed.search(this);&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;node&quot; value=&quot;&quot; /&gt;&lt;input type=&quot;text&quot; name=&quot;display_node&quot;  size=22 maxlength=80 /&gt;&lt;input type=&quot;submit&quot; name=&quot;go_button&quot; value=&quot;search&quot; /&gt;&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;&lt;html&gt;&lt;head&gt; &lt;title&gt;Zedulator Talk&lt;/title&gt;&lt;/head&gt;&lt;body bgColor=&quot;black&quot;&gt;&lt;iframe name=&quot;devnull&quot; style=&quot;display:none&quot;&gt;&lt;/iframe&gt;&lt;form method=&quot;post&quot; enctype=&quot;application/x-www-form-urlencoded&quot;      target=&quot;devnull&quot;      onSubmit=&quot;parent.zed.talk(this);&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;node_id&quot; value=&quot;163868&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;op&quot; value=&quot;message&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;message&quot; value=&quot;&quot; /&gt;&lt;input type=&quot;text&quot; name=&quot;display_message&quot;  size=22 maxlength=240 /&gt;&lt;input type=&quot;submit&quot; name=&quot;message_send&quot; value=&quot;talk&quot; /&gt;&lt;/form&gt;&lt;/body&gt;&lt;/html&gt;&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot;&gt;&lt;html&gt;  &lt;head&gt;    &lt;title&gt;Zedulator Help&lt;/title&gt;  &lt;/head&gt;&lt;style&gt;* {    background-color:black;    color:lightgray;    font-family:Verdana,Sans-Serif;    font-size:small;}.heading {    font-weight:bold;    font-size:1.25em;    margin-bottom: 0px;    margin-right: 3em;    color:orange;}td {    padding-right:2em;     border-bottom:1px solid gray;}.menu a{ color:lightblue; }.menu  { margin-bottom:0.5em; }dt, dt a { font-weight:bold; color:orange; }dd { margin-left:1em; margin-bottom:0.5em; }pre, .intro b { color:orange; }.intro a { color:lightblue; }&lt;/style&gt;  &lt;body&gt;&lt;table&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; class=&quot;intro&quot;&gt;&lt;p&gt;&lt;b&gt;ZEDULATOR&lt;/b&gt; tiles your browser with frames as shown in the diagram. Use the frame borders to contract or expand the frames as needed.&lt;/p&gt;&lt;p&gt;You can search using PerlMonks shortcuts or go directly to any URI using zedulator shortcuts. (see &lt;a href=&quot;#searching&quot;&gt;searching&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;The search results are, by default, targeted to the browsing frame. Links in the private messages, other users, and chat frames can also be targeted to the browsing frame.(see &lt;a href=&quot;#displaying&quot;&gt;targeting&lt;/a&gt;)&lt;/p&gt;&lt;p&gt;You can customize shortcuts, frames, and targeting. (see &lt;a href=&quot;#tiling&quot;&gt;customizing&lt;/a&gt;)&lt;/p&gt;&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;&lt;pre style=&quot;font-family:monospace&quot;&gt;+---------------+---------------+|   talk input  | search input  ++---------------+---------------+| private msgs  | other users   |+---------------+---------------+|                               ||        chat frame             ||                               |+-------------------------------+|                               ||      browsing frame           ||                               |+-------------------------------+&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;dl&gt;&lt;dt&gt;&lt;a name=&quot;searching&quot;&gt;Zedulator: search shortcuts&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;The default search goes directly to Perlmonks search. However, if the search term starts with a forward slash, it gets treated as a &lt;i&gt;zedulator&lt;/i&gt; search and uses the built-in or custom zedulator shortcuts and goes directly to the requested page, bypassing Perlmonks.  Custom shortcuts can be calls to local javaScript functions, see the shortcut definitions in zedulator.html.&lt;br /&gt;&lt;table&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;/zed&lt;/td valign=&quot;top&quot;&gt;&lt;td valign=&quot;top&quot;&gt;open this help page&lt;/td valign=&quot;top&quot;&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;gogle://&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;any standard PerlMonks shortcut like pad://, cpan:, etc.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;/cb60&lt;/td valign=&quot;top&quot;&gt;&lt;td valign=&quot;top&quot;&gt;open mini-cb60.flux8.com&lt;/td valign=&quot;top&quot;&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;/nn&lt;/td valign=&quot;top&quot;&gt;&lt;td valign=&quot;top&quot;&gt;open Newest Nodes&lt;/td valign=&quot;top&quot;&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;/float&lt;/td valign=&quot;top&quot;&gt;&lt;td valign=&quot;top&quot;&gt;float zedulator in a chromeless window&lt;/td&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;/filepath&lt;/td valign=&quot;top&quot;&gt;&lt;td valign=&quot;top&quot;&gt;open a local file&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;dt &gt;&lt;a name=&quot;displaying&quot;&gt;Zedulator : targeting links to the bottom frame&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;table&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; nowrap&gt;searches&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;automatically appear in bottom frame&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot; nowrap&gt;links in other zedulator frames&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;drag and drop the link to the search input box and submit the search&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;browser bookmarks&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;copy the link, paste it into the search input box and submit the search&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;dt&gt;&lt;a name=&quot;tiling&quot;&gt;Zedulator : customizing&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;table&gt;&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;create custom search shortcuts&lt;/td&gt;&lt;td &gt;edit the shortcut/url associations in zedulator.html&lt;/td&gt;&lt;/tr&gt;&lt;td valign=&quot;top&quot;&gt;start with page other than zedulator help&lt;/td&gt;&lt;td&gt;edit the browse_frame.src in zedulator.html&lt;/td&gt;&lt;/tr&gt;&lt;td valign=&quot;top&quot;&gt;permanent resize/move/ delete frame&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;edit framesets in zedulator.html&lt;/td&gt;&lt;/tr&gt;&lt;td valign=&quot;top&quot;&gt;retarget search to tab or window&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;edit the form target in zedulator.search.html&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/dl&gt;  &lt;/body&gt;&lt;/html&gt;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Guest Cleanup (Maze)</title>
    <link>http://prlmnks.org/html/575684.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/575684.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl#reguest.pl#by Chris Monahan#this is free software, you can distribute it under the same terms as perl itselfuse warnings;use strict;my @dirs = (&quot;Music&quot;, &quot;Pictures&quot;, &quot;Documents&quot;, &quot;Desktop&quot;);print &quot;preserving guest content under a timestamped folder \n \n&quot;;my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdist) = gmtime(time);  $min++; $hour++; $mday++; $sec++; $mon++; $year++; my $count = 0; my @mkdir = ( &quot;$year:$mon:$mday&quot;, &quot;$hour:$min:$sec&quot;);chdir (&quot;/home/guest-content&quot;);while ($count ne @mkdir){system &quot;mkdir $mkdir[$count]&quot;;chdir &quot;$mkdir[$count]&quot;;$count ++;}chdir (&quot;/home&quot;);$count = 0;while ($count ne @dirs){my $dest = &quot;guest-content/$year:$mon:$mday/$hour:$min:$sec/&quot;;#unless (system (&quot;mv guest/$dirs[$count]/ $dest&quot;);#){#}$count++;}print &quot;purging configuration settings \n &quot;;system (&quot;rm -R  guest&quot;);print &quot;restoring guest home \n &quot;;system (&quot;mkdir guest&quot;);system (&quot;cp -R default/* guest&quot;);$count = 0;while ($count ne @dirs){system (&quot;mkdir guest/$dirs[$count]&quot;);$count++;}print &quot;restoring guest account password and ownership details \n&quot;;#system(&quot;usermod -p password guest&quot;);system (&quot;chown -R guest:guest guest&quot;);print &quot;done \n&quot;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Screwed tree scanning (Maze)</title>
    <link>http://prlmnks.org/html/575666.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/575666.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl#this is free software, you can distribute it under the same terms as perl itself# scanfiletree pre alpha#by Christopher Monahan # scans a filetree as defined by a set of parameters passed to it # and returns it in the preferred format  eg: XMLuse warnings;use strict;# use XML::Simple;use Cwd;use Data::Dumper; #beginning of variable declarationslocal $::path;                 #scalar for the path when in string formlocal @::path;                 #array for the path when in list formlocal @::direntry;           #array for holding the directory entries of the directory being scanned # local %::params;               #basic parameters passed to scantree via arguments and the configurationlocal $::root;                 #the virtual root to start scanning fromlocal $::troot;                #the true root to start scanning fromlocal $::outputfile;           #the name of the file that will receive the fatefull treedata# local %::handler_self_params;  #parameters with some extrapolation involved destined for controlling the handler subroutines# local $::mainflag;             #the main argument passed to scantree# local $::regdir[0] = 1;        #the value for the register sublocal %::treehash;             #the hash the tree will be stored inlocal $::status;               #here to stop things if things go sour, or tell a particular stage to implement advanced mechanisms# end of variable declarations#begin sub definitionssub scan { #for scanning arrays in generalmy @hunt = split (/&amp;/, $_[0]);if ($#hunt ne 0){my $count = 0;my %founda;my $length = 0;while ($count != @hunt){$founda{$count} = grep {/$hunt[$count]/} @_;$length = $length + length($founda{$count});$count++;}return $length; #? will this work ?}else{my @foundb = 0;@foundb = grep {/$_[0]/} @_;return $#foundb;}}### eatdir section# sub handle_eatdir_params {#  if (defined (%::handler_self_params{&quot;eatdir&quot;}{&quot;split&quot;})) {#  @::path = split (/\//, $_[0])#  } # if (defined (%::handler_self_params{&quot;eatdir&quot;}{&quot;register&quot;})){# my $count = 0;# while ($count ne $#path){# if ($count == 0){# register;# $count++# }# }# if (%::handler_self_params {&quot;eatdir&quot;} {&quot;register&quot;}){# return @path# }# else {# return $_[0]# }# }sub eatdir {my $seendir = $_[0];my @direntries;my $direntry;# my @seendir = handle_eatdir_params(@_);# my @seendir = @_;# unless ($#seendir eq 0) {my $seendir = join (&quot;/&quot;, @seendir)}# else {my $seendir = $seendir[0]}opendir SEENDIR, $seendir;@direntries = readdir SEENDIR;closedir SEENDIR;$direntries[0] = &quot;pie&quot;;$direntries[1] = &quot;pie&quot;;foreach $direntry (@direntries){if (-d &quot;$seendir/$direntry&quot;){eatdir (&quot;$seendir/$direntry&quot;)}}my $direntries = join ( &#39;:&#39; , @direntries);handle_direntries(&quot;${seendir}:${direntries}&quot;);}### direntry subs ###sub handle_direntries{&amp;::handle_direntries_params($_[0]);&amp;::handle_direntries_main;}sub handle_direntries_params {($::path, @::direntry) = split (/:/, $_[0]);@::path = split (/\//, $::path);# more argument parsing for options here later}sub handle_direntries_main{my $count = 0;local %::pathline;while ($count ne $#::path){$::pathline{&quot;$::path[$count]:$count&quot;} = {};$count ++;}$count = 0;while ($count ne $#::direntry){unless (-d &quot;$::path/$::direntry[$count]&quot;){ $::pathline{&quot;$::path[$#::path]:$#::path&quot;}{&quot;$::direntry[$count]&quot;} = $::FileLabel; }$count ++; }$count = $#::path;while ($count gt 0){my $lcount = $count - 1;$::pathline{&quot;$::path[$lcount]:$lcount&quot;}{&quot;$::path[$count]&quot;} = $::pathline{&quot;$::path[$count]&quot;};delete $::pathline{&quot;$::path[$count]&quot;};$count --;}local $::mergecount;local $::mergepoint;&amp;handle_direntries_merge;}sub mergepoint{if (defined $_[0]){my $val = join (&#39;{&#39;, $::mergepoint,$_[0]); #}$val = &quot;$val}&quot;;$::mergepoint = $val;return $val;}else{return &#39; &#39;;}}sub handle_direntries_merge{no strict &#39;refs&#39;;# my $merge = $_[0];# my $treeref = $_[1];if (defined $_[0]){my $mergepoint = mergepoint($_[0]);}else {my $mergepoint = mergepoint;}my @mergekeys = keys %::pathline$mergepoint};my $mergekey;foreach ($mergekey, @mergekeys){if (exists %::treehash$mergepoint{$mergekey}){$::mergecount++;handle_direntries_merge($mergekey);$::mergecount - 1;}else {$::treehash$mergepoint{$mergekey} = $::pathline$mergepoint{$mergekey};}}}#here should lie some code for taking the hash of a particular pathline, and merging it in with the main treehash#at the moment just dump for diagnostic purposes - comment out the above of the  and uncomment the following line to get some tacky functionality# print Dumper(%{$_[0]});# sub handle_direntries_main_alt{# my $count = 1;# my $treeref = \%::treehash;# while ($count != $#::path){# $treeref = \%$treeref-&gt;{$::path[$count]};# $count++;# next if $count == $#::path;# unless (defined($treeref-&gt;{$::path[$count]})) {# $treeref-&gt;{$::path[$count]} = {&quot;$::DirLabel&quot; =&gt; $::path[$count]}# }# $count = 0;# while ($count != $#::direntries){# $treeref -&gt; {$::path[$count]}{$::direntry[$count]} = &quot;$::FileLabel&quot; unless $treeref -&gt; {$::path[$count]}{$::direntry[$count]} = &quot;$::DirLabel&quot;;# } # }# }# sub register { #sub for keeping track of directories: eg - making sure we are not in a recursive symlink loop, could use inode numbers here# if(){# $::regdir[$::regdir[0]]=&quot;first $main::regdir[$::regdir[0]]&quot;# }### stage subs ###sub begin{print &quot;Ready to scan $::troot and deposit the resulting XML into $$::outputfile \n shall I proceed? (y/n)\n&quot;;my $confirm = &lt;STDIN&gt;;if ($confirm =~ /y|Y/){chroot($::troot);&amp;eatdir($::troot);}else{die &quot;it was a pleasure anyway \n&quot;;$::status = 0;}%::treehash = (&quot;begin&quot;,&quot;+&quot;,&quot;root&quot;,&quot;/$::root&quot;);}sub handle_main_params{ #{ # this bits a stub# $::mainflag = \$ARGV[0] unless defined(@_);# # if ($::mainflag =~ /-x|--routine/){# # ## routine scheduling bit# # }# elsif ($::mainflag eq &quot;-c&quot;) {# ##configuration bit# }# else {$::root = \$ARGV[0];$::outputfile = \$ARGV[1];my $cd = cwd;unless ($::root =~ /[^\/]/){ $::troot = &quot;$cd\/$$::root&quot;; }else {$::troot = $$::root; }}sub finish{#again another stubprint Dumper(%::treehash);}# end of subroutine definitions#main$::FileLabel = &quot;File&quot;;# $::DirLabel = &#39;+&#39;;handle_main_params ();begin();finish();print &#39;we have reached the end 2 \n&#39;;## end of mainh&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Latin Verb Conjugator (Minimiscience)</title>
    <link>http://prlmnks.org/html/574292.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/574292.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -w#conjugate.pl, v.1.0#Created by John T. Wodder II#Last edited: 21 Sept 2006 by John Wodder#This script will create a synopsis of a Latin verb &amp; output it as a LaTeX#document.use strict;use Switch;my($tmp, $base, $vowel, $vowel2, $stemTwo, $stemThree, $conj, $trans, $first, $subj, $extPerson, $person, $personal, $passive, $perfect, $sum, $adj);my %short = (&#39;\\=o&#39;, 1, &#39;m&#39;, 1, &#39;s&#39;, 0, &#39;t&#39;, 1, &#39;mus&#39;, 0, &#39;tis&#39;, 0, &#39;nt&#39;, 1, &#39;r&#39;, 1, &#39;ris/re&#39;, 0, &#39;tur&#39;, 0, &#39;mur&#39;, 0, &#39;min\\=\\i&#39;, 0, &#39;ntur&#39;, 1, &#39;or&#39;, 1, &#39;te&#39;, 0);my $word = qr/[[:alpha:]\\={}]+/;my $long = qr/\\=\{?\\?([aeio])\{?\}?/i;my $lineTerm = &quot; \\\\\n&quot;;sub append { my($pre, $post, $opt) = @_; # Bits guide for $opt: # 1 - Use &#39;m&#39; instead of &#39;\=o&#39; # 2 - Use -i\=o &amp; -iunt endings (Use is determined at runtime) # 4 - Use -int instead of -unt (only applies to fut. perf. act. indic.) $opt = 0 unless defined $opt; $post = &#39;m&#39; if $post eq &#39;\\=o&#39; &amp;&amp; ($opt &amp; 1); if ($pre =~ /$long$/o) {  $pre =~ s/$long$/$1/o if $short{$post};  $pre =~ s/i$/iu/io if $post =~ /^nt/o &amp;&amp; ($opt &amp; 2);  $pre =~ s/a$//io if $post =~ /^(\\=)?o/o; } else {  $pre =~ s/e$/i/io;  if ($post =~ /^nt/) {   if ($opt &amp; 2) {    $pre =~ s/i$/iu/o;   } elsif (!($opt &amp; 4)) { # 4 applies to the fut. perf. act. indic.    $pre =~ s/i$/u/o;   }  } elsif ($post =~ /^(\\=)?o/o &amp;&amp; !($opt &amp; 2)) {   $pre =~ s/i$//o;  } elsif ($post eq &#39;ris/re&#39;) {   $pre =~ s/i$/e/io;  } } print $pre, $post;}print &quot;Enter the four principal parts of the verb you wish to conjugate,\nseparated by spaces, with macrons denoted LaTeX-style:\nEnter `quit&#39; to exit.\n&gt; &quot;;VERB: while (&lt;STDIN&gt;) { if (/^(($word)([ie]?)\\=o),?\s+\2(e|$long)re,?\s+($word)\\=\{?\\i\{?\}?,?\s+($word)us$/io) { # (\\=ur|\\=\{u\}r)?  ($first, $base, $vowel, $stemTwo, $stemThree) = ($1, $2, $4, $6, $7);  $trans = $7 !~ /(\\=ur|\\=\{u\}r)$/i;  $stemThree =~ s/(\\=ur|\\=\{u\}r)$//i unless $trans;  switch ($vowel) {   case m/^\\=\{?a\}?$/i {$conj = 1; $subj = &#39;\\=e&#39;; $vowel2 = &#39;\\=a&#39;; }   case m/^\\=\{?e\}?$/i {$conj = 2; $subj = &#39;e\\=a&#39;; $vowel2 = &#39;\\=e&#39;; }   case m/^e$/i {($conj, $subj, $vowel2) = $3 ? (4, &#39;i\\=a&#39;, &#39;i\\=e&#39;) : (3, &#39;\\=a&#39;, &#39;\\=e&#39;); }   case m/^\\=\{?\\i\{?\}?$/i {$conj = 5; $subj = &#39;i\\=a&#39;; $vowel2 = &#39;i\\=e&#39;; }   else {die(&quot;An error has occurred in parsing the stem vowel.\n&quot;); }  }  last VERB; } elsif (/^($word)\\=\{?o\}?$/io) {  my $a = $1;  print &#39;Is the verb a standard first-conjugation verb? (y/n): &#39;;  $tmp = &lt;STDIN&gt;;  if ($tmp =~ /^y/i) {   ($base, $conj, $vowel, $subj, $trans, $stemTwo, $stemThree, $first, $vowel2) = ($a, 1, &#39;\\=a&#39;, &#39;\\=e&#39;, 1, $a.&#39;\\=av&#39;, $a.&#39;\\=at&#39;, $a.&#39;\\=o&#39;, &#39;\\=a&#39;);   last VERB;  } else {print &quot;Enter the four principal parts.\n&quot;; } } elsif (/^q(uit)?$/io) {exit; } elsif ($_ eq &quot;`quit&#39;\n&quot;) {print &quot;I didn&#39;t mean that literally.\n&quot;; } else {print &quot;Quid?\n&quot;; } print &#39;&gt; &#39;;}print &quot;In what person &amp; number do you wish to conjugate this verb?\n&gt; &quot;;PERSON: while(defined($extPerson = &lt;STDIN&gt;)) { switch ($extPerson) {  case /^(1(st)?|first)(\s*person)?,?\s*s(ing(\.|ular)?)?$/io {   ($person, $personal, $passive, $perfect, $sum, $adj) = (0, &#39;\\=o&#39;, &#39;r&#39;, &#39;\\=\\i&#39;, &#39;sum&#39;, &#39;us/a/um&#39;);   last PERSON;  } case /^(2(nd)?|second)(\s*person)?,?\s*s(ing(\.|ular)?)?$/io {   ($person, $personal, $passive, $perfect, $sum, $adj) = (1, &#39;s&#39;, &#39;ris/re&#39;, &#39;ist\\=\\i&#39;, &#39;es&#39;, &#39;us/a/um&#39;);   last PERSON;  } case /^(3(rd)?|third)(\s*person)?,?\s*s(ing(\.|ular)?)?$/io {   ($person, $personal, $passive, $perfect, $sum, $adj) = (2, &#39;t&#39;, &#39;tur&#39;, &#39;it&#39;, &#39;est&#39;, &#39;us/a/um&#39;);   last PERSON;  } case /^(1(st)?|first)(\s*person)?,?\s*p(l(\.|ur(\.|al)?)?)?$/io {   ($person, $personal, $passive, $perfect, $sum, $adj) = (3, &#39;mus&#39;, &#39;mur&#39;, &#39;imus&#39;, &#39;sumus&#39;, &#39;\\=\\i/ae/a&#39;);   last PERSON;  } case /^(2(nd)?|second)(\s*person)?,?\s*p(l(\.|ur(\.|al)?)?)?$/io {   ($person, $personal, $passive, $perfect, $sum, $adj) = (4, &#39;tis&#39;, &#39;min\\=\\i&#39;, &#39;istis&#39;, &#39;estis&#39;, &#39;\\=\\i/ae/a&#39;);   last PERSON;  } case /^(3(rd)?|third)(\s*person)?,?\s*p(l(\.|ur(\.|al)?)?)?$/io {   ($person, $personal, $passive, $perfect, $sum, $adj) = (5, &#39;nt&#39;, &#39;ntur&#39;, &#39;\\=erunt&#39;, &#39;sunt&#39;, &#39;\\=\\i/ae/a&#39;);   last PERSON;  } case /^q(uit)?$/io {exit; }  else {print &quot;Quid?\n&quot;; } } print &#39;&gt; &#39;;}my $file = $first;$file =~ s/[\\={}]//g;open(FILE, &#39;&gt;&#39;, &quot;$file.tex&quot;);select FILE;print &quot;\\documentclass{article}\\begin{document}\\title{Synopsis of \\emph{$first}, $extPerson}\\author{\\texttt{conjugate.pl}, v.1.0}\\maketitle\n\\begin{center}\\begin{tabular}{l &quot;, ($trans ? &quot;c c}\n &amp; \\textbf{Active} &amp; \\textbf{Passive} \\\\ \\hline\n\\multicolumn{3&quot; : &quot;c}\n\\multicolumn{2&quot;), &quot;}{c}{\\textbf{Indicative Mood}} \\\\ \\hline\n&quot;;print &#39;Present &amp; &#39;, $base; append($vowel, $personal, ($conj&gt;3) ? 2 : 0);if ($trans) { print &#39; &amp; &#39;, $base; append($vowel, ($person==0) ? &#39;or&#39; : $passive, ($conj&gt;3) ? 2 : 0);}print $lineTerm, &#39;Imperfect &amp; &#39;, $base, $vowel2;append(&#39;b\\=a&#39;, $personal, 1);if ($trans) { print &#39; &amp; &#39;, $base, $vowel2; append(&#39;b\\=a&#39;, $passive);}print $lineTerm, &#39;Future &amp; &#39;, $base;if ($conj &lt; 3) { print $vowel; append(&#39;bi&#39;, $personal);} else { append(($person==0) ? $subj : $vowel2, $personal, 1);}if ($trans) { print &#39; &amp; &#39;, $base; if ($conj &lt; 3) {  print $vowel;  append(&#39;bi&#39;, ($person==0) ? &#39;or&#39; : $passive); } else {  append(($person==0) ? $subj : $vowel2, $passive); }}print $lineTerm, &#39;Perfect &amp; &#39;, $stemTwo, $perfect;print &#39; &amp; &#39;, $stemThree, $adj, &#39; &#39;, $sum if $trans;print $lineTerm, &#39;Pluperfect &amp; &#39;, $stemTwo;append(&#39;er\\=a&#39;, $personal, 1);if ($trans) { print &#39; &amp; &#39;, $stemThree, $adj, &#39; &#39;; append(&#39;er\\=a&#39;, $personal, 1);}print $lineTerm, &#39;Future Perfect &amp; &#39;, $stemTwo;append(&#39;eri&#39;, $personal, 4);if ($trans) { print &#39; &amp; &#39;, $stemThree, $adj, &#39; &#39;; append(&#39;eri&#39;, $personal);}print $lineTerm, &#39;\\multicolumn{&#39;, $trans+2, &quot;}{c}{\\textbf{Subjunctive Mood}} \\\\ \\hline\n Present &amp; &quot;, $base;append($subj, $personal, 1);if ($trans) { print &#39; &amp; &#39;, $base; append($subj, $passive);}print $lineTerm, &#39;Imperfect &amp; &#39;, $base, $vowel;append(&#39;r\\=e&#39;, $personal, 1);if ($trans) { print &#39; &amp; &#39;, $base, $vowel; append(&#39;r\\=e&#39;, $passive);}print $lineTerm, &#39;Perfect &amp; &#39;, $stemTwo;append(&#39;er\\=\\i{}&#39;, $personal, 1);if ($trans) { print &#39; &amp; &#39;, $stemThree, $adj, &#39; &#39;; append(&#39;s\\=\\i{}&#39;, $personal, 1);}print $lineTerm, &#39;Pluperfect &amp; &#39;, $stemTwo;append(&#39;iss\\=e&#39;, $personal, 1);if ($trans) { print &#39; &amp; &#39;, $stemThree, $adj, &#39; &#39;; append(&#39;ess\\=e&#39;, $personal, 1);}print $lineTerm, &#39;\\multicolumn{&#39;, $trans+2, &quot;}{c}{\\textbf{Infinitives}} \\\\ \\hline\n Present &amp; &quot;, $base, $vowel, &#39;re&#39;;print &#39; &amp; &#39;, $base, ($conj != 3 &amp;&amp; $conj != 4) ? ($vowel, &#39;r\\=\\i&#39;) : &#39;\\=\\i&#39; if $trans;print $lineTerm, &#39;Perfect &amp; &#39;, $stemTwo, &#39;isse&#39;;print &#39; &amp; &#39;, $stemThree, &#39;us/a/um esse&#39; if $trans;print $lineTerm, &#39;Future &amp; &#39;, $stemThree, &#39;\\=urus/a/um esse&#39;;print &#39; &amp; ---&#39; if $trans;print $lineTerm, &#39;\\multicolumn{&#39;, $trans+2, &quot;}{c}{\\textbf{Participles}} \\\\ \\hline\n Present &amp; &quot;, $base, $vowel2, &#39;ns, -&#39;;$vowel2 =~ s/\\=//;print $vowel2, &#39;ntis&#39;;print &#39; &amp; ---&#39; if $trans;print $lineTerm, &#39;Perfect &amp; ---&#39;;print &#39; &amp; &#39;, $stemThree, &#39;us/a/um&#39; if $trans;print $lineTerm, &#39;Future &amp; &#39;, $stemThree, &#39;\\=urus/a/um&#39;;print &#39; &amp; &#39;, $base, $vowel2, &#39;ndus/a/um&#39; if $trans;print $lineTerm, &#39;\\multicolumn{&#39;, $trans+2, &quot;}{c}{\\textbf{Imperatives}} \\\\ \\hline\n &amp; &quot;, $base, $vowel, &#39;, &#39;, $base;append($vowel, &#39;te&#39;);if ($trans) { print &#39; &amp; &#39;, $base, $vowel, &#39;re, &#39;, $base; append($vowel, &#39;min\\=\\i&#39;);}if ($trans) { print &lt;&lt;EOT;$lineTerm &amp; \\textbf{Gerunds} &amp; \\textbf{Supines} \\\\ \\hlineGenitive &amp; $base${vowel2}nd\\=\\i &amp; --- \\\\Dative &amp; $base${vowel2}nd\\=o &amp; --- \\\\Accusative &amp; $base${vowel2}ndum &amp; ${stemThree}um \\\\Ablative &amp; $base${vowel2}nd\\=o &amp; ${stemThree}\\=u \\\\EOT} else { print &lt;&lt;EOT;$lineTerm \\multicolumn{2}{c}{\\textbf{Gerunds}} \\\\ \\hlineGenitive &amp; $base${vowel2}nd\\=\\i \\\\Dative &amp; $base${vowel2}nd\\=o \\\\Accusative &amp; $base${vowel2}ndum \\\\Ablative &amp; $base${vowel2}nd\\=o \\\\\\multicolumn{2}{c}{\\textbf{Supines}} \\\\ \\hlineAccusative &amp; ${stemThree}um \\\\Ablative &amp; ${stemThree}\\=u \\\\EOT}print &#39;\\end{tabular}\\end{center}\\end{document}&#39;;close; select STDOUT;print &quot;Done!\nThe synopsis has been saved to $file.tex.\nWould you like to typeset it now? (y/n): &quot;;$tmp = lc getc;if ($tmp eq &#39;y&#39;) { system(&quot;pdflatex $file.tex&quot;); # NOT pdfetex system(&quot;open $file.pdf&quot;) unless $?;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>BinBot - Find .NZB links in RSS feeds. (iamjafi)</title>
    <link>http://prlmnks.org/html/574044.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/574044.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl# Binbot.pl: Reads a list of rss feeds from a file and searches for keywords, writing matching &lt;title&gt; and# &lt;link&gt; elements to a new rss file.# I use it for tracking USENET binaries, but it could be used for any pupose.#Files: #urls.txt - A text file consisting of URLs to rss feeds, one per line. #e.g. http://www.whatever.com/some-rss.rss#keywords.txt - A text file consisting of keywords to search for, one per line.# 9/24/06 - switched to URI::Fetch (from LWP::Simple) to allow reading gzip compressed feeds.use strict;use warnings;use XML::RSS::Parser::Lite;use XML::RSS::SimpleGen;use URI::Fetch;#variablesmy $url_file = &quot;urls.txt&quot;;my $rss_file = &quot;binbot.rss&quot;;my $keyword_file = &quot;keywords.txt&quot;;my @keywordlist;my @rsslist;#load keywordsopen (KEYWORDFILE, $keyword_file) || die &quot;No Keyword file ($keyword_file) found, aborting.\n&quot;;while (&lt;KEYWORDFILE&gt;){chomp;push (@keywordlist, $_);}close KEYWORDFILE;#load list of rss filesopen (URLFILE,&quot;$url_file&quot;) || die &quot;No URL file ($url_file) found, aborting.\n&quot;;while (&lt;URLFILE&gt;){chomp;push (@rsslist, $_);}close URLFILE;#create the output rss imagerss_new(&#39;htp://www.whatever_you_want.com&#39;,&quot;BinBot Results&quot;);#loop through the rss files searching for keywordsforeach my $rss (@rsslist) {print &quot;Reading $rss\n&quot;;#Fetch the file. If successful, search for keywordsmy $res = URI::Fetch-&gt;fetch($rss) or die URI::Fetch-&gt;errstr;if ($res-&gt;is_success) {      my $xml = $res-&gt;content;  my $rp = new XML::RSS::Parser::Lite;$rp-&gt;parse($xml);# Search for keywords in rss filefor (my $i = 0; $i &lt; $rp-&gt;count(); $i++) {my $item = $rp-&gt;get($i);foreach my $kw (@keywordlist) {my $title = $item-&gt;get(&#39;title&#39;);my $url = $item-&gt;get(&#39;url&#39;);my $desc = $item-&gt;get(&#39;description&#39;);# If the keyword exists in the title, add the entry to the rss image.if ( $title =~ /$kw/i ) { print &quot;Matched keyword $kw\n&quot;;rss_item($url,$title,$desc) }}}} else {      print $res-&gt;status_line, &quot;\n&quot;;  }}# Save the rss image to a file.rss_save(&quot;$rss_file&quot;);&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Windows Active Directory to PDF Phone List (davis)</title>
    <link>http://prlmnks.org/html/573693.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573693.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse warnings;use strict;use Data::Dumper;use Net::LDAP;use Net::LDAPS;use Template;my $template_input = &#39;\documentclass[10pt,a4paper]{article}\usepackage{times}\usepackage{xtab}\usepackage{colortbl}\setlength\textheight{290mm}\setlength{\voffset}{-15mm} \begin{document}\begin{center}\begin{xtabular}{lllll}\textbf{Name} &amp; \textbf{Title} &amp; \textbf{Ext.} &amp; \textbf{Mobile} &amp; \textbf{SPD} \\\\\hline[% FOREACH buildings %]\hline\multicolumn{5}{c}{[% buildingname %]}\\\\\hline[% FOREACH staff %][%- IF loop.index % 2 -%]\rowcolor[gray]{0.91}[%- END -%][%name%] &amp; \\tiny{[%title%]} &amp; [%extension%] &amp; [%mobile%]  &amp; [%mobile_speed_dial%]\\\\[% END %][% END %]\end{xtabular}\end{center}\end{document}&#39;;##There&#39;ll be some customization necessary heremy $ldap = Net::LDAPS-&gt;new(&quot;domain.controller&quot;) or die &quot;$@&quot;;my $message    = $ldap-&gt;bind( &quot;cn=Some User,ou=Service Accounts,dc=company,dc=com&quot;,    password =&gt; &#39;Secret&#39; );$message = $ldap-&gt;search(    base   =&gt; &quot;ou=Employees,dc=company,dc=com&quot;,    filter =&gt; &quot;(&amp; (cn=*) (objectClass=user))&quot;,);$message-&gt;code &amp;&amp; die $message-&gt;error;my @skip_names = (    #A list of names to be skipped (service/admin accounts etc));my %staff;foreach my $employee ( $message-&gt;all_entries ) {    my $name = $employee-&gt;get_value(&quot;cn&quot;);    next if ( grep /^\Q$name\E$/, @skip_names );        my $title             = $employee-&gt;get_value(&quot;title&quot;)           || &quot;&quot;;    my $extension         = $employee-&gt;get_value(&quot;telephoneNumber&quot;) || &quot;&quot;;    my $mobile            = $employee-&gt;get_value(&quot;mobile&quot;)          || &quot;&quot;;    my $mobile_speed_dial = $employee-&gt;get_value(&quot;pager&quot;)           || &quot;&quot;;        my $building = $employee-&gt;get_value(&quot;physicalDeliveryOfficeName&quot;) || &quot;&quot;;    my $useraccount_control = $employee-&gt;get_value(&quot;userAccountControl&quot;)        || &quot;&quot;;    next if ( account_disabled($useraccount_control) );    # Skip disabled accounts    push @{ $staff{$building} },        {        name              =&gt; $name,        title             =&gt; $title,        extension         =&gt; $extension,        mobile            =&gt; $mobile,        mobile_speed_dial =&gt; $mobile_speed_dial        };}my @buildings;foreach my $building ( sort keys(%staff) ) {    my @staff = sort { $a-&gt;{name} cmp $b-&gt;{name} } @{ $staff{$building} };    push @buildings, { buildingname =&gt; $building, staff =&gt; \@staff };}my $template = Template-&gt;new();my $output;$template-&gt;process( \$template_input, { buildings =&gt; \@buildings }, \$output )    or die $template-&gt;e-&gt;error(), &quot;\n&quot;;open( my $fh, &quot;&gt;&quot;, &quot;phone_list.tex&quot; )    or die &quot;Couldn&#39;t open phone_list.tex for writing: $!\n&quot;;print $fh $output;close($fh);sub account_disabled {    my $flags = shift;    my %check = calculate_flags($flags);    return 1 if ( $check{ACCOUNTDISABLE} );    return 0;}sub calculate_flags {    my $flags_to_check = shift;    my %table          = (        SCRIPT                         =&gt; 0x0001,        ACCOUNTDISABLE                 =&gt; 0x0002,        HOMEDIR_REQUIRED               =&gt; 0x0008,        LOCKOUT                        =&gt; 0x0010,        PASSWD_NOTREQD                 =&gt; 0x0020,        PASSWD_CANT_CHANGE             =&gt; 0x0040,        ENCRYPTED_TEXT_PWD_ALLOWED     =&gt; 0x0080,        TEMP_DUPLICATE_ACCOUNT         =&gt; 0x0100,        NORMAL_ACCOUNT                 =&gt; 0x0200,        INTERDOMAIN_TRUST_ACCOUNT      =&gt; 0x0800,        WORKSTATION_TRUST_ACCOUNT      =&gt; 0x1000,        SERVER_TRUST_ACCOUNT           =&gt; 0x2000,        DONT_EXPIRE_PASSWORD           =&gt; 0x10000,        MNS_LOGON_ACCOUNT              =&gt; 0x20000,        SMARTCARD_REQUIRED             =&gt; 0x40000,        TRUSTED_FOR_DELEGATION         =&gt; 0x80000,        NOT_DELEGATED                  =&gt; 0x100000,        USE_DES_KEY_ONLY               =&gt; 0x200000,        DONT_REQ_PREAUTH               =&gt; 0x400000,        PASSWORD_EXPIRED               =&gt; 0x800000,        TRUSTED_TO_AUTH_FOR_DELEGATION =&gt; 0x1000000,    );    my %results;    foreach my $flag ( keys %table ) {        $results{$flag} = 1 if ( $flags_to_check &amp; $table{$flag} );    }    return %results;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>unichist -- count/summarize characters in data (graff)</title>
    <link>http://prlmnks.org/html/573646.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573646.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl=head1 NAMEunichist=head1 SYNOPSISunichist [--chart] [--top=N] [--hex[only]] [--enc=ENC] [file ...] --chart : print summary of character counts per &quot;chart&quot; --top=N : print only the N most frequent characters --hex     : include the Unicode hexadecimal code point value --hexonly : show the hex code point instead of the character itself --enc=ENC : convert input from ENC to utf8 (def: input is utf8)=head1 DESCRIPTIONFor text data provided on STDIN or in one or more files named on thecommand line, this program will print the list of characters occurringin the data, together with the frequency of occurrence for eachcharacter.By default, input is assumed to be in utf8, and all characters presentin the input are counted and listed on STDOUT, one character per line,in their &quot;standard&quot; order (i.e. the numeric ordering determined bytheir Unicode code point values), with the number of occurrencesfollowing each character.If the input uses some known encoding other than utf8, simply name theencoding with the &quot;--enc=...&quot; option (e.g. &quot;--enc=cp1252&quot; or&quot;--enc=UTF-16LE&quot;).  If the value of this option is not recognized as aknown encoding, the program exits with an error message listing theknown encodings.  (Note that ASCII is a proper subset of utf8; the--enc option is only needed when data is neither ASCII nor utf8.)Output is always in utf8 (but with the &quot;--hexonly&quot; option, it willalways be just plain ASCII).The --hex option will put the hexadecimal code point value at thebeginning of each output line, followed by the utf8 character and thenits frequency.  Use --hexonly to output just the hexadecimal value andfrequency without the actual utf8 character itself (useful when yourdisplay window is unable to handle utf8 data correctly).The &quot;--top=N&quot; option will cause only the N most frequent characters tobe listed, in descending order of frequency.  If N is 0, no characterswill be listed (useful in combination with the &quot;--chart&quot; option,described below).  If N is -1, all characters will be listed indescending order of frequency (instead of the default code-pointorder).The &quot;--chart&quot; option will produce a supplemental set of output lines,breaking the character counts into groups according the the &quot;chart&quot;pages defined by the Unicode Standard (version 5.0).  As of thisversion, there are about 150 distinct &quot;charts&quot; ranging fromU0000-U007F (ASCII) to U2F800-U2FA1F (CJK Compatibility IdeographsSupplement).  These charts define the classes of characters thatUnicode uses when organizing its code pages into distinct sets(e.g. by language, writing system or function).  Usually, a given datafile would contain characters spanning just a few distinct charts, andthis form of listing is useful when checking for &quot;outlier characters&quot;.To see only this summary of character counts by chart, use this optionin combination with &quot;--top=0&quot;, to turn off the listing of individualcharacters with their frequencies.=head1 LIMITATIONS/BUGSBe aware that some values in the range \x{0000} - \x{2FA1F} do notcorrespond to defined characters -- there are gaps in the variouscharts.  To the extent that Unicode explicitly omits some ranges ofcode point values as &quot;unassigned&quot;, any characters that fall withinthese unassigned ranges will be always be listed by their hex valueonly in the default output, and grouped together into a single&quot;unassigned&quot; class when the &quot;--chart&quot; option is used.  But there aresome &quot;unassigned&quot; code points that we are not able to identify assuch.  When in doubt, use the &quot;--hexonly&quot; option, and check the outputagainst the code charts as published at www.unicode.org/charts/.It&#39;s also possible that unicode input might contain characters in aregion called the &quot;Private Use Area&quot; (UE000-UF8FF), which means thatthe correct label or interpretation of the character depends on thewhim of whoever created the data.  Another possible anomaly for utf8input is the present of &quot;characters&quot; in the so-called &quot;Surrogate Area&quot;(UD800-UDFFF), which indicates an encoding error by whoever createdthe data.  In both cases, the default output will show only the hexvalues of the observed code points in these ranges, and the &quot;--chart&quot;output will indicate these regions as &quot;Private Use&quot; or &quot;Surrogate&quot;.=head1 OTHER NOTESThe default output listing uses the symbolic names NUL, TAB, LFD, RTN,SPC, NBSP and DEL for the null-byte, the five common whitespacecharacters and \x7F, respectively; other ASCII and Latin-1 controlcharacters are presented in &quot;\xHH&quot; notation.=head1 AUTHORDavid Graff ( graff (at) ldc (dot) upenn (dot) edu )=cutuse strict;use Encode;use Getopt::Long;my $Usage = &quot;Usage: $0 [--chart] [--top=N] [--hex[only]] [--enc=ENC] [file ...]\n&quot;;my %opt;GetOptions( \%opt, &#39;chart&#39;, &#39;hex&#39;, &#39;hexonly&#39;, &#39;enc=s&#39;, &#39;top=i&#39; )    or die $Usage;die $Usage if ( @ARGV == 0 and -t );my $inmode = &#39;:utf8&#39;;if ( $opt{enc} ) {    my @enclist = Encode-&gt;encodings(&quot;:all&quot;);    listEncodings( $Usage, @enclist ) unless ( grep /$opt{enc}/, @enclist );    $inmode = &quot;:encoding($opt{enc})&quot;;}binmode STDOUT, &#39;:utf8&#39;;my ( %char_hist, %class_hist, %class_def, %unassigned );# load the definitions of &quot;chart&quot; character classes#  and unassigned ranges:my $last_end = -1;while (&lt;DATA&gt;) {    chomp;    my ( $bgn, $end, $name ) = split / [-:] /, $_, 3;    $bgn = chr( hex( $bgn ));    $class_def{$bgn}{limit} = chr( hex( $end ));    $class_def{$bgn}{title} = $name;    if ( $last_end+1 != ord( $bgn )) {        for my $val ( $last_end+1 .. ord($bgn)-1 ) {            $unassigned{chr($val)} = undef;        }    }    if ( $name =~ /Surrogate|Privat Use/ ) {        for my $chr ( $bgn .. $class_def{$bgn}{limit} ) {            $unassigned{$chr} = $name;        }    }    $last_end = hex( $end );}if ( @ARGV == 0 ) {    binmode STDIN, $inmode;    count_chars( \%char_hist );} else {    for my $file ( @ARGV ) {        count_chars( \%char_hist, $file, $inmode );    }}my $nonchrformat = &quot;%04X %d\t%s\n&quot;;my $chrformat = ( $opt{hexonly} ) ? &quot;%04X %d\n&quot; :                ( $opt{hex} ) ? &quot;%04X %s %d\n&quot; : &quot;%s %d\n&quot;;my @outorder;if ( not exists( $opt{top} )) {    @outorder = sort keys %char_hist;}elsif ( $opt{top} != 0 ) {    $opt{top} = scalar keys %char_hist if ( $opt{top} &lt; 0 );    @outorder = ( sort {$char_hist{$b} &lt;=&gt; $char_hist{$a}}                        keys %char_hist )[0 .. $opt{top}-1];}my %symbols = ( &quot; &quot; =&gt; &#39;SPC&#39;,                 &quot;\t&quot; =&gt; &#39;TAB&#39;,                 &quot;\n&quot; =&gt; &#39;LFD&#39;,                 &quot;\r&quot; =&gt; &#39;RTN&#39;,                 &quot;\x00&quot; =&gt; &#39;NUL&#39;,                 &quot;\x7F&quot; =&gt; &#39;DEL&#39;,                 &quot;\xA0&quot; =&gt; &#39;NBSP&#39;,              );for my $char ( @outorder ) {    if ( exists( $unassigned{$char} )) {        my $status = $unassigned{$char} || &#39;unassigned&#39;;        printf( $nonchrformat, ord( $char ), $char_hist{$char}, $status );        next;    }    my @args = ();    push @args, ord( $char ) if ( $chrformat =~ /X/ );    if ( $chrformat =~ /s/ ) {        push @args, (( exists( $symbols{$char} )) ? $symbols{$char} :                      ( $char lt &#39; &#39; || $char =~ /\x80-\x9F/ ) ?                        sprintf( &quot;\\x%02x&quot;, ord( $char )) : $char );    }    push @args, $char_hist{$char};    printf( $chrformat, @args );}if ( $opt{chart} ) {    count_classes( \%char_hist, \%class_def, \%unassigned, \%class_hist );    print &quot;\n&quot;;    for my $class ( sort keys %class_def ) {        printf( &quot;%04x-%04x %d\t%s\n&quot;,                ord($class), ord($class_def{$class}{limit}),                $class_hist{$class}, $class_def{$class}{title} )            if ( $class_hist{$class} );    }    printf( &quot;xxxx-xxxx %d\t unassigned\n&quot;, $class_hist{unassigned} )        if ( $class_hist{unassigned} );}sub count_chars{    my ( $hist, $file, $mode ) = @_;    my $fh;    if ( defined $file ) {        open( $fh, &quot;&lt;$mode&quot;, $file ) or die &quot;$file: $!&quot;;    } else {        $fh = \*STDIN;    }    while ( &lt;$fh&gt; ) {        for my $ch ( split // ) {            $$hist{$ch}++;        }    }}sub count_classes{    my ( $ch_hist, $cl_def, $non_chr, $cl_hist ) = @_;    my @start = sort keys %$cl_def;    my $bgn = shift @start;    for my $chr ( sort keys %$ch_hist ) {        if ( exists( $$non_chr{$chr} )) {            my $class = $$non_chr{$chr} || &#39;unassigned&#39;;            $$cl_hist{$class}++;            next;        }        while ( @start and $chr gt $$cl_def{$bgn}{limit} ) {            $bgn = shift @start;        }        if ( $chr gt $$cl_def{$bgn}{limit} ) {            $$cl_hist{unassigned} += $$ch_hist{$chr};        } else {            $$cl_hist{$bgn} += $$ch_hist{$chr};        }    }}sub listEncodings{   # user is asking for help: list all available encodings    my ( $Usage, @enclist ) = @_;    my $colwidth = length( (sort {length($b) &lt;=&gt; length($a)} @enclist)[0] ) + 2;    my $ncol = int( 80/$colwidth );    my $nrow = int( scalar(@enclist)/$ncol );    $nrow++ if ( scalar(@enclist) % $ncol );    my $fmt = &quot;%-${colwidth}s&quot;;    print $Usage, &quot;\n  Acceptable values for ENC are:\n&quot;;    foreach my $r ( 0 .. $nrow ) {        foreach my $c ( 0 .. $ncol ) {            my $i = $c * $nrow + $r;            printf( $fmt, $enclist[$i] );        }        print &quot;\n&quot;;    }    exit( 0 );}__DATA__0000 - 007F : Basic Latin ASCII0080 - 00FF : Latin-10100 - 017F : Latin Extended A0180 - 024F : Latin Extended B0250 - 02AF : IPA Extensions02B0 - 02FF : Spacing Modifier Letters0300 - 036F : Combining Diacritical Marks0370 - 03FF : Greek0400 - 04FF : Cyrillic0500 - 052F : Cyrillic Supplement0530 - 058F : Armenian0590 - 05FF : Hebrew0600 - 06FF : Arabic0700 - 074F : Syriac0750 - 077F : Arabic Supplement0780 - 07BF : Thaana07C0 - 07FF : N&#39;Ko0900 - 097F : Devanagari0980 - 09FF : Bengali0A00 - 0A7F : Gurmukhi0A80 - 0A8F : Gujarati0B00 - 0B7F : Oriya0B80 - 0BFF : Tamil0C00 - 0C7F : Telugu0C80 - 0CFF : Kannada0D00 - 0D7F : Malayalam0D80 - 0DFF : Sinhala0E00 - 0E7F : Thai0E80 - 0EFF : Lao0F00 - 0FFF : Tibetan1000 - 109F : Myanmar10A0 - 10FF : Georgian1100 - 11FF : Hangul Jamo1200 - 137F : Ethiopic1380 - 139F : Ethiopic Supplement13A0 - 13FF : Cherokee1400 - 167F : Canadian Syllabics1680 - 169F : Ogham16A0 - 16FF : Runic1700 - 171F : Tagalog1720 - 173F : Hanunoo1740 - 175F : Buhid1760 - 177F : Tagbanwa1780 - 17FF : Khmer1800 - 18FF : Mongolian1900 - 194F : Limbu1950 - 197F : Tai Le1980 - 19DF : New Tai Lue19E0 - 19FF : Khmer Symbols1A00 - 1AFF : Buginese1B00 - 1B7F : Balinese1D00 - 1D7F : Phonetic Extensions1D80 - 1DBF : Phonetic Extensions Supplement1DC0 - 1DFF : Combining Diacritical Marks Supplement1E00 - 1EFF : Latin Extended Additional1F00 - 1FFF : Greek Extended2000 - 206F : General Punctuation2070 - 209F : Superscripts and Subscripts20A0 - 20CF : Currency Symbols20D0 - 20FF : Combining Diacritical Marks for Symbols2100 - 214F : Letterlike Symbols2150 - 218F : Number Forms2190 - 21FF : Arrows2200 - 22FF : Mathematical Operators2300 - 23FF : Miscellaneous Technical2400 - 243F : Control Pictures2440 - 245F : Optical Character Recognition2460 - 24FF : Enclosed Alphanumerics2500 - 257F : Box Drawing2580 - 259F : Block Elements25A0 - 25FF : Geometric Shapes2600 - 26FF : Miscellaneous Symbols2700 - 27BF : Dingbats27C0 - 27EF : Miscellaneous Mathematical Symbols A27F0 - 27FF : Supplemental Arrows A2800 - 28FF : Braille Patterns2900 - 297F : Supplemental Arrows B2980 - 29FF : Miscellaneous Mathematical Symbols B2A00 - 2AFF : Supplemental Mathematical Operators2B00 - 2BFF : Miscellaneous Symbols and Arrows2C00 - 2C5F : Glagolitic2C60 - 2C7F : Latin Extended C2C80 - 2CFF : Coptic2D00 - 2D2F : Georgian Supplement2D30 - 2D7F : Tifinagh2D80 - 2DDF : Ethiopic Extended2E00 - 2E7F : Supplemental Punctuation2E80 - 2EFF : CJK Radicals Supplement2F00 - 2FDF : Kangxi Radicals2FF0 - 2FFF : Ideographic Description Characters3000 - 303F : CJK Symbols and Punctuation3040 - 309F : Hiragana30A0 - 30FF : Katakana3100 - 312F : Bopomofo3130 - 318F : Hangul Compatibility Jamo3190 - 319F : Kanbun31A0 - 31BF : Bopomofo Extended31C0 - 31EF : CJK Strokes31F0 - 31FF : Katakana Phonetic Extensions3200 - 32FF : Enclosed CJK Letters and Months3300 - 33FF : CJK Compatibility3400 - 4DBF : CJK Unified Ideographs Extension A4DC0 - 4DFF : Yijing Hexagram Symbols4E00 - 9FBF : CJK Unified IdeographsA000 - A48F : Yi SyllablesA490 - A4CF : Yi RadicalsA700 - A71F : Modifier Tone LettersA720 - A7FF : Latin Extended DA800 - A82F : Syloti NagriA840 - A87F : Phags-PaAC00 - D7AF : Hangul SyllablesD800 - D8FF : High Surrogate AreaDC00 - DFFF : Low Surrogate AreaE000 - F8FF : Private Use AreaF900 - FAFF : CJK Compatibility IdeographsFB00 - FB4F : Alphabetic Presentation FormsFB50 - FDFF : Arabic Presentation Forms AFE00 - FE0F : Variation SelectorsFE10 - FE1F : Vertical FormsFE20 - FE2F : Combining Half MarksFE30 - FE4F : CJK Compatibility FormsFE50 - FE6F : Small Form VariantsFE70 - FEFF : Arabic Presentation Forms BFF00 - FFEF : Halfwidth and Fullwidth FormsFFF0 - FFFF : Specials10000 - 1007F : Linear B Syllabary10080 - 100FF : Linear B Ideograms10100 - 1013F : Aegean Numbers10140 - 1018F : Ancient Greek Numbers10300 - 1032F : Old Italic10330 - 1034F : Gothic10380 - 1039F : Ugaritic103A0 - 103DF : Old Persian10400 - 1044F : Deseret10450 - 1047F : Shavian10480 - 104AF : Osmanya10800 - 1083F : Cypriot Syllabary10900 - 1091F : Phoenician10A00 - 10A5F : Kharoshthi12000 - 123FF : Cuneiform12400 - 1247F : Cuneiform Numbers and Punctuation1D000 - 1D0FF : Byzantine Musical Symbols1D100 - 1D1FF : Musical Symbols1D200 - 1D24F : Ancient Greek Musical1D300 - 1D35F : Tai Xuan Jing Symbols1D360 - 1D37F : Counting Rod Numerals1D400 - 1D7FF : Mathematical Alphanumeric Symbols20000 - 2A6DF : CJK Unified Ideographs Extension B2F800 - 2FA1F : CJK Compatibility Ideographs Supplement&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Move/merge directories (diotalevi)</title>
    <link>http://prlmnks.org/html/573031.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573031.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;use Getopt::Long &#39;GetOptions&#39;;use autouse &#39;Pod::Usage&#39; =&gt; &#39;pod2usage&#39;;GetOptions( &#39;tgt=s&#39; =&gt; \ my($tgt),            nop     =&gt; \ my($nop),            why     =&gt; \ my($why),            help =&gt; sub { pod2usage( -verbose =&gt; 1 ) },            man =&gt; sub { pod2usage( -verbose =&gt; 2 ) } )  or die pod2usage( -verbose =&gt; 0 );if ( not -d $tgt ) {    pod2usage( -verbose =&gt; 0 );}=head1 NAMEmerge-move - Moves everything under the current location elsewhere.=head1 SYNOPSIS cd /home/data/blah merge-move --tgt /home/data/somewhere-else Options:   --tgt TARGET-DIRECTORY   --nop   --why=head1 OPTIONS=over=item C&lt;--tgt TARGET-DIRECTORY&gt;This is the place which all the stuff in the current directory will bemerged into.=back=cutuse autouse &#39;Cwd&#39; =&gt; &#39;cwd&#39;;use autouse &#39;File::Find&#39; =&gt; &#39;find&#39;;use autouse &#39;File::Spec::Functions&#39; =&gt; qw( canonpath catfile splitpath catdir );use autouse &#39;File::Path&#39; =&gt; &#39;mkpath&#39;;use autouse &#39;File::Copy&#39; =&gt; &#39;move&#39;;$SIG{CHLD} = &#39;IGNORE&#39;;my $pwd = cwd();my $pwd_rx = qr/\A\Q$pwd/;my ( %dirs );find( { wanted =&gt; sub {            return if not -f $_;            my $srcfile = canonpath( $File::Find::name );            my ( undef, $srcdir, $file ) = splitpath( $srcfile );            my $tgtdir = catdir( $tgt, $srcdir );            if ( ! exists $dirs{$tgtdir}                 and ! -d $tgtdir ) {                $dirs{$tgtdir} = undef;                if ( $why ) {                    print &quot;mkdir $tgtdir\n&quot;;                }                if ( not $nop ) {                    mkpath $tgtdir, 0, 0775                      or die &quot;Can&#39;t create $tgtdir: $!&quot;;                }            }            my $tgtfile = catfile( $tgtdir, $file );            if ( -e $tgtfile ) {                die &quot;Couldn&#39;t move $srcfile: $tgtfile already exists.\n&quot;;            }            if ( $why ) {                print &quot;mv $srcfile $tgtfile\n&quot;;            }            if ( not $nop ) {                move $srcfile, $tgtfile                  or die &quot;Couldn&#39;t move $srcfile to $tgtfile: $!&quot;;            }        },        no_chdir =&gt; 1 },      &#39;.&#39; );&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Fixup tabular text file (diotalevi)</title>
    <link>http://prlmnks.org/html/573022.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573022.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings FATAL =&gt; &#39;all&#39;;no warnings &#39;uninitialized&#39;;use Getopt::Long &#39;GetOptions&#39;;use English &#39;$PROGRAM_NAME&#39;;use autouse &#39;Pod::Usage&#39; =&gt; &#39;pod2usage&#39;;our %CHANGES;our $VERSION = ~0;=head1 NAMEfix-tabs - Fixes some common problems in tab-delimited files=head1 DESCRIPTIONThis fixes some problems I encountered with tabular text files.=over=item * Removes empty trailing rows=item * Adds missing trailing columns=item * Warns if the header is missing columns=item * Warns if the file isn&#39;t a text file=item * Warns if there is only one column.=item * Dos2unix line ending conversion=item * Fixes Excel formatted numbers:=over=item * (...) parens around negative numbers=item * Optional $ sign=item * Optional commas=back=back=head1 SYNOPSISfix-tabs [options] file1 file2 ...  Options:    --help Displays this message    --man  Displays the manual    --clip Removes things off the right edge of the table=cutGetOptions(    help =&gt; sub { pod2usage( -verbose =&gt; 1 ) },    man  =&gt; sub { pod2usage( -verbose =&gt; 2 ) },    clip =&gt; \our ($CLIP_EDGES),    )    or pod2usage( -verbose =&gt; 0 );if ( not scalar @ARGV ) {    pod2usage( -verbose =&gt; 0 );}for my $file (@ARGV) {    fix_file($file);}exit;# To regenerate the regex on the following line, run this# command. It&#39;ll be uglier than what&#39;s below but that&#39;s because I made# the one below prettier. It&#39;s still equivalent and is the source for# the below.## perl -MRegexp::Common -le &#39;print qr/(?:$RE{num}{real}|$RE{num}{int}|$RE{num}{real}{-sep=&gt;&#39;,&#39;}{-group=&gt;3}|$RE{num}{int}{-sep=&gt;&#39;,&#39;}{-group=&gt;3})/&#39;my $NUMBER;BEGIN {    $NUMBER        = qr/(?-xism:(?:(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))|(?:(?:[+-]?)(?:[0123456789]+))|(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]{1,3}(?:(?:[,])[0123456789]{3})*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))|(?:(?:[+-]?)(?:[0123456789]{1,3}(?:,[0123456789]{3})*))))/;}my $EXCEL_NUMBER;BEGIN {    $EXCEL_NUMBER = qr/(?xsm)(?:    \( \$? $NUMBER \)  |    \$? $NUMBER)/;}sub fix_file {    my ($file) = @_;    -T $file or die &quot;$file isn&#39;t a text file.\n&quot;;    # Read the header line and get the # of columns I expect every    # other line to have.    open my $fh, &#39;&lt;&#39;, $file or die &quot;Can&#39;t open $file: $!&quot;;    my $header_line = &lt;$fh&gt;;    $header_line =~ m/\t/mx        or die &quot;$file isn&#39;t a tab delimited text file.\n&quot;;    my %field_names;    {        my @labels = split /\t/, $header_line;        chomp $labels[-1];        for my $index ( 0 .. $#labels ) {            my $column_name = $labels[$index];            if ( $column_name =~ s/\A\s+// ) {                ++$CHANGES{header_whitespace};            }            if ( $column_name =~ s/\s+\z// ) {                ++$CHANGES{header_whitespace};            }            $field_names{$column_name} = $index;        }    }    my $expected_columns = scalar keys %field_names;    # The input file will be copied here. This shouldn&#39;t be left    # around after the program is finished.    my $tmpfile = &quot;$file.tmp&quot;;    open my $out, &#39;&gt;&#39;, $tmpfile        or die &quot;Couldn&#39;t open $tmpfile for writing: $!&quot;;    # If there are Windows line endings, that&#39;s automatically a fix.    if ( $header_line =~ tr/\r//d ) {        ++$CHANGES{windows_cr};    }    # Copy out the header line using the cleaned up headigns.    print {$out} join( &quot;\t&quot;,        sort { $field_names{$a} &lt;=&gt; $field_names{$b} }            keys %field_names )        . &quot;\n&quot;        or die &quot;Couldn&#39;t write to $tmpfile: $!&quot;;    while ( my $line = &lt;$fh&gt; ) {        # Again, fixing Windows line endings.        if ( $line =~ tr/\r//d ) {            ++$CHANGES{windows_cr};        }        if ( not $line =~ m/\S/msx ) {            # Just skip empty lines and cause the file to be            # rewritten.            ++$CHANGES{blank};            next;        }        my @values = split /\t/, $line;        chomp $values[-1];        # Column # fixes. Either too many or too little.        if ( scalar(@values) &lt; $expected_columns ) {            ++$CHANGES{col_count};            push @values, (&#39;&#39;) x ( $expected_columns - scalar @values );        }        elsif ( scalar(@values) &gt; $expected_columns ) {            ++$CHANGES{col_count};            if ( not $CLIP_EDGES ) {                while ( $values[-1] eq &#39;&#39;                    and scalar(@values) &gt; $expected_columns )                {                    pop @values;                }            }            else {                splice @values, $expected_columns;            }            if ( scalar(@values) &gt; $expected_columns ) {                warn                    &quot;Too many columns in row $.. Expected $expected_columns, got @{[ scalar @values ]}.\n&quot;;            }        }        print {$out} join( &quot;\t&quot;, @values ) . &quot;\n&quot;            or die &quot;Couldn&#39;t write to $tmpfile: $!&quot;;    }    close $out        or die &quot;Couldn&#39;t flush $tmpfile: $!&quot;;    if ( not keys %CHANGES ) {        print &quot;$file ok.\n&quot;;        unlink $tmpfile            or die &quot;Couldn&#39;t remove unused $tmpfile: $!&quot;;    }    else {        print &quot;$file fixed.\n&quot;;        # Report on several named things getting fixed. This just puts        # nice names on the stuff.        for my $change (            [ windows_cr =&gt; &#39;Windows line endings&#39; ],            [ col_count  =&gt; &#39;Column count&#39; ],            [ blank      =&gt; &#39;Blank lines&#39; ],            [ fix_num    =&gt; &#39;Number formatting&#39; ]            )        {            my ( $field, $desc ) = @$change;            my $fix = delete $CHANGES{$field};            if ( not defined $fix ) {                next;            }            print &quot;$desc: $fix\n&quot;;        }        for ( sort grep { $CHANGES{$_} } keys %CHANGES ) {            print &quot;$_: $CHANGES{$_}\n&quot;;        }        my $backupfile = &quot;$file.old&quot;;        # Add a number to the .old to find a file name that isn&#39;t used        # yet.        while ( -e $backupfile ) {            my ($id) = $backupfile =~ m/\.(\d+)$/msx;            no warnings &#39;numeric&#39;;            $id += 0;            $backupfile =~ s/\d+$//msx;            $backupfile .= &quot;.$id&quot;;        }        rename $file, $backupfile            or die &quot;Couldn&#39;t rename $file to backupfile&quot;;        rename $tmpfile, $file            or die &quot;Couldn&#39;t rename $tmpfile to $file&quot;;    }    return 1;}sub fix_excel_number {    my $newnum = $_;    my $oldnum = $_;    $newnum =~ s/\A\s*($EXCEL_NUMBER)\s*\z/normalize_excel_number($1)/e;    if ( $newnum ne $oldnum ) {        $_ = $newnum;        warn &quot;Fix number $oldnum -&gt; $newnum\n&quot;;        ++$CHANGES{fix_num};        return 1;    }    else {        return 0;    }}sub normalize_excel_number {    my $num = shift @_;    $num =~ tr/$,//d;    $num =~ s/\A\((.+)\)\z/-$1/;    return $num;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>diotalevi&#39;s grep (diotalevi)</title>
    <link>http://prlmnks.org/html/573020.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573020.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl## no critic VersionVaruse strict;use warnings;use Getopt::Long &#39;GetOptions&#39;;use autouse &#39;File::Find&#39;      =&gt; &#39;find&#39;;use autouse &#39;Pod::Usage&#39;      =&gt; &#39;pod2usage&#39;;use autouse &#39;Term::ANSIColor&#39; =&gt; &#39;colored&#39;;use autouse &#39;IPC::Open3&#39; =&gt; &#39;open3&#39;;$SIG{CHLD} = &#39;IGNORE&#39;;use vars qw( $TextOnly );main();exit;sub main {    # Fetch parameters.    GetOptions(        man  =&gt; sub { pod2usage( -verbose =&gt; 2 ) },        help =&gt; sub { pod2usage( -verbose =&gt; 1 ) },        t        =&gt; \$TextOnly,        l        =&gt; \my ($filename_only),        w        =&gt; \my ($word),        i        =&gt; \my ($ignore_case),        Q        =&gt; \my ($quotemeta),        h        =&gt; \my ($no_filename),        n        =&gt; \my ($line_no),        R        =&gt; \my ($no_recursive),        v        =&gt; \my ($invert_match),        plain    =&gt; \my ($no_ansicolor),        &#39;name=s&#39; =&gt; \my ($filename_rx),        )        or pod2usage( -verbose =&gt; 0 );    my ( $match, @srcs ) = @ARGV;    if ( not @srcs ) {        @srcs = &#39;.&#39;;    ## no critic Noisy    }    # Validate parameters.    if ( not defined $match ) {        pod2usage( -verbose =&gt; 0 );    }    # Pre-process the pattern and then compile it.    if ($quotemeta) {        $match = quotemeta $match;    }    if ($word) {        $match = &quot;\\b$match\\b&quot;;    }    if ($ignore_case) {        $match = &quot;(?i)$match&quot;;    }    my $match_rx = qr/$match/;    # Get a function which formats the output for whatever was    # requested. All info is passed through the globals    # $File::Find::rel_name, $., and $_. The input will contain    # whatever linebreak is currently active so most things don&#39;t need    # to add one.    my $prev_file = &#39;&#39;;    my $formatter = (        $line_no &amp;&amp; $no_filename        ? sub { &quot;$.:&quot; . shift }        : $line_no ? sub {            if ( $File::Find::name ne $prev_file ) {                $prev_file = $File::Find::name;                return ( ( $prev_file eq &#39;&#39; ? &#39;&#39; : &quot;\n&quot; )                    . colored( $File::Find::name, &#39;bold green&#39; ) . &quot;\n$.:&quot;                        . shift );            }            else {                return &quot;$.:&quot; . shift;            }            }        : $no_filename   ? sub {shift}        : $filename_only ? sub {            if ( $File::Find::name ne $prev_file ) {                $prev_file = $File::Find::name;                return ( ( $prev_file eq &#39;&#39; ? &#39;&#39; : &quot;\n&quot; )                    . colored( $File::Find::name, &#39;bold green&#39; )                        . &quot;\n&quot; );            }            else {                return;            }            }        : sub {            if ( $File::Find::name ne $prev_file ) {                $prev_file = $File::Find::name;                return ( ( $prev_file eq &#39;&#39; ? &#39;&#39; : &quot;\n&quot; )                    . colored( $File::Find::name, &#39;bold green&#39; ) . &quot;\n&quot;                        . shift );            }            else {                return shift;            }        }    );    my $grep_file_fn = sub {        grep_file(            ignore_rcs   =&gt; 1,            plain        =&gt; $no_ansicolor,            match_rx     =&gt; $match_rx,            filename_rx  =&gt; $filename_rx,            formatter    =&gt; $formatter,            invert_match =&gt; $invert_match,            match_once   =&gt; $filename_only        );    };    # Here&#39;s the main loop. For each source directory/file, search it.    for my $src (@srcs) {        # Examine all files in $src.        if ($no_recursive) {            # Mimic the API of File::Find for grep_file().            # local $File::Find::dir = unimplemented            ## no critic            local $File::Find::name = $src;            local $_                = $src;            $grep_file_fn-&gt;();        }        else {            find( $grep_file_fn, $src );        }    }    return 0;}sub open_file_harder {    my ($filename) = @_;    return if not defined $filename;    if ( my ($extension) = $filename =~ /(\.[^.]+)\z/mx ) {        my @readers = (            [ qr/\.t(?:ar\.)?gz\z/ =&gt; qw( gzcat ),    $filename ],            [ qr/\.zip\z/,         =&gt; qw( unzip -p ), $filename ],            [ qr/\.Z\z/            =&gt; qw( zcat ),     $filename ],            [ qr/\.gz\z/           =&gt; qw( gzcat ),    $filename ],            [ qr/\.bz2\z/          =&gt; qw( bzcat ),    $filename ],        );        for my $reader (@readers) {            my ( $pattern, @command ) = @{$reader};            if ( $extension =~ $pattern ) {                open3( undef, my $fh, undef, @command );                return $fh;            }        }    }    open my $fh, &#39;&lt;&#39;, $filename        or die &quot;Couldn&#39;t open $filename: $!&quot;;    return $fh;}sub grep_file {    my %p            = @_;    my $match_rx     = $p{match_rx};    my $formatter    = $p{formatter};    my $invert_match = $p{invert_match};    my $plain        = $p{plain};    my $match_once   = $p{match_once};    my $filename = $_;    # Ignore CVS stuff.    return if $File::Find::name =~ m{/CVS/?};    # If there is a pattern required of filenames, try that one    # first. This requires no checks to the FS so I&#39;m doing this    # before the next stuff.    return        if defined $p{filename_rx}        and not $filename =~ $p{filename_rx};    # Ignore non-existant files.    return if not -f $filename;    # Ignore non-text files if that&#39;s what was requested.    return if $TextOnly and not -T _;    eval {        my $fh = open_file_harder($filename);    LINE: while ( my $line = &lt;$fh&gt; ) {            # If the line matches the pattern print it as a formatted            # line.            my $matched;            if ($plain) {                $matched = ( $line =~ /$match_rx/mx );            }            else {                $matched = ( $line =~ /$match_rx/mx );                $line                    =~ s/((?:$match_rx)+)/ colored( &quot;$1&quot;, &#39;yellow on_black&#39; ) /gemx;            }            # Given    Match     then exclusive or is great here.            #            0   1            #          +---+---+            # Invert 0 |   | X |            #        1 | X |   |            if ( $matched xor $invert_match ) {                print $formatter-&gt;($line);                last LINE if $match_once;            }        }    };    return 1;}__END__=head1 NAMEdgrep - A recursive grep that uses perl regular expressions.=head1 SYNOPSISdgrep [options] [file ...] Options:   -help      Prints this help message   -man       Prints the manual   -t         Searches only `text&#39; files   -w         Matches only &quot;words&quot; using \b...\b   -i         Case-insensitive matching   -Q         Ignore perl meta-characters   -v         Invert output, match lines that don&#39;t match the pattern   -h         Exclude filename from output   -n         Include line number in output   -R         Disable recursion, no directories.   -plain     Disable highliting of matched text   -name EXPR Only open files matching this regular expression=head1 OPTIONS=over 4=item B&lt;-help&gt;Prints a simple message on usage and then exits.=item B&lt;-man&gt;Prints the manual and then exits.=item B&lt;-t&gt;Only `text&#39; files are searched.=item B&lt;-w&gt;When matching, the pattern is surrounded by perl\&#39;s \b assertion. Thatis, the match must be on a &quot;word&quot; boundary, either starting orfinishing. To perl, &quot;word&quot; is locale specific but generally means anyalphanumeric character and underscore.=item B&lt;-i&gt;Match without regard to casing. This is affected by locale.=item B&lt;-Q&gt;Pattern is a literal string. All regex metacharacters will be escapedusing the quotemeta() function.=item B&lt;-v&gt;Print only lines which do B&lt;not&gt; match the pattern. This is equivalentto grep\&#39;s -v parameter.=item B&lt;-h&gt;Omit the filename from the output when a line is matched. This issemi-equivalent to grep\&#39;s -h parameter.=item B&lt;-n&gt;Print the line number.=item B&lt;-R&gt;Do not recurse into any subdirectories.=item B&lt;-plain&gt;C&lt;dgrep&gt; automatically inserts ANSI escape codes to highlight matchedtext. Use the C&lt;-plain&gt; option to disable that.=item B&lt;-name&gt; EXPRC&lt;dgrep&gt; usually searches every file and directory, recursively. WhenC&lt;-name EXPR&gt; is used, only filenames matching this regular expressionare searched.=back=head1 DESCRIPTIONB&lt;dgrep&gt; is an &quot;improved&quot; version of the grep that comes with the Sunbox. It is normally recursive, accepts perl regular expressions, andoptionally prints the filename the match was found in.=cut&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>cutf - cut by field name (diotalevi)</title>
    <link>http://prlmnks.org/html/573019.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573019.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;use Getopt::Long;use autouse &#39;Pod::Usage&#39; =&gt; &#39;pod2usage&#39;;GetOptions(    &#39;d|delimiter=s&#39; =&gt; \( my ($delim)     = &quot;\t&quot; ),    &#39;f|fields=s&#39;    =&gt; \( my ($spec_list) = q{} ),    &#39;v&#39;             =&gt; \my ($reverse),    help =&gt; sub { pod2usage( -verbose =&gt; 1 ) },    man  =&gt; sub { pod2usage( -verbose =&gt; 2 ) },    )    or pod2usage( -verbose =&gt; 0 );my $delim_rx = qr/\Q$delim/xm;my $header = &lt;&gt;;my @field_names = map {uc} split /$delim_rx/xm, $header;chomp @field_names;my @selected_fields;SPEC: for my $spec (    map { $_ =~ /\S/xm ? uc $_ : () }    split /,/xm, $spec_list    ){    ## no critic ProhibitCascadingIfElse    if ( $spec =~ /\A(\d+)\z/xm and ( 1 &lt;= $1 and $1 &lt;= @field_names ) ) {        push @selected_fields, $1 - 1;        next SPEC;    }    elsif ( $spec =~ /\A(\d+)-(\d+)\z/xm        and ( 1 &lt;= $1 and $1 &lt;= @field_names )        and ( 1 &lt;= $2 and $2 &lt;= @field_names )        and $1 &lt;= $2 )    {        push @selected_fields, $1 - 1 .. $2 - 1;        next SPEC;    }    elsif ( $spec =~ /\A-(\d+)\z/xm        and ( 1 &lt;= $1 and $1 &lt;= @field_names ) )    {        push @selected_fields, 0 .. $1 - 1;        next SPEC;    }    elsif ( $spec =~ /\A(\d+)-\z/xm        and ( 1 &lt;= $1 and $1 &lt;= @field_names ) )    {        push @selected_fields, $1 - 1 .. $#selected_fields;        next SPEC;    }    else {        for my $ix ( 0 .. $#field_names ) {            # Push *all* columns with the name $            my $found_it;            if ( uc $spec eq $field_names[$ix] ) {                push @selected_fields, $ix;                $found_it = 1;            }            next SPEC if $found_it;        }    }    die qq&lt;Invalid spec &quot;$spec&quot;.\n&gt;;}if ($reverse) {    my %selected;    for my $col_idx ( 0 .. $#field_names ) {        $selected{$_} = 1;    }    for my $col_idx (@selected_fields) {        $selected{$_} = 0;    }    @selected_fields        = grep { $selected{$_} } sort { $a &lt;=&gt; $b } keys %selected;}print join( $delim, @field_names[@selected_fields] ) . &quot;\n&quot;;while ( my $line = &lt;&gt; ) {    my @line = split /$delim_rx/xm, $line;    chomp @line;    ## no critic NoWarnings    no warnings &#39;uninitialized&#39;;    print join( $delim, @line[@selected_fields] ) . &quot;\n&quot;;}__END__=head1 NAMEcutf - remove sections from each line of files=head1 SYNOPSIS  cutf [OPTION]... [FILE]...  cutf --man for more options=head1 DESCRIPTIONPrint selected parts of lines from each FILE to standard output.=head1 OPTIONSMandatory arguments to long options are mandatory for short optionstoo.=over=item -b, --bytes=LISTTODO: output only these bytes=item --output-delimiter=STRINGTODO: use C&lt;STRING&gt; as the output delimiter the default is to use the input delimiter=item --helpdisplay this help and exit=item --versionTODO: output version information and exit=backUse one, and only one of -b, -c or -f. Each LIST is made up of onerange, or many ranges separated by commas. Each range is one of:  N      Nth byte, character or field, counted from 1    N-     from Nth byte, character or field, to end of line    N-M    from Nth to Mth (included) byte, character or field    -M     from first to Mth (included) byte, character or field=over=item -c, --characters=LISTTODO: output only these characters=item -d, --delimiter=DELIMuse DELIM instead of TAB for field delimiter=item -f, --fields=LISToutput only these fields; also print any line that contains nodelimiter character, unless the -s option is specified=item -nTODO: with -b: don&#39;t split multibyte characters=item -s, --only-delimitedTODO: do not print lines not containing delimiters=backWith no FILE, or when FILE is -, read standard input.=head1 DIAGNOSTICS=over=item Invalid spec &quot;%s&quot;.Your spec wasn&#39;t one of the recognized forms: COLUMN FROM-TO -TO FROM-=back=cut&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>cksum contents of a tarball (diotalevi)</title>
    <link>http://prlmnks.org/html/573018.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/573018.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;use Getopt::Long &#39;GetOptions&#39;;use Carp &#39;croak&#39;;use Pod::Usage &#39;pod2usage&#39;;GetOptions(    tgz  =&gt; \my ($tgz),    )    or die &quot;Usage: $0 --tgz TARBALL&quot;;open my $tgz_fh, &#39;-|&#39;, &#39;tar&#39;, &#39;xvzf&#39;, $tgz    or croak &quot;Can&#39;t tar xvzf $tgz: $!&quot;;# tar will print a file before it is done so I have this reader to# wait for the next file to get mentioned.my $file_reader = do {    my @files;    sub {        # Add to @files if necessary and possible.        while ( @files &lt; 2 and $tgz_fh ) {            chomp( my $file = &lt;$tgz_fh&gt; );            if ( not defined $file ) {                close $tgz_fh;                undef $tgz_fh;            }            else {                push @files, $file;            }        }        if (@files) {            return shift @files;        }        else {            return;        }    };};# For each file, cksum it.# For each directory, plan to remove it in LIFO order.my @directories;while ( my $file = $file_reader-&gt;() ) {    if ( -f $file ) {        0 == system &#39;cksum&#39;, $file            or croak &quot;Can&#39;t exec cksum $file: $?&quot;;        unlink $file            or croak &quot;Can&#39;t unlink $file: $!&quot;;    }    elsif ( -d _ ) {        unshift @directories, $file;    }}# Remove my directories in LIFO order.while (@directories) {    my $size_before = @directories;    @directories = grep { not rmdir } @directories;    last if @directories == $size_before;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>socksumm -- Display a summary of open sockets (grinder)</title>
    <link>http://prlmnks.org/html/572712.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/572712.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#! /usr/bin/perl -w## socksumm -- socket usage summary## Copyright (C) 2005-2006 David Landgrenuse strict;use Getopt::Long;my $VERSION = &#39;1.0&#39;;my $ok = GetOptions(    &#39;help&#39;,         \my $help,    &#39;localport=s&#39;,  \my $watch_local_port,    &#39;remoteport=s&#39;, \my $watch_remote_port,    &#39;port=s&#39;,       \my $watch_port,    &#39;sleep=i&#39;,      \my $sleep,    &#39;version&#39;,      \my $version,    &#39;num=i&#39;,        \my $num,);if( not $ok or $help ) {    eval &quot;use Pod::Usage&quot;;    if( $@ ) {        print &lt;&lt;HELP;$0 [-localport=?] [-remoteport=?] [-port=?] [-sleep=n] [-num=n](install Pod::Usage for detailed help)HELP    }    else {        pod2usage(1);    }    exit;}$sleep ||= 60;if( $version ) {    eval &quot;use File::Basename&quot;;    print +($@ ? $0 : basename($0)), &quot; v$VERSION\n&quot;;    exit 0;}my $netstat_re;my $args;# platform-specific settings;{    my $ip_re = &#39;\d+(?:\.\d+){3}&#39;;    if( $^O eq &#39;freebsd&#39; ) {        $args = &#39;-nf inet&#39;;        $netstat_re = qr/^\S+(?:\s+\d+){2}\s+($ip_re)[:.](\d+)\s+($ip_re)[:.](\d+)\s+(\S+)\s*$/;    }    elsif( $^O eq &#39;linux&#39; ) {        $args = &#39;-n --inet&#39;;        $netstat_re = qr/^\S+(?:\s+\d+){2}\s+($ip_re)[:.](\d+)\s+($ip_re)[:.](\d+)\s+(\S+)\s*$/;    }    elsif( $^O eq &#39;solaris&#39; ) {        $args = &#39;-nf inet&#39;;        $netstat_re = qr/^($ip_re)\.(\d+)\s+($ip_re)\.(\d+)(?:\s+\d+){4}\s+(\S+)\s*$/;    }    else {        die &quot;Don&#39;t know how to decode netstat on $^O\n&quot; unless defined $args;    }}# resolve service names if we candefined $_ and /\D/ and $_ = getservbyname($_,&#39;tcp&#39;) || $_    for ($watch_local_port, $watch_remote_port, $watch_port);my %state;my @col = qw(    ESTABLISHED CLOSE_WAIT TIME_WAIT FIN_WAIT_1 FIN_WAIT_2 SYN_SENT SYN_RECV LAST_ACK);print &quot;estab close twait finw1 finw2 syntx synrx lastk total\n&quot;;while( 1 ) {    my $total    = 0;    @state{@col} = (0) x @col;    open my $in, &quot;netstat $args |&quot;        or die &quot;Cannot open pipe from netstat: $!\n&quot;;    while( &lt;$in&gt; ) {        chomp;        next unless my($local_host, $local_port, $remote_host, $remote_port, $state)            = /$netstat_re/;        next if $watch_port            and $local_port  != $watch_port            and $remote_port != $watch_port        ;        next if $watch_local_port  and $local_port  != $watch_local_port;        next if $watch_remote_port and $remote_port != $watch_remote_port;        $state =~ s/^(FIN_WAIT)(\d+)$/$1_$2/; # munge Linux variant        ++$state{$state};        ++$total;    }    close $in;    # display one line of data    my $timestamp = sprintf( &#39;%02d:%02d:%02d&#39;, (localtime)[2,1,0] );    printf &quot;%5d %5d %5d %5d %5d %5d %5d %5d %5d %s&quot;,        @state{@col}, $total, $timestamp;    delete @state{@col};    # deal with unknown or don&#39;t-care socket states    if( %state ) {        print &#39; &#39;, join( &#39; &#39;, map {&quot;$_=$state{$_}&quot;} sort keys %state );        %state = ();    }    print &quot;\n&quot;;    last if defined $num and --$num &lt;= 0;    sleep $sleep;}exit 0;__END__=head1 NAMEsocksumm - Display a summary of open sockets=head1 SYNOPSISB&lt;socksumm&gt; [B&lt;-l&gt;,B&lt;-localport&gt;] [B&lt;-r&gt;,B&lt;-remoteport&gt;] [B&lt;-p&gt;,B&lt;-port&gt;] [B&lt;-s&gt;,B&lt;-sleep&gt;] [B&lt;-n&gt;,B&lt;-num&gt;] [B&lt;-version&gt;]=head1 DESCRIPTIONParse the output of the C&lt;netstat(1)&gt; command and produce a summaryof the socket connections on a port.=head1 OPTIONS=over 5=item B&lt;-l&gt;,B&lt;-localport&gt;Summarise socket connections on this local port. Numeric or symbolic names(for example 389 or C&lt;ldap&gt;) are recognised. In otherwords, use this tomonitor inbound connections.=item B&lt;-r&gt;,B&lt;-remoteport&gt;Summarise socket connections on this remote port. Numeric or symbolic namesare recognised. Use this to monitor outbound connections.=item B&lt;-p&gt;,B&lt;-port&gt;Summarise socket connections on this port. Numeric or symbolic namesare recognised. Use this to monitor eitherbound connections.=item B&lt;-s&gt;,B&lt;-sleep&gt;Time to sleep between invocations of C&lt;netstat&gt;. A sixty (60) second sleeptime is assumed if this switch is omitted.=item B&lt;-n&gt;,B&lt;-number&gt;Produce this many summaries of C&lt;netstat&gt; and then exit.=back=head1 EXAMPLESC&lt;socksumm -l=ldap -s=10&gt;Summarise the inbound connections to the LDAP listener port. Will produceoutput that looks similar to the following: estab close twait finw1 finw2 syntx synrx lastk total   519     0     4     0     0     0     0     0   523 12:42:50   524     0     2     0     0     0     0     1   527 12:43:00   516     0     3     0     0     0     0     0   519 12:43:11C&lt;socksumm -r=22 -s=3600&gt;See how many outbound C&lt;ssh&gt; connections are open every hour.=head1 BUGSAssumes that C&lt;netstat&gt; can be found on the PATH. If you are runningC&lt;netstat&gt; on a platform other than FreeBSD, Linux or Solaris thescript will die. Please mail me the output and I&#39;ll endeavour toincorporate it (or, better yet, send me patches).=head1 COPYRIGHTCopyright 2005-2006 David Landgren.This script is free software; you can redistribute it and/or modify itunder the same terms as Perl itself.=head1 AUTHORDavid Landgrenjoin chr(0x40) =&gt; reverse qw[landgren.net david]=cut&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Reaped: Email using sendmail (NodeReaper)</title>
    <link>http://prlmnks.org/html/572473.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/572473.html</guid>

    <description>
        This node was taken out by the &lt;a href=&quot;/out/node/NodeReaper&quot;&gt;NodeReaper&lt;/a&gt; on &lt;a href=&quot;/out/localtime/2006-09-12 04-40-50&quot;&gt;2006-09-12 04-40-50&lt;/a&gt;&lt;BR&gt;Reason:  &amp;#91;&lt;a href=&quot;/out/node/marto&quot;&gt;marto&lt;/a&gt;]: Reap, this is a dupe of &lt;a href=&quot;/html/572472.html&quot;&gt;Email using sendmail&lt;/a&gt;&lt;p&gt;You may view &lt;a href=&quot;/out/href/?node=Visit%20Reaped%20Nodes&amp;amp;nodenum=572473&quot;&gt;the original node and the consideration vote tally&lt;/a&gt;.&lt;/p&gt;
    </description>
</item>

        

<item>
    <title>Email using sendmail (alandev)</title>
    <link>http://prlmnks.org/html/572472.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/572472.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse Mail::Mailer;$mailer=Mail::Mailer-&gt;new(&quot;sendmail&quot;);print &quot;\nRecipient Address:&quot;;$too=&lt;&gt;;chomp($too);@to=split(&quot;;&quot;,$too);print &quot;\nSubject:&quot;;$mail_subject=&lt;&gt;;chomp($mail_subject);print &quot;\nContent:&quot;;$mail_content=&lt;STDIN&gt;;$mailer-&gt;open( { From    =&gt; $from,To      =&gt; \@to,Subject =&gt; $mail_subject});print $mailer $mail_content;close($mailer); &lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Reaped: Oral sex (NodeReaper)</title>
    <link>http://prlmnks.org/html/571357.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/571357.html</guid>

    <description>
        This node was taken out by the &lt;a href=&quot;/out/node/NodeReaper&quot;&gt;NodeReaper&lt;/a&gt; on &lt;a href=&quot;/out/localtime/2006-09-05 20-28-25&quot;&gt;2006-09-05 20-28-25&lt;/a&gt;&lt;BR&gt;Reason:  &amp;#91;&lt;a href=&quot;/out/node/liverpole&quot;&gt;liverpole&lt;/a&gt;]: Total garbage.&lt;p&gt;You may view &lt;a href=&quot;/out/href/?node=Visit%20Reaped%20Nodes&amp;amp;nodenum=571357&quot;&gt;the original node and the consideration vote tally&lt;/a&gt;.&lt;/p&gt;
    </description>
</item>

        

<item>
    <title>uhead: &quot;head -c&quot; for utf8 data (graff)</title>
    <link>http://prlmnks.org/html/570713.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/570713.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl=head1 NAMEuhead -- unicode-aware version of unix &quot;head&quot;=head1 SYNOPSISuhead -c N [file ...]   show first N unicode chars from file(s)=head1 DESCRIPTIONThis does what the standard &quot;head -c N&quot; command (GNU version) would do(i.e. show the first N characters from one or more files), with justthe following differences:=over 4=item *The &quot;-c N&quot; option is required (not optional)=item *N refers to a number of UTF-8 encoded unicode characters rather thanbytes=item *&quot;Negative&quot; values for N are not supported (you cannot elect to viewall but the last N characters)=backIf no files are provided on the command line, it will read from STDINinstead. (But if it notices that STDIN is actually the user&#39;s tty, nota pipe or redirection from a file, it will exit with a suitable errormessage.)=head1 AUTHORDavid Graff &lt;graff(at)ldc.upenn.edu&gt;=cutuse strict;my $Usage = &quot;Usage: $0 -c N [file ...]\n&quot;;die $Usage unless ( @ARGV &gt; 1 and $ARGV[0] eq &#39;-c&#39; and                    $ARGV[1] =~ /^\d+$/ );shift;my $show_chrs = shift;if ( -t ) {    @ARGV or die &quot;You need to provide some data (pipe or file(s))\n$Usage&quot;;}else {    @ARGV = ( &#39;__STDIN__&#39; );}binmode STDOUT, &quot;:utf8&quot;;my $nfiles = @ARGV;while ( @ARGV ) {    my $file = shift;    my $head;    if ( $file eq &#39;__STDIN__&#39; ) {        binmode STDIN, &quot;:utf8&quot;;        read STDIN, $head, $show_chrs;    }    else {        if ( open( I, &quot;&lt;:utf8&quot;, $file )) {            read I, $head, $show_chrs;        }        else {            warn &quot;open failed on $file\n&quot;;            next;        }    }    print &quot;\n==&gt; $file &lt;==\n&quot; if ( $nfiles &gt; 1 );    print $head,&quot;\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Yet Another Sudoku Solver (SubStack)</title>
    <link>http://prlmnks.org/html/569825.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/569825.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl# solve.pl - Solves all sudoku puzzles, even really hard ones# Just feed it a file with each row on a line and spaces for the blanks.use strict;use warnings;use Storable qw(dclone);my $DEBUG = 0;die &quot;usage: $0 file\n&quot; unless @ARGV;open my $fh, &quot;&lt;&quot;, $ARGV[0] or die &quot;failed to open &#39;$ARGV[0]&#39;: $!\n&quot;;# Store all potential squares (by which I mean the board-type thing).# This grows as new potentials solutions manifest and shrinks as they fail.my @squares = [ map [ m/([\d ])/g ], &lt;$fh&gt; ];# Number of potential solutions that will be acceptable for the given search.# This is automatically adjusted based on the availability of good solutions.my $threshold = 1;close $fh;# Iternate through each spot and see how many choices for numbers there are.# If the number of choices meets the threshold, fill the coordinate in, on# multiple instances of the square if needed.scan: while  (grep $_ eq &quot; &quot;, map @$_, @{$squares[0]}) {  # keep track of y coordinate on the square  my $y = -1;  for my $row (@{$squares[0]}) {    $y++;    # keep track of x coordinate on the square    my $x = -1;    for my $number (@$row) {      $x++;      next unless $number eq &quot; &quot;; # only bother solving blank squares      # Load all the numbers in the coordinate&#39;s 3x3 magic square.      # They aren&#39;t really magic squares of course, but it makes them easier to      # refer to.      my @magic = grep $_ ne &quot; &quot;,        map @{$_}[int($x / 3) * 3 .. int($x / 3) * 3 + 2 ],          @{$squares[0]}[int($y / 3) * 3 .. int($y / 3) * 3 + 2];      # Load all the numbers in the coordinate&#39;s row.      my @row_nums = grep $_ ne &quot; &quot;, @$row;      # Load all the numbers in the coordinate&#39;s column.      my @col_nums = grep $_ ne &quot; &quot;, grep defined, map $_-&gt;[$x], @{$squares[0]};      # Count up the occurances of the numbers the coordinate can&#39;t be.      my %count = map { $_ =&gt; 0 } 1 .. 9;      $count{$_}++ for @magic, @row_nums, @col_nums;      # All the possible values for the coordinate      my @possible = grep $count{$_} == 0, keys %count;      print &quot;($x, $y): &quot;,        &quot;  possible = @{[ sort @possible ]}\n&quot;,        &quot;  magic    = @{[ sort @magic ]}\n&quot;,        &quot;  cols     = @{[ sort @col_nums ]}\n&quot;,        &quot;  rows     = @{[ sort @row_nums ]}\n&quot;      if $DEBUG;      if (@possible == $threshold) {        # Number of possibilities meets the threshold        print &quot;Solved coordinate ($x, $y) == (@possible)\n&quot; if $DEBUG;        # Throw the first possibility onto the current square.        $squares[0][$y][$x] = shift @possible;        for (@possible) {          # Throw the other possibilities into copies of the current square.          push @squares, dclone($squares[0]);          $squares[$#squares][$y][$x] = $_;        }        # Set the threshold back to 1 for a successful match.        $threshold = 1;        next scan;      }      # Scrap squares that don&#39;t have any possible choices for a particular      # coordinate.      if (@possible == 0) {        print &quot;Scrapping guess due to ($x, $y)\n&quot; if $DEBUG;        shift @squares;        die &quot;No more guesses! Unsolvable!\n&quot; unless @squares;        $threshold = 1;        next scan;      }    }  }  # The possibilities weren&#39;t good enough. Be less picky next iteration.  $threshold++;}show(0);sub show { # useful for debugging the squares while running  print join(&quot;&quot;, @$_), &quot;\n&quot; for @{$squares[$_[0]]};}&lt;/pre&gt;Spaces are used for blanks. Here&#39;s an example to try out:&lt;pre class=&quot;block_code&quot;&gt;    9  4  7  6    89    21      36 8  42 67  9 68      61    54    8  7  4  1    &lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>spamstats.pl (tcf03)</title>
    <link>http://prlmnks.org/html/569766.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/569766.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -wuse strict;#use diagnostics;#use Data::Dumper;my %action = ( &#39;RECV&#39; =&gt; { 0   =&gt; &#39;Allowed Message&#39;,                           1   =&gt; &#39;Aborted Message&#39;,                           2   =&gt; &#39;Blocked Message&#39;,                           3   =&gt; &#39;Quarantined Message&#39;,                           4   =&gt; &#39;Tagged Message&#39;,                           5   =&gt; &#39;Deferred Message&#39;,                           6   =&gt; &#39;Per-User Quarantined Message&#39;,                           7   =&gt; &#39;Whitelisted Message&#39;,                           &#39;-&#39; =&gt; &#39;Undefined&#39; },               &#39;SEND&#39; =&gt; { 1   =&gt; &#39;Delivered Message&#39;,                           2   =&gt; &#39;Rejected Message&#39;,                           3   =&gt; &#39;Deferred Message&#39;,                           4   =&gt; &#39;Expired Message&#39;,                           &#39;-&#39; =&gt; &#39;Undefined&#39; } );$action{&#39;SCAN&#39;} = $action{&#39;RECV&#39;};my %reason = ( 0    =&gt; &#39;Undefined&#39;,               1    =&gt; &#39;Virus&#39;,               2    =&gt; &#39;Banned Attachment&#39;,               3    =&gt; &#39;RBL Match&#39;,               4    =&gt; &#39;Rate Control&#39;,               5    =&gt; &#39;Too Many Message In Session&#39;,               6    =&gt; &#39;Timeout Exceeded&#39;,               7    =&gt; &#39;No Such Domain&#39;,               8    =&gt; &#39;No Such User&#39;,               9    =&gt; &#39;Subject Filter Match&#39;,               10   =&gt; &#39;&#39;,               11   =&gt; &#39;Client IP&#39;,               12   =&gt; &#39;Recipient Address Rejected&#39;,               13   =&gt; &#39;No Valid Recipients&#39;,               14   =&gt; &#39;Domain Not Found&#39;,               15   =&gt; &#39;Sender Address Rejected&#39;,               16   =&gt; &#39;&#39;,               17   =&gt; &#39;Need Fully Qualified Recipient&#39;,               18   =&gt; &#39;Need Fully Qualified Sender&#39;,               19   =&gt; &#39;Unsupported Command&#39;,               20   =&gt; &#39;MAIL FROM Syntax Error&#39;,               21   =&gt; &#39;Bad Address Syntax&#39;,               22   =&gt; &#39;RCPT TO Syntax Error&#39;,               23   =&gt; &#39;Send EHLO/HELO first&#39;,               24   =&gt; &#39;Need MAIL Command&#39;,               25   =&gt; &#39;Nested Mail Command&#39;,               26   =&gt; &#39;&#39;,               27   =&gt; &#39;EHLO/HELO Syntax Error&#39;,               28   =&gt; &#39;&#39;,               29   =&gt; &#39;&#39;,               30   =&gt; &#39;Mail Protocol Error&#39;,               31   =&gt; &#39;Score&#39;,               32   =&gt; &#39;&#39;,               33   =&gt; &#39;&#39;,               34   =&gt; &#39;Header Filter Match&#39;,               35   =&gt; &#39;Sender Block/Accept&#39;,               36   =&gt; &#39;Recipient Block/Accept&#39;,               37   =&gt; &#39;Body Filter Match&#39;,               38   =&gt; &#39;Message Size Bypass&#39;,               39   =&gt; &#39;Intention Analysis Match&#39;,               40   =&gt; &#39;SPF/Caller-ID&#39;,               41   =&gt; &#39;Client Host Rejected&#39;,               42   =&gt; &#39;&#39;,               43   =&gt; &#39;&#39;,               44   =&gt; &#39;Authentication Not Enabled&#39;,               45   =&gt; &#39;Allowed Message Size Exceeded&#39;,               46   =&gt; &#39;Too Many Recipients&#39;,               47   =&gt; &#39;Need RCPT Command&#39;,               48   =&gt; &#39;DATA Syntax Error&#39;,               49   =&gt; &#39;Internal Error&#39;,               50   =&gt; &#39;Too Many Hops&#39;,               51   =&gt; &#39;&#39;,               52   =&gt; &#39;&#39;,               53   =&gt; &#39;&#39;,               54   =&gt; &#39;&#39;,               55   =&gt; &#39;Invalid Parameter Syntax&#39;,               56   =&gt; &#39;STARTTLS Syntax Error&#39;,               57   =&gt; &#39;TLS Already Active&#39;,               58   =&gt; &#39;Too Many Errors&#39;,               59   =&gt; &#39;Need STARTTLS First&#39;,               60   =&gt; &#39;Spam Fingetpront Found&#39;,               &#39;-&#39;  =&gt; &#39;Undefined&#39; );## Check Usage ##die &quot;usage: spamstat.pl &lt;logfile&gt;\n&quot;    unless ( defined ($ARGV[0]) and -f $ARGV[0]);my $file;open $file, $ARGV[0] or    die &quot;Unable to open $ARGV[0]: $!\n&quot;;# Define our buckets for collecting datamy %bucket  = ();my %USER    = ();my %VIRUS   = ();my %SPAM    = ();# These numbers must be valid reason codes...my @wanted = ( 1, 60 );# We rely on autovivification for counting # it almost seems like cheating...for (&lt;$file&gt;){    chomp;        my ( $month, $day, $time, $host,         $process, $clientIP, $MessageID,         $timeStart, $timeEnd, $service, @INFO ) = split /\s+/;    # anything after this point can/should be changed depending on your needs.    my ( $sender, $recip, $action_, $reason_, @reasonextra,         $encrypted, $score, $queueid, @response );       if ( $service =~ /^RECV/ )    {        ( $sender, $recip, $action_, $reason_, @reasonextra ) = (@INFO);        print &quot;Action = $action_ Service = $service\n&quot; unless            $action{$service}{$action_};        print &quot;Reason = $reason_  Service = $service\n&quot; unless            $reason{$reason_};        $VIRUS{$host}{$reasonextra[0]}{&#39;count&#39;}++ if ( $reason_ == 1 );        $SPAM{$host}{$recip}{&#39;count&#39;}++ if ( $action_  == 2 and                                             $reason_  == 60 );        $USER{$host}{$recip}{$action{$service}{$action_}}{$reason{$reason_}}{&#39;count&#39;}++;            #if ( grep /^$reason_$/, @wanted );        $bucket{$host}{$service}{$action{$service}{$action_}}{$reason{$reason_}}{&#39;count&#39;}++    }    if ( $service =~ /^SCAN/ )    {        ( $encrypted, $sender, $recip, $score, $action_, $reason_, @reasonextra ) = (@INFO);        print &quot;Action = $action_ Service = $service\n&quot; unless            $action{$service}{$action_};        print &quot;Reason = $reason_  Service = $service\n&quot; unless            $reason{$reason_};                $VIRUS{$host}{$reasonextra[0]}{&#39;count&#39;}++ if ( $reason_ == 1 );        $SPAM{$host}{$recip}{&#39;count&#39;}++ if ( $action_  == 2 and                                             $reason_  == 60 );        $USER{$host}{$recip}{$action{$service}{$action_}}{$reason{$reason_}}{&#39;count&#39;}++;            #if ( grep /^$reason_$/, @wanted );        $bucket{$host}{$service}{$action{$service}{$action_}}{$reason{$reason_}}{&#39;count&#39;}++;    }    if ( $service =~ /^SEND/ )    {        ( $encrypted, $action_, $queueid, @response ) = (@INFO);        $bucket{$host}{$service}{$action{$service}{$action_}}{&#39;count&#39;}++;    }}# Example reports...#for my $host ( keys %VIRUS )#{#    print &quot;[$host]\n&quot;;#    for my $virus ( sort keys %{$VIRUS{$host}} )#    {#        printf &quot;\t%-50s %3d\n&quot;, $virus, $VIRUS{$host}{$virus}{&#39;count&#39;};#    }                #}#for my $host ( keys %USER )#{#    print &quot;[$host]\n&quot;;#    for my $user ( keys %{$USER{$host}} )#    {#        print &quot; $user\n&quot;;#        for my $action ( keys %{$USER{$host}{$user}} )#        {#            print &quot;\t  $action\n&quot;;#            for my $reason ( keys %{$USER{$host}{$user}{$action}} )#            {#                print &quot;\t\t$reason&quot;, #                &quot; $USER{$host}{$action}{$reason}{&#39;count&#39;}\n&quot;;#            }#        }#    }#}#for my $host ( keys %SPAM )#{#    for my $user ( keys %{ $SPAM{$host} } )#    {#        print &quot;$user [$SPAM{$host}{$user}{&#39;count&#39;}]\n&quot;;#    }#}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>BigDemon (LordScinawa)</title>
    <link>http://prlmnks.org/html/568445.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/568445.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;# # To install this program:# # mkdir /etc/abdemon# # cd /etc/abdemon# # jed /user.conf# # write here user and pass coded in base64 :) # # user:pass# # jed /abcomand.conf# # write here the command to startup or shtudown the demon# # Demon Name:command:Description#!/usr/bin/perl -wuse strict;use warnings;use IO::Socket::INET;use MIME::Base64;sub login{print&quot;Starting LogIN\n&quot;;my $session = $_[0];print $session &quot;LogIN: AbsoluteDemon\n\r&quot;;print $session &quot;UserName:&quot;;my $ut=&lt;$session&gt;;print $session &quot;Pass:&quot;;my $pa=&lt;$session&gt;;open DB, &quot;&lt;&quot;, &quot;user.conf&quot;;#open DB, &quot;&gt;&quot;, &quot;/etc/abdemon/user.conf&quot;;$a=&lt;DB&gt;;my @vagone=split( /:/, $a);my $user=beis($vagone[0]);my $pass=beis($vagone[1]);chomp($user, $pass);$ut =~ s/\r\n\z//;$pa =~ s/\r\n\z//;chomp($ut, $pa);if ($ut eq $user) {if ($pa eq $pass){print &quot;LogIN Succesfull\n&quot;;choose($session);}}else {print $session &quot;User can NOT log in&quot;;sleep 1;uail(); }}sub choose {my $session=$_[0];my @comz;my $ch;#open COM, &quot;&lt;&quot;, &quot;/etc/abdemon/adcomand.conf&quot;;open COM, &quot;&lt;&quot;, &quot;C:/abd/abcomand.conf&quot;;my $num=0;while (my $riga=&lt;COM&gt;) {$num=$num+1;print $session &quot;$num, $riga\n\r&quot;;    $comz[$num]=$riga;                                #array che contiene i comandi pi il numero }do  { $ch=&lt;$session&gt;;#ricevo il numero di comando    $ch =~ s/\n\r\z//;my $dirty=$comz[$ch];#tiro fuori la riga e la chompochomp($dirty);my @command=split( /:/, $dirty);#tiro fuori il comandoprint $session &quot;$command[1]\n\r&quot;;print &quot;$ch\n\r&quot;; system($command[1]);print $session &quot;And now?&quot;}while ($ch ne &quot;0&quot;);close $session;close COM;sleep 10;uail();}sub beis { my $a=decode_base64($_[0]); print &quot;Decoding..\n&quot;;return $a;} sub uail {my @time = (localtime);my $sock = new IO::Socket::INET(LocalPort =&gt; &#39;7350&#39;,#Localaddr =&gt;&#39;localhost&#39;,Proto =&gt; &#39;tcp&#39;,Listen =&gt; &#39;1&#39;) or die &quot;Cannot Listen on sock! $!\n&quot;;my $session = $sock-&gt;accept;print &quot;Socket Created\n&quot;;#open LOGZ, &#39;&gt;&gt;&#39;, &#39;/etc/abdemon/access_log&#39;;open LOGZ, &#39;&gt;&gt;&#39;, &#39;logz.txt&#39;;my $ip=$session-&gt;peerhost;print (LOGZ &quot;$ip at time: $time[2]h $time[1]m $time[0]s Day: $time[3]/$time[4]($time[5]-100) &quot;);close LOGZ;print&quot;Logged IP\n&quot;;login($session);close $sock;}print&quot;Absolute Demon 1.0 (un)stable relase\n&quot;;chdir &quot;C:/abd&quot;;uail();&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>perl-assoc 0.31 (Maze)</title>
    <link>http://prlmnks.org/html/567770.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/567770.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl#perl-assoc 0.31#by Chris Monahan + help from perl monks##This is free software, you can distribute it under the same#terms as perl itself####a simple listing script for associations on a win32 system####like assoc for win 2000/XP except there isn&#39;t ####yet any functionality to change association####Just list them...####could be used on win 9.x or others without assoc##since 0.1 added options and help and rewrote to make clearer (thanks ikegami)#but for some reason looking up a specific extension has been broken... at a loss here...#since: 0.2 fixed bugs - albiet a little sloppily turns out looking up specific extension#was just me using = instead of ==, *slaps forhead*#since: 0.25 added functionality for changing (not deleting or creating) a single association#and listing more than one extension, also a foil to bail when it tries to be executed in a #non win32 enviromentuse warnings;use strict;unless ($^O =~ /Win32/){die &quot;This program requires a full Win32 enviroment&quot;}else{## not using indents for this master block because it&#39;s so huge and boringuse Win32::TieRegistry (Delimiter =&gt; &quot;:&quot;);#define subroutines --sub scan { #for scanning arrays in generalmy $hunt = $_[0];my @founda = 0;#if (defined($hunt)){@founda = grep {/$hunt/} @_;#}#else{#$founda[$#_] = 1;#}return $#founda;}sub help { # output helpprint&lt;&lt;EOF;perl-assoc 0.2Displays file extension associations-to see particular extensions: ASSOC .ext1 .ext2 .ext3... [options]  .ext  Specifies the file extension to display  -to see all file extensions: ASSOC [options]will show a list of all known file associations-to change a single extension association (creating/destroying associations not yet supported):ASSOC .ext=filetypefiletype specifies what identifier this extension will use in the registry and the interface available options are: /W - warn about extensions not assigned with a filetype /F - format output with paddingeg: assoc .htm .pl /Fmight give you:.htm \t = \t FireFoxHTML.pl \t = \t Perl EOF}sub mainlist {#simple abstraction for problem with calling with no variablesforeach my $ext (keys %{ $Registry-&gt;{&quot;Classes:&quot;} }) {  next unless substr($ext, 0, 1) eq &#39;.&#39;;  my $RegHash = $Registry-&gt;{&quot;Classes:$ext&quot;};  if (not exists $RegHash-&gt;{&#39;:&#39;}) {    print &quot;\t --No filetype associated with $ext\n&quot; if scan(&quot;/W&quot;, @_);    next;  }  my $class = $RegHash-&gt;{&quot;:&quot;};  chop $ext;  if (scan(&quot;/F&quot;, @_)){     print &quot;$ext \t = \t $class \n&quot;;  }  else {  print &quot;$ext=$class \n&quot;} }} #declare my variablesmy $ext;my $RegHash;my $class;my $extcnt = 0;my $warnalert;my @cnvbits;if(@ARGV){#-beginning of silly solution for calling it with no variables#finding pleas for helpif ($ARGV[0] eq &quot;/?&quot;) { help();}elsif ($ARGV[0] eq &quot;help&quot;) {help();}##what to do when called with extension&#39;s (plural)elsif (substr ($ARGV[0] ,0,1) eq &#39;.&#39;){@cnvbits = (split /=/, $ARGV[0]);if (@cnvbits == 2 ){my $RegHash = $Registry-&gt;{&quot;Classes:$cnvbits[0]&quot;};$RegHash-&gt;{&#39;:&#39;} = $cnvbits[1];print &quot;$cnvbits[0] = $cnvbits[1] \n&quot;;}else{while (substr ($ARGV[$extcnt] ,0,1) eq &#39;.&#39;){my $ext = $ARGV[$extcnt];my $RegHash = $Registry-&gt;{&quot;Classes:$ext&quot;};$warnalert = 0; if (not exists $RegHash-&gt;{&#39;:&#39;}) {   if (scan(&quot;/W&quot;, @ARGV)) {print &quot;\t  --No filetype found associated with $ext\n&quot;}    else {print &quot;$ext=? \n&quot;};   $warnalert = 1; } unless($warnalert){ my $class = $RegHash-&gt;{&quot;:&quot;}; if (scan(&quot;/F&quot;, @ARGV)){  print &quot;$ext \t = \t $class \n&quot;;}else { print &quot;$ext=$class \n&quot;}}$extcnt++} }}##and finally when all else fails just list everythingelse {mainlist(@ARGV);}}else {#-end of silly solution for calling it with no variblesmainlist();}}#end of master block#to-do##lots##need to find out why I can&#39;t seem to create a default value when one doesn&#39;t already exist#create a subroutine #since it&#39;ll have to be renamed to work on NT, add a sub for pinpointing the name used to run it for use in the help sub#abstract common functions as it gets larger, can&#39;t rely on copy and paste##add the abstract functions to a perl module##create an ftype tool to go with this one&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>perl-assoc 0.1 (Maze)</title>
    <link>http://prlmnks.org/html/567756.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/567756.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#perl-assoc 0.1#by Chris Monahan + help from perl monks##This is free software, you can distribute it under the same#terms as perl itself####a simple listing script for associations on a win32 system####like assoc for win 2000/XP except there isn&#39;t ####yet any functionality to change association####Just list them...quite uselessly - just proof of concept#use warnings;use strict;use Win32::TieRegistry (Delimiter =&gt; &quot;:&quot;);#use Data::Dumper;my $class;my $val;my $key;#my $error;if (not defined($ARGV[0])){ foreach $class (keys %{ $Registry-&gt;{&quot;Classes:&quot;} }){if ($class =~ /^[.]/) {my $RegHash = $Registry-&gt;{&quot;Classes:$class&quot;};#$error = Dumper %RegHash;while (my ($key, $val) = each(%$RegHash)){#or die &quot;failure to read registry: $! \nlast contents of Registry Hash = $error \n&quot;; if ($key eq &quot;:&quot;){ print &quot;$class \t = \t $val\n&quot;; } #else{#warn &quot;unable to recognise association for $class&quot;#}}}}}else {$class = $ARGV[0];if ($class =~ /^[.]/) {my $RegHash = $Registry-&gt;{&quot;Classes:$class&quot;};#$error = Dumper %RegHash;while (my ($key, $val) = each(%$RegHash)){#or die &quot;failure to read registry: $! \nlast contents of Registry Hash = $error \n&quot;; if ($key eq &quot;:&quot;){ print &quot;$class \t = \t $val\n&quot;; } #else{#warn &quot;unable to recognise association for $class&quot;#}}}}#To-Do:#everything#use more sensible looping for listing - thank you ikegami#enable formatting and verbose options#enable changing types## in the end possibly going into more advanced file type stuff## &lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Color diff for terminal (frodo72)</title>
    <link>http://prlmnks.org/html/567025.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/567025.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;use Carp;use Pod::Usage qw( pod2usage );use Getopt::Long qw( :config gnu_getopt require_order pass_through );use Fatal qw( open );use Term::ANSIColor qw( :constants );use File::Basename qw( basename );use version; my $VERSION = qv(&#39;0.0.1&#39;);# Pre-mangling based on the name used to install the programmy %config;if (basename($0) eq &#39;cdiff&#39;) {   # Blindly re-route all options to diff. @ARGV shall be used to   # build the external command that will output the text to be colorised   unshift @ARGV, &#39;diff&#39;;}else {   GetOptions(\%config, &#39;usage&#39;, &#39;help&#39;, &#39;man&#39;, &#39;version&#39;);   pod2usage(&quot;$0 v$VERSION&quot;) if $config{version};   pod2usage(-verbose =&gt; 99, -sections =&gt; &#39;USAGE&#39;) if $config{usage};   pod2usage(-verbose =&gt; 99, -sections =&gt; &#39;NAME|USAGE|OPTIONS|EXAMPLES&#39;)     if $config{help};   pod2usage(-verbose =&gt; 2) if $config{man};}# Other recommended modules (uncomment to use):#  use IO::Prompt;#  use Readonly;#  use Data::Dumper;#  use Log::Log4perl qw( :easy );# Script implementation heremy %color_for = (   &#39;&lt;&#39; =&gt; RED,   &#39;-&#39; =&gt; RED,   &#39;&gt;&#39; =&gt; GREEN,   &#39;+&#39; =&gt; GREEN,   &#39;@&#39; =&gt; BLUE,);# Establish inputmy $fh;if (scalar @ARGV) {   my $command = join &#39; &#39;, map { quotemeta } @ARGV;   open $fh, &#39;-|&#39;, $command;}else {   $fh = \*STDIN;}# Iterate over input and color itwhile (&lt;$fh&gt;) {   my $first_char = substr $_, 0, 1;   delete $color_for{&#39;-&#39;} if $first_char eq &#39;&lt;&#39;;   print BOLD, $color_for{$first_char} if exists $color_for{$first_char};   print;   print RESET if exists $color_for{$first_char};}close $fh;__END__=head1 NAMEcolordiff - colorise a C&lt;diff&gt; output, optionally invoking a command cdiff     - call C&lt;diff(1)&gt; and colorise its output=head1 VERSIONCall with C&lt;--version&gt; (not available in C&lt;cdiff&gt;). It should be 0.0.1.=head1 USAGE   colordiff [--usage] [--help] [--man] [--version]   [ some command producing diff output ] | colordiff   colordiff &lt; some-diff-file   colordiff [ some command producing diff output ]   cdiff [ diff(1) options and command line ]=head1 OPTIONSC&lt;colordiff&gt; has the same options of the subcommand it&#39;s required tocall, with the following exceptions:=over=item --helpprint a somewhat more verbose help, showing usage, this description ofthe options and some examples from the synopsis.=item --manprint out the full documentation for the script.=item --usageprint a concise usage line and exit.=item --versionprint the version of the script.=backC&lt;cdiff&gt; always I&lt;forwards&gt; the command line to C&lt;diff(1)&gt;, so seethe manpage to find the options. Note that not all options will bemeaningful to use with C&lt;cdiff&gt;; notably, if you want to produce acompact style diff the colorisation will be mostly unuseful.=head1 EXAMPLES   # get full documentation   shell$ colordiff --man   # Use as a filter   shell$ diff file1 file2 | colordiff   # We can spare a few typing, simple invocation of diff   shell$ cdiff file1 file2   # Pass options to diff, e.g. get unified diff   shell$ cdiff -u file1 file2   # The filter incarnation is still useful, anyway - e.g.   # with version control systems   shell$ cvs diff -u -r REL_1_0 somefile | colordiff   shell$ svk diff somefile | colordiff   # Save a few types   shell$ colordiff cvs diff -u -r REL_1_0 somefile   shell$ colordiff svk diff somefile   # These two are equivalent, choose the best for you   shell$ colordiff diff -u file1 file2   shell$ cdiff -u file1 file2   # These aliases could turn useful, assumes sh or compatibles   shell$ alias svkdiff=&#39;colordiff svk diff&#39;   shell$ svkdiff somefile   shell$ svkdiff -r -1 somefile   shell$ alias cvsdiff=&#39;colordiff cvs diff -u&#39; # I like unified diff   shell$ cvsdiff -r REL_1_0 somefile  =head1 DESCRIPTIONC&lt;colordiff&gt; colorises a C&lt;diff(1)&gt; text on the terminal, in order to makeit visually clear where the changes are. It is best suited to situation wherethe differences are small, i.e. they do not take pages and pages, becauseall colorisation happens in the terminal.When the command line of C&lt;colordiff&gt; is empty, the input text to coloriseis assumed to be on standard input. Otherwise, the command line isassumed to be a command which is invoked and whose output must becolorised. So, the following are equivalent:   shell$ command foo bar baz | colordiff   shell$ colordiff command foo bar bazbut you can save a little typing with the latter.When installed as C&lt;cdiff&gt;, it is assumed to be a blind wrapper aroundC&lt;diff(1)&gt;. In this case, C&lt;diff(1)&gt; will be invoked with the remainingoptions, so the following are equivalent:   shell$ cdiff foo bar baz   shell$ colordiff diff foo bar bazbut the former is stunningly faster to type and better to remember.Note that only &quot;plain diff&quot; and unified styles are supported forcolorisation.=head1 DIAGNOSTICSNone particular. If for some reason the pipe from the diff command cannotbe established the script will die with a hopefully meaningful message.=head1 CONFIGURATION AND ENVIRONMENTcolordiff requires no configuration files or environment variables.=head1 DEPENDENCIESYou won&#39;t get far without Term::ANSIColor.=head1 BUGS AND LIMITATIONSNo bugs have been reported.The error code from the diff command is not replicated as exit code ofC&lt;colordiff&gt;. This should not be a real limitation, because C&lt;colordiff&gt;is intended for interactive usage more than batch.Please report any bugs or feature requests through http://rt.cpan.org/=head1 AUTHORFlavio Poletti C&lt;flavio@polettix.it&gt;=head1 LICENCE AND COPYRIGHTCopyright (c) 2006, Flavio Poletti C&lt;flavio@polettix.it&gt;. All rights reserved.This script is free software; you can redistribute it and/ormodify it under the same terms as Perl itself. See L&lt;perlartistic&gt;and L&lt;perlgpl&gt;.Questo script  software libero: potete ridistribuirlo e/omodificarlo negli stessi termini di Perl stesso. Vedete ancheL&lt;perlartistic&gt; e L&lt;perlgpl&gt;.=head1 DISCLAIMER OF WARRANTYBECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTYFOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHENOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIESPROVIDE THE SOFTWARE &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHEREXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THEENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITHYOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALLNECESSARY SERVICING, REPAIR, OR CORRECTION.IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITINGWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/ORREDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BELIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USETHE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEINGRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR AFAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IFSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OFSUCH DAMAGES.=head1 NEGAZIONE DELLA GARANZIAPoich questo software viene dato con una licenza gratuita, nonc&#39; alcuna garanzia associata ad esso, ai fini e per quanto permessodalle leggi applicabili. A meno di quanto possa essere specificatoaltrove, il proprietario e detentore del copyright fornisce questosoftware &quot;cos com&#39;&quot; senza garanzia di alcun tipo, sia essa espressao implicita, includendo fra l&#39;altro (senza per limitarsi a questo)eventuali garanzie implicite di commerciabilit e adeguatezza peruno scopo particolare. L&#39;intero rischio riguardo alla qualit edalle prestazioni di questo software rimane a voi. Se il softwaredovesse dimostrarsi difettoso, vi assumete tutte le responsabilited i costi per tutti i necessari servizi, riparazioni o correzioni.In nessun caso, a meno che ci non sia richiesto dalle leggi vigentio sia regolato da un accordo scritto, alcuno dei detentori del dirittodi copyright, o qualunque altra parte che possa modificare, o redistribuirequesto software cos come consentito dalla licenza di cui sopra, potressere considerato responsabile nei vostri confronti per danni, iviinclusi danni generali, speciali, incidentali o conseguenziali, derivantidall&#39;utilizzo o dall&#39;incapacit di utilizzo di questo software. Ciinclude, a puro titolo di esempio e senza limitarsi ad essi, la perditadi dati, l&#39;alterazione involontaria o indesiderata di dati, le perditesostenute da voi o da terze parti o un fallimento del software adoperare con un qualsivoglia altro software. Tale negazione di garanziarimane in essere anche se i dententori del copyright, o qualsiasi altraparte,  stata avvisata della possibilit di tali danneggiamenti.Se decidete di utilizzare questo software, lo fate a vostro rischioe pericolo. Se pensate che i termini di questa negazione di garanzianon si confacciano alle vostre esigenze, o al vostro modo diconsiderare un software, o ancora al modo in cui avete sempre trattatosoftware di terze parti, non usatelo. Se lo usate, accettate espressamentequesta negazione di garanzia e la piena responsabilit per qualsiasitipo di danno, di qualsiasi natura, possa derivarne.=cut&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Subversion(SVN) pre-commit hook (runrig)</title>
    <link>http://prlmnks.org/html/562373.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/562373.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perlrequire SVN::Core;require SVN::Repos;require SVN::Fs;require SVN::Delta;package ChangeReceiver;my $file_re = qr/\.txt/;my $bad_re = qr/foo/;our @ISA = qw(SVN::Delta::Editor);sub add_file {  return [0, $_[1]];}sub open_file {  return [0, $_[1]];}sub apply_textdelta {  $_[1]-&gt;[0] = 1;  return;}sub close_file {  my ($self, $file_baton) = @_;  my ($changed, $path) = @$file_baton;  return unless $changed;  return unless $path =~ /$file_re/;  my $pool = SVN::Pool-&gt;new_default_sub;  my $stream = SVN::Fs::file_contents( $self-&gt;{txn_root}, $path, $pool );  my $bytes;  my $byte_cnt = 0;  my $exit_code = 0;  my $buffer = &#39;&#39;;  while ( $bytes = $stream-&gt;read( $buffer, $SVN::Core::STREAM_CHUNK_SIZE, 0 ) ) {    if ( $buffer =~ /$bad_re/ ) {      $exit_code=1;      last;    }    $byte_cnt += $bytes;    $buffer = &#39;&#39;;  }  $stream-&gt;close;  if ($exit_code) {    warn &quot;Bad file: $path\n&quot;;    exit $exit_code;  }  return;}package main;my ($rep, $txn) = @ARGV;my $rep = SVN::Repos::open($rep);my $fs = $rep-&gt;fs;my $txn_ptr = $fs-&gt;open_txn($txn);my $txn_root = SVN::Fs::txn_root($txn_ptr);my $base_root = $fs-&gt;revision_root($fs_ptr, SVN::Fs::txn_base_revision($txn_ptr));my $editor = ChangeReceiver-&gt;new;$editor-&gt;{txn_root} = $txn_root; # Bad OO I knowSVN::Repos::dir_delta($base_root, &#39;&#39;, &#39;&#39;, $txn_root, &#39;&#39;, $editor, sub{1}, 1, 1, 0, 0);exit 0;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>lspm  list names and descriptions of Perl modules in a directory (Aristotle)</title>
    <link>http://prlmnks.org/html/561518.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/561518.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl=head1 NAMElspm - list names and descriptions of Perl modules in a directory=head1 SYNOPSIS lspm -h lspm [-p] [-a] [-c [num]] [-l len] [dir [dir dir ...]]=head1 DESCRIPTIONLists all or a subset of installed Perl modules, with version numbers and descriptions.It will look in Perl&#39;s default search path for modules, C&lt;@INC&gt;, if you don&#39;t explicitly list any directories to walk. Note that this default search excludes the current directory.=head1 OPTIONS=over 4=item B&lt;-h&gt;, B&lt;--help&gt;See a synopsis.=item B&lt;--man&gt;Browse the manpage.=item B&lt;-p&gt;, B&lt;--show-path&gt;Include path of found modules in output.=item B&lt;-a&gt;, B&lt;--align&gt;Vertically align descriptions.=item B&lt;-c&gt;, B&lt;--align-local&gt;, B&lt;--align-cont&gt;Align descriptions in blocks where the module names don&#39;t differ too much in length, to avoid pushing all descriptions way over to the right just because a few names are long. The output looks more ragged than with full alignment, but is still lined up locally and only requires the eye to cross small gaps between columns, so is usually more readable.You can pass an optional positive integer argument to specify the length threshold; the default is 7.=item B&lt;-l&gt;, B&lt;--max-length&gt;, B&lt;--limit&gt;Cut off descriptions at specified length.=back=head1 SEE ALSOL&lt;http://www.cpan.org/modules/by-authors/id/TOMC/scripts/pmdesc.gz&gt;=head1 BUGSI need something to write here.=head1 COPYRIGHT AND LICENCEWritten by Aristotle Pagaltzis, (c)2006.This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.=cutuse 5.6.1;use strict;use warnings;use List::Util qw( min max );use File::Find qw( find );use File::Spec::Functions qw( rel2abs abs2rel no_upwards );use ExtUtils::MakeMaker ();use Getopt::Long 2.24, qw( :config bundling no_ignore_case no_auto_abbrev );use Pod::Usage qw( pod2usage );$|++;sub module_name_from_filename {local $_ = shift;s! \.p(?:m|od) \z!!x;s!/!::!g;return $_;}sub get_module_description {my ( $file, $max_length ) = @_;my $desc;open my $pod, &quot;&lt;&quot;, $fileor ( warn( &quot;\tCannot open $file: $!&quot; ), return );my $get_line = sub {$_ = &lt;$pod&gt;;defined and s/\x0D?\x0A/\n/g; # fix DOS crud; see perlport$_;};local $_;# find descriptionwhile ( $get_line-&gt;() ) {last if m{\A=head\d\s+NAME\b};}# skip leading junkwhile ( $get_line-&gt;() ) {last if /\A=\w/;if( s{\A.*? - \s*}{} ) {$desc .= $_;last;}}# collect descriptionwhile ( $get_line-&gt;() ) {last if /\A=\w/;s/\A\s+\z//;$desc .= $_;last if not length;}for( $desc ) {last if not defined;s/\s*\z//;s/\s+/ /g;$_ = substr $_, 0, $max_length if $max_length;undef $_ if not length;}return $desc;}sub get_module_version {my ( $file ) = @_;local $_ = MM-&gt;parse_version( $file );$_ = eval if $_ and /[^\d._]/;return $_;}{my %visited;sub visited {my ( $dir ) = @_;my $unique_id;if( $^O eq &quot;MSWin32&quot; ) {$unique_id = $dir;}else {my ( $dev, $inode ) = stat $dir or return;$unique_id = join &#39;:&#39;, $dev, $inode;}return ! ! $visited{ $unique_id }++;}}sub name_width {my ( $module, $version ) = @_;length( $module . ( defined $version ? $version : &#39;&#39; ) );}sub print_module_info {my ( $module, $version, $desc, $path, $name_width ) = @_;my @output;push @output, do {local $_ = $version;$_ = &#39;&#39; if not defined;my $name = &quot;$module ($_)&quot;;$name = sprintf &#39;%-*s&#39;, $name_width + 3, $name if defined( $desc and $name_width );$name;};push @output, &quot;[$path]&quot; if defined $path;push @output, &#39;-&#39;, $desc if defined $desc;print &quot;@output\n&quot;;}GetOptions(&#39;h|help&#39;                     =&gt; sub { pod2usage( -verbose =&gt; 1 ) },&#39;man&#39;                        =&gt; sub { pod2usage( -verbose =&gt; 2 ) },&#39;show-path|p!&#39;               =&gt; \( my $opt_path = &#39;&#39; ),&#39;align|a&#39;                    =&gt; \( my $opt_align = 0 ),&#39;align-local|align-cont|c:7&#39; =&gt; \( my $opt_cont ),&#39;max-length|limit|l&#39;         =&gt; \( my $opt_limit = 0 ),) or pod2usage( -verbose =&gt; 1 );pod2usage &#39;argument to --align-local must be a positive integer&#39;if $opt_cont and $opt_cont &lt; 1;@ARGV = no_upwards( @INC ) unless @ARGV;my @info;my $min_w = 100;my $max_w = 0;for my $inc_dir ( sort { length $b &lt;=&gt; length $a } map rel2abs( $_ ), @ARGV ) {find({wanted =&gt; sub {return unless /\.p(?:m|od)\z/;s/\.pod\z/.pm/; # if it&#39;s POD, parse the corresponding codereturn if not -f;my @details = (module_name_from_filename( abs2rel $File::Find::name, $inc_dir ),get_module_version( $_ ),get_module_description( $_, $opt_limit ),$opt_path ? $File::Find::name : undef,);if( $opt_cont ) {my $cur_w = name_width @details;$max_w = max $max_w, $cur_w;$min_w = min $min_w, $cur_w;if( $max_w - $min_w &gt; $opt_cont ) {print_module_info @$_, $max_w for @info;@info = ();$min_w = $max_w;$max_w = 0;}}if( $opt_align or $opt_cont ) {push @info, \@details;}else {print_module_info @details;}},preprocess =&gt; sub { visited( $File::Find::dir ) ? () : @_ },},$inc_dir,);}if( @info ) {my $name_width = max map name_width( @$_ ), @info;print_module_info @$_, $name_width for @info;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>A complete perl roguelike (dabreegster)</title>
    <link>http://prlmnks.org/html/561379.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/561379.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;// None, the game is at http://assilem.org/breegrl/trunk/emotionrl.tgz&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>ReorgXSD.pl (dsilvia)</title>
    <link>http://prlmnks.org/html/560368.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/560368.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!perluse strict;#use warnings;use File::Spec::Functions &#39;:ALL&#39;;sub escapeSpecial($){my $str=shift(@_);return(quotemeta($str));}sub getEntityType($){my $wholeStr=shift(@_);if(!$wholeStr || $wholeStr=~m{^\s*$}){return(&#39;&#39;,&#39;&#39;);}my $comparator=&#39;(\s*?&lt;(\b\w+?\b:?\b\w+?\b).*?(?:\bname\b.*?=.*?(?:\&quot;|\&#39;)\b\w*?\b(?:\&quot;|\&#39;))?.*?&gt;)&#39;;if(!($wholeStr=~m{$comparator}s)){return(&#39;&#39;,&#39;&#39;);}return($1,$2);}sub getEntry($){my $wholeStr=shift(@_);my $entityType=getEntityType($wholeStr);my $entry;my $comparator;my $tail;if(!$entityType){return($wholeStr,&#39;&#39;,&#39;&#39;,&#39;&#39;,&#39;&#39;);}($entry,$entityType)=getEntityType($wholeStr);$tail=substr($entry,length($entry)-2,2);if($tail eq &#39;/&gt;&#39;){return getSimpleEntry($wholeStr,$entityType,$entry);}else{return getComplexEntry($wholeStr,$entityType,$entry);}}sub getComplexEntry($$$){my $wholeStr=shift(@_);my $entityType=shift(@_);my $anyTag=&#39;.*?&lt;/?(?:[a-z_][a-z0-9.:_-]*?).*?&gt;&#39;;my $closeTag=&#39;&lt;/(?:xs:|.).*?&gt;&#39;;my $comparator;my $entityName;my $entityDefinition;my $resultStr;my $beginMatch;my $matchLen;my $chunk;my $theHead;my $theTail;my $matches=0;$comparator=$anyTag;if($entityType =~ m{(?:xs.*?|.*?)?:?import}){$wholeStr=~m{($comparator)}sg;$entityDefinition=$1;$matchLen=pos($wholeStr);$beginMatch=0;if($wholeStr=~m{(?=$entityDefinition).}sg){$beginMatch=pos($wholeStr)-1;}$resultStr=substr($wholeStr,0,$beginMatch).substr($wholeStr,$matchLen);$comparator=&#39;namespace.*?=.*?(?:\&quot;|\&#39;)(.*?)(?:\&quot;|\&#39;)&#39;;$wholeStr=~m{$comparator}s;$entityName=$1;return($resultStr,$entityDefinition,$entityName,$entityType,&#39;complex&#39;);}$chunk=$wholeStr;$chunk=~m{$anyTag}s;$beginMatch=$-[0];$matchLen=$beginMatch;$comparator=&#39;\bname\b.*?=.*?(?:\&quot;|\&#39;)(\b\w*?\b)(?:\&quot;|\&#39;)&#39;;$chunk=~m{$comparator}s;$entityName=$1;while($chunk=~m{($anyTag)}sg){my $endOfMatch=$+[0];my $tmp=$1;$tmp=~m{&lt;}s;my $tmpBegin=$-[0];$theHead=substr($tmp,$tmpBegin,2);$theTail=substr($tmp,length($tmp)-2);if($theHead ne &#39;&lt;/&#39;){if($theHead=~m{&lt;.} and $theTail ne &#39;/&gt;&#39;){$matches++};}else{$matches--};if(!$matches){$closeTag=&#39;&lt;/&#39;.$entityType.&#39;.*?&gt;&#39;;$chunk=~m{$closeTag}s;$matchLen+=$+[0];last;}$matchLen+=$endOfMatch;$chunk=substr($chunk,$endOfMatch);}$entityDefinition=substr($wholeStr,$beginMatch,$matchLen);$resultStr=substr($wholeStr,0,$beginMatch).substr($wholeStr,$beginMatch+$matchLen);return($resultStr,$entityDefinition,$entityName,$entityType,&#39;complex&#39;);}sub getSimpleEntry($$$){my $wholeStr=shift(@_);my $entityType=shift(@_);my $entityDefinition;my $comparator;my $entityName;my $resultStr;my $beginMatch;my $endMatch;$comparator=&#39;\s*?&lt;&#39;.$entityType.&#39;.*?(?:\bname\b.*?=.*?(?:\&quot;|\&#39;)(\b\w*?\b)(?:\&quot;|\&#39;))?.*?/&gt;&#39;;if($wholeStr=~m{($comparator)}sg){$entityDefinition=$1;$beginMatch=$-[0];$endMatch=$+[0];$comparator=&#39;\bname\b.*?=.*?(?:\&quot;|\&#39;)(\b\w*?\b)(?:\&quot;|\&#39;)&#39;;if($wholeStr=~m{$comparator}s){$entityName=$1;}$resultStr=substr($wholeStr,0,$beginMatch).substr($wholeStr,$endMatch);return($resultStr,$entityDefinition,$entityName,$entityType,&#39;simple&#39;);}return($wholeStr,&#39;&#39;,&#39;&#39;,&#39;&#39;,&#39;&#39;);}my @myArgs=@ARGV;if(!$myArgs[0]){my @myPath=splitpath(__FILE__);my $myName=$myPath[2];print &quot;\nUsage: &quot;.$myName.&quot; file(s)\n\n&quot;;print &quot;Reorganizes xsd files to be more human readable.  Puts any header information\n&quot;;print &quot;first, then tries to determine a root entity and places it next.  Should more\n&quot;;print &quot;than one entity be a possible root entity, all are listed, and if none are\n&quot;;print &quot;found, a comment to that effect is entered.  Next, any remaining complex\n&quot;;print &quot;elements, then simple elements, then complex entities, and simple entities.\n&quot;;print &quot;Last whatever is left (if any!;)\n\n&quot;;print &quot;The only requirement is a well-formed file.  Qualification for a root entity\n&quot;;print &quot;is that it not be referenced by any other entity.\n\n&quot;;print &quot;Results of the process are placed in a like named file with the prefix of\n&quot;;print &quot;&#39;ReorgXSD.\n\n&quot;;print &quot;Shortcomings:\n&quot;;print &quot;\tDoes not analyze DTD entries to determine proper settings for\n&quot;;print &quot;\ttype/attribute/ref, specifically, prefixes.  It merely assumes that\n&quot;;print &quot;\tany prefix ending in a colon (:) is valid an has been provided for.\n\n&quot;;print &quot;\tCannot distinguish between relevance of entities if they are named\n&quot;;print &quot;\talike.\n\n&quot;;print &quot;\tComments are not preserved as they cannot be meaningfully\n&quot;;print &quot;\tinterpolated.  There is no way to tell if a comment goes with a\n&quot;;print &quot;\tspecific entity or group of entities or the whole file!:-(\n\n&quot;;print &quot;\tThe concept of non-reference indicating a root element can be\n&quot;;print &quot;\tnaive in the case of very complicated xsd files with imports and\n&quot;;print &quot;\tother outside references.\n\n&quot;;exit 0;}while(@myArgs){my $inFileName=$myArgs[0];my @pathMembers=splitpath($inFileName);my $outFileName=$pathMembers[0].$pathMembers[1].&quot;ReorgXSD.&quot;.$pathMembers[2];my ($initFile,$fileHdr,$fileFtr);{local $/=undef;open(INITFILE,&quot;&lt; $inFileName&quot;) or die &quot;Could not open initialization file &#39;&quot;.$inFileName.&quot;&#39;: $!\n&quot;;$initFile=&lt;INITFILE&gt;;close(INITFILE);}my $comparator;# normalize the parsing input:#remove comments (cannot meaningfully interpolate these)#  remove the &lt;?xml... and &lt;xs:schema... header#  remove the &lt;/xs:schema... footer#reduce newlines to single occurrences.$comparator=&#39;(^(?:&lt;\?xml.*?&gt;)*.*?&lt;(?:xs.*?|.*:)schema\b.+?&gt;)&#39;;$initFile=~m{$comparator}s;$fileHdr=$1;$initFile=$&#39;;$comparator=&#39;(^&lt;/(?:xs.?|.*):?\bschema\b.*?&gt;)&#39;;$initFile=~m{$comparator}ms;$fileFtr=$1;$initFile=$`;$comparator=&#39;\s*?&lt;!--.*?--&gt;&#39;;$initFile=~s/$comparator//sg;$comparator=&#39;(\r\n|[\r\n]){2,}&#39;;$initFile=~s/$comparator/$1/g;my @AllEntities;my @AllElements;my %UnReferenced;my %ComplexElements;my %SimpleElements;my @xsImports;my %ComplexEntities;my %SimpleEntities;my $fileIterator=$initFile;my $elmDef;my $elmName;my $elmType;my $tagType;($fileIterator,$elmDef,$elmName,$elmType,$tagType)=getEntry($fileIterator);while($elmDef){if($tagType eq &#39;complex&#39;){if($elmType =~ m{(?:xs.*?|.*?):?element}){%ComplexElements=(%ComplexElements,$elmName=&gt;$elmDef);@AllEntities=(@AllEntities,$elmName);@AllElements=(@AllElements,$elmName);}elsif($elmType =~ m{(?:xs.*?|.*?):?import}){@xsImports=(@xsImports,$elmDef);}elsif($elmName){%ComplexEntities=(%ComplexEntities,$elmName=&gt;$elmDef);@AllEntities=(@AllEntities,$elmName);}}else{if($elmType =~ m{(?:xs.*?|.*?):?element}){%SimpleElements=(%SimpleElements,$elmName=&gt;$elmDef);@AllEntities=(@AllEntities,$elmName);@AllElements=(@AllElements,$elmName);}elsif($elmType =~ m{(?:xs.*?|.*?):?import}){@xsImports=(@xsImports,$elmDef);}elsif($elmName){%SimpleEntities=(%SimpleEntities,$elmName=&gt;$elmDef);@AllEntities=(@AllEntities,$elmName);}}($fileIterator,$elmDef,$elmName,$elmType,$tagType)=getEntry($fileIterator);}my $rootName=&#39;&#39;;my @rootDefn;foreach my $entity (sort @AllEntities){my $refd=0;foreach my $key (sort @AllElements){next if $key eq $entity;if(($ComplexEntities{$key}=~m{((?:\b\w+\b)(?&lt;!name)\s*?=\s*?(?:\&quot;|\&#39;)(?:\w+?:)?\b$entity\b(?:\&quot;|\&#39;))}) ||($ComplexElements{$key}=~m{((?:\b\w+\b)(?&lt;!name)\s*?=\s*?(?:\&quot;|\&#39;)(?:\w+?:)?\b$entity\b(?:\&quot;|\&#39;))}) ||($SimpleEntities{$key}=~m{((?:\b\w+\b)(?&lt;!name)\s*?=\s*?(?:\&quot;|\&#39;)(?:\w+?:)?\b$entity\b(?:\&quot;|\&#39;))}) ||($SimpleElements{$key}=~m{((?:\b\w+\b)(?&lt;!name)\s*?=\s*?(?:\&quot;|\&#39;)(?:\w+?:)?\b$entity\b(?:\&quot;|\&#39;))})){$refd=1;last;}}if(!$refd){%UnReferenced=(%UnReferenced,$entity=&gt;1);}}foreach my $key (sort @AllElements){if($UnReferenced{$key}){if($ComplexElements{$key}){@rootDefn=(@rootDefn,$ComplexElements{$key});delete $ComplexElements{$key};}elsif($SimpleElements{$key}){@rootDefn=(@rootDefn,$SimpleElements{$key});delete $SimpleElements{$key};}elsif($ComplexEntities{$key}){@rootDefn=(@rootDefn,$ComplexEntities{$key});delete $ComplexEntities{$key};}elsif($SimpleEntities{$key}){@rootDefn=(@rootDefn,$SimpleEntities{$key});delete $SimpleEntities{$key};}}}open(OUTFILE,&quot;&gt; $outFileName&quot;) or die &quot;Could not open output file $!\n&quot;;print OUTFILE $fileHdr.&quot;\n&quot;;if(@xsImports){print OUTFILE &quot;\n&lt;!-- imports (ReorgXSD) --&gt;\n&quot;;foreach my $entity (@xsImports){print OUTFILE $entity.&quot;\n&quot;;}}if(@rootDefn &amp;&amp; @rootDefn == 1){print OUTFILE &quot;\n&lt;!-- Root Element (ReorgXSD) --&gt;\n&quot;;print OUTFILE $rootDefn[0].&quot;\n&quot;;}elsif(@rootDefn){my $numRoots=@rootDefn;print OUTFILE &quot;\n&lt;!-- No Root Element Found ($numRoots possible) (ReorgXSD) --&gt;\n&quot;;foreach my $defn (@rootDefn){print OUTFILE $defn.&quot;\n&quot;;}}else{print OUTFILE &quot;\n&lt;!-- No Root Element Found (ReorgXSD) --&gt;\n&quot;;}if(%ComplexElements){print OUTFILE &quot;\n&lt;!-- Complex elements (ReorgXSD) --&gt;\n&quot;;foreach my $key (sort keys %ComplexElements){print OUTFILE $ComplexElements{$key}.&quot;\n&quot;;}}if(%SimpleElements){print OUTFILE &quot;\n&lt;!-- Simple elements (ReorgXSD) --&gt;\n&quot;;foreach my $key (sort keys %SimpleElements){print OUTFILE $SimpleElements{$key}.&quot;\n&quot;;}}if(%ComplexEntities){print OUTFILE &quot;\n&lt;!-- other named complex entities (ReorgXSD) --&gt;\n&quot;;foreach my $key (sort keys %ComplexEntities){print OUTFILE $ComplexEntities{$key}.&quot;\n&quot;;}}if(%SimpleEntities){print OUTFILE &quot;\n&lt;!-- other named simple entities (ReorgXSD) --&gt;\n&quot;;foreach my $key (sort keys %SimpleEntities){print OUTFILE $SimpleEntities{$key}.&quot;\n&quot;;}}if($fileIterator and $fileIterator !~ m{^\s*$}){print OUTFILE &quot;\n&lt;!-- misc entities (ReorgXSD) --&gt;\n&quot;;print OUTFILE $fileIterator;}print OUTFILE &quot;\n&quot;;print OUTFILE $fileFtr;print OUTFILE &quot;\n&quot;;close(OUTFILE);print &quot;Results are in file &#39;&quot;.$outFileName.&quot;&#39;\n&quot;;shift(@myArgs);}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Win32 iTunes Alarm Clock (Ole!) (Adam)</title>
    <link>http://prlmnks.org/html/559699.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/559699.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!perluse strict;use Time::Local;use Warnings;use Win32;use Win32::OLE;my $start = shift || -1;  # Use -1 for immediate start.my $playlist = shift;my $fadeup = 1;if ( not defined $playlist ){    if ( $start !~ m/^\s*-?\d+\s*$/ )    {        $playlist = $start;        $start = -1;        $fadeup = 0;    }    else    {        $playlist = &quot;Party Shuffle&quot;;    }}if ( $start != &quot;-1&quot; ) # Determine when to proceed, then wait until then.{    my ( $sH, $sM ) = $start =~ m/^\s*(\d\d?)(\d\d)\s*$/;    die &quot;$0 &#39;$start&#39;\nTime should be in military time with no symbols, e.g.:\n6:30 am = 630, 10:15 pm = 2215\n&quot;         unless defined( $sH ) and defined( $sM );    my $t = time();    my @p = localtime($t); # ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)    my ( $tM, $tH ) = ( $p[1], $p[2] );    my $s = 0;    my $today = 0;    if ( $sH &lt; $tH || ( $sH == $tH &amp;&amp; $sM &lt;= $tM ) )    {        my @sP = localtime($t + 86400);        $s = timelocal( 0, $sM, $sH, $sP[3], $sP[4], $sP[5] );    }    elsif ( $sH &gt; $tH || ( $sH == $tH &amp;&amp; $sM &gt; $tM ) )    {        $s = timelocal( 0, $sM, $sH, $p[3], $p[4], $p[5] );        $today = 1;    }    else    { die &quot;ASSERT( &#39;$sH&#39;, &#39;$tH&#39; )&quot; }    print &quot;Set for &quot;, ( $today ? &quot;today, &quot; : &quot;tomorrow, &quot; ), scalar( localtime( $s ) ), &quot;\n&quot;;    sleep( ( $s - $t ) - 59 ) if ( ( $s - $t ) &gt; 59 );    print &quot;Ready? One Minute to Go!\n&quot;;    sleep( 15 ) while time() &lt; $s;}else{    # no delay? then no fade either.    $fadeup = 0;}print &quot;Starting iTunes . . .\n&quot;;my $G_iTA = new Win32::OLE(&quot;iTunes.Application&quot;);$G_iTA-&gt;{ &quot;BrowserWindow&quot; }-&gt;{ &quot;MiniPlayer&quot; } = 1;$G_iTA-&gt;{ &quot;SoundVolume&quot; } = $fadeup ? 10 : 90;print &quot;Playing...\n&quot;;$G_iTA-&gt;{ &quot;LibrarySource&quot; }-&gt;{ &quot;Playlists&quot; }-&gt;ItemByName( $playlist )-&gt;PlayFirstTrack();if ( $fadeup ){    print &quot;Fading up...\n&quot;;    for my $v ( 11 .. 90 )    {        sleep( 1 );        $G_iTA-&gt;{ &quot;SoundVolume&quot; } = $v;    }        print &quot;Have a nice day!\n\n&quot;;}else{    print &quot;iTunes load complete.\n\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>SSH Failed Attempt Monitor (Anonymous Monk)</title>
    <link>http://prlmnks.org/html/559466.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/559466.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl# This script watches the /var/log/secure for failed ssh attempts.  When found, it will add a reject route to your routing table, making it impossible for your machine to communicate with that host again.## Written By: Matt Joubert (matt __at__ uucp _dot_ ca)# Date: June 2, 2006#use strict;use warnings;use Sys::Syslog;# define ssh log file locationmy $logFile = &#39;/var/log/secure&#39;;# syslog facilitymy $syslogFac = &#39;local0&#39;;# syslog levelmy $syslogLevel = &#39;info&#39;;# SAFE IPS, NEVER BLOCK  (I sometimes forget a password..)my @safe = qw/ 192.168.0.1 /;# define threshold in minutes to reset the failed attempt counter# note, this shouldn&#39;t be nuts because if set to high, you could shoot yourself in the footmy $thresHold   = 10;    # minutesmy $maxAttempts = 5;##### Probably wont need to change anything below #####use File::Tail;use Time::ParseDate;$thresHold *= 60;        # convert to seconds;my $fh = File::Tail-&gt;new(  name        =&gt; $logFile,  maxinterval =&gt; 10,  interval    =&gt; 10,  adjustafter =&gt; 5) || die (&quot;could not open log file: $!&quot;);# at this point, the file is open.. so the rest should be able to work fine in fork.defined(my $pid = fork)   or die &quot;Can&#39;t fork: $!&quot;;exit if $pid;my %db;my @rejects;while ( my $line = $fh-&gt;read ) {    # ignore all lines except for the failed ones    next unless $line =~ /Failed password/ig;    my @column = split ( /\s+/, $line );    # grab the IP address    $line =~ m/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/g;    my $ip = $1;    next unless $ip;    next if safe( $ip, @safe );    my ( $mon, $day, $time ) = (@column)[ 0, 1, 2 ];    my $epoch = parsedate(&quot;$mon $day $time&quot;);    if ( !defined( $db{$ip} ) ) {        push ( @{ $db{$ip} }, $epoch );    }    else {        push ( @{ $db{$ip} }, $epoch );        # past threshold.. start over from scratch        if ( $db{$ip}[ $#{ $db{$ip} } ] - $db{$ip}[ $#{ $db{$ip} } - 1 ] &gt; $thresHold ) {            undef( $db{$ip} );            push ( @{ $db{$ip} }, $epoch );        }        else {    # threshold is good - check for attempts            if ( scalar @{ $db{$ip} } &gt; $maxAttempts ) {                if ( !isRejected( $ip, @rejects ) ) {                    push ( @rejects, $ip );                    syslog(&quot;$syslogLevel|$syslogFac&quot;, &quot;Adding $ip to reject route table for too many failed attempts&quot;);                    system(&quot;/sbin/route add -host $ip reject&quot;);                }            }        }    }}# check if ip is &quot;safe&quot; from being blockedsub safe {    my $ip   = shift;    my @safe = @_;    foreach (@safe) {        return 1 if $ip eq $_;    }    return 0;}# check if ip has alread been recently reacted toosub isRejected {    my $ip      = shift;    my @rejects = @_;    foreach (@rejects) {        return 1 if $ip eq $_;    }    return 0;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>JavaScript::XRay + HTTP::Proxy equals Crazy Delicious (diotalevi)</title>
    <link>http://prlmnks.org/html/559405.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/559405.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;=head1 NAMEjsxray-proxy - A JavaScript::XRay proxy=head1 SYNOPSIS jsxray [options]  Options:   -port   -switches   -no-xray   -help   -man=head1 DESCRIPTIONStraps L&lt;HTTP::Proxy&gt; onto L&lt;JavaScript::XRay&gt; so I can useJavaScript::XRay really easily and on arbitrary web sites.=over=item -port ...Specifies a port to listen on. The default is 8080.=item -switchesSpecifies switches to use for JavaScript::XRay. Prefix your switch with no- to pass it as a turned off switch.=item -no-xrayDoesn&#39;t install JavaScript::XRay. It&#39;s just a simple proxy now.=item -helpDisplays the program&#39;s options.=item -manDisplays the entire manual.=back=cutuse Getopt::Long &#39;GetOptions&#39;;use autouse &#39;Pod::Usage&#39;, &#39;pod2usage&#39;;GetOptions(    help         =&gt; \&amp;help,    man          =&gt; \&amp;man,    &#39;port=i&#39;     =&gt; \( my ($port) = 8080 ),    &#39;switches=s&#39; =&gt; \( my ($switches) = &#39;all&#39; ),    &#39;no-xray&#39;    =&gt; \my ($no_xray)    )    or pod2usage( -verbose =&gt; 0 );sub help { pod2usage( -verbose =&gt; 1 ) }sub man  { pod2usage( -verbose =&gt; 2 ) }require HTTP::Proxy;my $proxy = HTTP::Proxy-&gt;new( port =&gt; $port );if ( not $no_xray ) {    require HTTP::Proxy::BodyFilter::simple;    require JavaScript::XRay;    my %switches = map { /^no-(.+)/ ? ( $1 =&gt; 0 ) : ( $_ =&gt; 1 ) }        $switches =~ /((?:no-)?[a-z]+)/g;    my $filter = HTTP::Proxy::BodyFilter::simple-&gt;new(        sub {            return unless $_[2]-&gt;header(&#39;content-type&#39;) =~ /text/;            my $uri  = $_[2]-&gt;request-&gt;uri;            my $xray = JavaScript::XRay-&gt;new(                abs_uri  =&gt; $uri,                switches =&gt; \%switches            );            ${ $_[1] } = $xray-&gt;filter( ${ $_[1] } );        }    );    $proxy-&gt;push_filter( response =&gt; $filter );}$proxy-&gt;start;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>ypne (LordScinawa)</title>
    <link>http://prlmnks.org/html/559066.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/559066.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#/usr/bin/perluse warnings; use strict;use File::Copy;#enter here the path of your nmap!my $pathofnmap = &quot;C:/Programmi/nmap-4.03&quot;;#don&#39;t change :)my $mi = (localtime)[1];#set in minute the gap between every scanmy $gap=1;#don&#39;t change :)my $mid; increm();##################################################print &quot;Your personal namp executor\n&quot;;print &quot;\n&quot;;print &quot;                 LordScinawa    ;)\n&quot;;##################################################sub increm { $mid = ($mi + $gap) % 60; }sub meinz{while(1){sleep 1;$mi = (localtime)[1];if ($mi &gt;= $mid) {print&quot;$mi, $mid\n&quot;;increm();esegui();  }}}sub esegui {chdir &quot;$pathofnmap&quot;;if (open(NMAP, &quot;nmap.exe -sS -P0 -S 127.0.0.1 -f -vv -O 80.104.113.95 |&quot;)){    chdir &quot;C:/Documents and Settings/Wxp/Documenti/pubz&quot;;if (open CAC, &quot;+&gt;&quot;, &quot;cache.html&quot;) {print&quot;opened cache\n&quot;;while (&lt;NMAP&gt;) {print&quot;nmap!!\n&quot;;if (/\n/) {print (CAC &quot;$_&lt;br&gt;\n&quot;);} else {die &quot;omfg&quot;;} }close CAC; my $filetobecopied = &quot;cache.html.&quot;;my $newfile = &quot;nmapresult.html.&quot;;copy($filetobecopied, $newfile) or die &quot;File cannot be copied.&quot;;print&quot;copiati\n&quot;; } else { die &quot;Impossibile aprire/creare il file di cache $! \n&quot;};close NMAP;} else {die &quot;Impossibile aprire Nmap $!\n&quot;}}meinz();&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>FSInfo (bpoag)</title>
    <link>http://prlmnks.org/html/558398.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558398.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl## FSInfo v0.1 written 061306:1135 by BJP## FSInfo will dump useful information about LVM structure of a given filesystem.## Usage: fsinfo &lt;mountpoint&gt;# Example: fsinfo /tmp#main();sub usage(){  print &quot;\n   Usage: fsinfo &lt;mountpoint&gt;\n&quot;;  print &quot; Example: fsinfo /tmp\n\n&quot;;  exit();}sub sanityCheck(){  if($#ARGV&lt;0 || $#ARGV&gt;0) ## Hee haw!   {    usage();  }  else  {    $targetFS=$ARGV[0];  }  ## OS level check..  @unameDump=split(/\s+/,`uname -a`);  if ($unameDump[3]&lt;5)  {    print &quot;fsinfo only works in AIX 5L or later.\n&quot;;    usage();  }  ## Check to see if the filesystem actually exists...  @dfContents=split(/\s+/,`df -m | grep &quot; $targetFS\$&quot;`);  if(length($targetFS)==length($dfContents[6]))  {    print &quot;\nFSInfo: Starting up..\nFSInfo:\n&quot;;  }  else  {    print &quot;\nFSInfo: Ack! Can&#39;t find the filesystem you specified ($targetFS)..!  Exiting.\n\n&quot;;    exit();  }}sub main(){  sanityCheck();  ## So far so good. Pull up the VG info for this filesystem..  $dfContents[0]=~/\/dev\//;  $targetLV=$&#39;;  @lslvContents=split(/\s+/,`lslv $targetLV|head -n1` );  $targetVG=$lslvContents[5];  print &quot;FSInfo: Filesystem \&quot;$targetFS\&quot; belongs to logical volume $targetLV which sits inside $targetVG. Details shown below.\n&quot;;  @vgdump=`lsvg -L $targetVG`;  @lvdump=`lslv -L $targetLV`;  ## Dump it all out...  print &quot;FSInfo:\nFSInfo: Volume Group information for $targetFS..\n&quot;;  print &quot;FSInfo:\n&quot;;  foreach $line (@vgdump)  {    print &quot;FSInfo: $line&quot;;  }  print &quot;FSInfo:\nFSInfo: Logical Volume information for $targetFS..\n&quot;;  print &quot;FSInfo:\n&quot;;  foreach $line (@lvdump)  {    print &quot;FSInfo: $line&quot;;  }  print &quot;FSInfo:\nFSInfo: Spinning down..\n\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>LSVPMembers (bpoag)</title>
    <link>http://prlmnks.org/html/558393.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558393.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl#### LSVPMembers written 062606:1051 by BJP#### LSVPMembers displays what hdisks belong to which vpaths on a given host.##@vpList = `lsdev -Cc disk | grep ^vp | cut -d&quot; &quot; -f1`;print &quot;\nLSVPMembers: Spinning up..\n&quot;;foreach $item (@vpList){  $counter=0;  chomp($item);  chomp($LUN=`lsattr -El $item | grep disk | head -n1 | cut -d\/ -f2`);  $lunID=substr($LUN,0,3).&quot;-&quot;.substr($LUN,3)  ;      print &quot;LSVPMembers: \&quot;$item\&quot; ($lunID) encompasses &quot;;  @vpMembers=split(/\s+/,`lsattr -El $item | cut -d&quot; &quot; -f2-3 | cut -c2- | grep disk | cut -d\/ -f1`);    foreach $vp (@vpMembers)  {    print &quot;$vp&quot;;    $counter++;      if ($counter&lt;@vpMembers)    {      print &quot;, &quot;;    }    else    {      print &quot;.&quot;;    }        if ($counter+1==@vpMembers)    {      print &quot;and &quot;;    }  }  print &quot;\n&quot;;}print &quot;LSVPMembers: Spinning down..\n\n&quot;;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>LSVGMembers (bpoag)</title>
    <link>http://prlmnks.org/html/558387.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558387.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl#### LSVGMembers written 062606:1051 by BJP#### LSVGMembers displays what logical volumes belong to each volume group on a system.##@vgList = `lsvg`;print &quot;\nLSVGMembers: Spinning up..\n&quot;;foreach $item (@vgList){  $counter=0;  chomp($item);  print &quot;LSVGMembers: \&quot;$item\&quot; encompasses &quot;;  @vgMembers=split(/\s+/,`lsvg -l $item | grep -v POINT\$ | grep -v $item: | cut -d&quot; &quot; -f1`);  foreach $lv (@vgMembers)  {    print &quot;$lv&quot;;     $counter++;      if ($counter&lt;@vgMembers)    {      print &quot;, &quot;;    }    else    {      print &quot;.&quot;;    }    if ($counter+1==@vgMembers)    {      print &quot;and &quot;;    }  }  print &quot;\n&quot;;}print &quot;LSVGMembers: Spinning down..\n\n&quot;;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>LSLVMembers (bpoag)</title>
    <link>http://prlmnks.org/html/558385.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558385.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl#### LSLVMembers written 062306:1606 by BJP#### LSLVMembers displays what member hdisks belong to each logical volume.##@lvList = split(/\s+/,`lsvg -o | lsvg -i -l | grep -v : | grep -v ^LV| cut -d\&quot; \&quot; -f1`);print &quot;\nLSLVMembers: Spinning up..\n&quot;;foreach $item (@lvList){  print &quot;LSLVMembers: \&quot;$item\&quot; encompasses &quot;;  @lvResults=split(/\s+/,`lslv -l $item`);  $counter=0;  $moreComing=0;  $totalSize=@lvResults;  while ($counter&lt;=@lvResults)  {    if (($lvResults[$counter]=~/hdisk/  || $lvResults[$counter]=~/vpath/) &amp;&amp; $counter&lt;$totalSize-5)    {      print &quot;$lvResults[$counter], &quot;;      $moreComing++;    }    if (($lvResults[$counter]=~/hdisk/ || $lvResults[$counter]=~/vpath/) &amp;&amp; $counter&gt;($totalSize-5))    {      if ($moreComing&gt;0)      {        print &quot;and &quot;;      }      print &quot;$lvResults[$counter]. &quot;;    }    $counter++;  }  print &quot;\n&quot;;}print &quot;LSLVMembers: Spinning down..\n\n&quot;;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>CeilingReport (bpoag)</title>
    <link>http://prlmnks.org/html/558382.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558382.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl### ceilingreport.pl written 022806:1022 by BJP###### This script examines how many free PPs remain in each volume group.@vgs=`lsvg -L`;$hostName=`hostname`;chomp($hostName);foreach $i (@vgs){        chomp($i);        $numFree=`lsvg -L $i| grep FREE`;        $numFree=~/PPs:/;        $numFree=$&#39;;        chomp($numFree);        $numFree=~s/^\s+//g;        print &quot;CeilingReport (on $hostName): $i has $numFree PPs remaining.\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Exchange to Postfix firewall Configuration (madbombX)</title>
    <link>http://prlmnks.org/html/558351.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558351.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -wuse strict;use Benchmark;use Config::ApacheFormat;use Fcntl qw(:flock);use Getopt::Std qw(getopts);use Log::Log4perl qw(get_logger :levels);use Net::hostent;use Net::LDAP;use Net::LDAP::Control::Paged;use Net::LDAP::Constant ( &quot;LDAP_CONTROL_PAGED&quot; );use Parallel::ForkManager;use POSIX qw(strftime);use Socket;use vars qw(  %opt  @Server @addresses @ldap_args @mynetworks @_t  $LOG $_appender $_layout $_pm  $HEAD  $config $domains $ldap $relay_domains);sub Bench_Begin();sub Bench_End();sub Create_PID();sub Die_Clean($$);sub GetExchange($);sub GetNitix($);sub Setup_Defaults();sub Setup_ForkManager($);sub Setup_Log();sub Usage();sub Version();sub Write_Networks($);sub Write_Relay_Domains($);sub Write_Relay_Recipients($);sub Write_SenderScores($);sub Write_Transport($);################################################################################# DO NOT EDIT BELOW HERE!!!#   Unless you are hacking up the script :)################################################################################ # Just in case we get through the whole script Bench_Begin(); # Get the options from the command line getopts(&#39;c:hl:s:V&#39;,\%opt); # Parse the options and do Usage/Version when necessary Usage() if $opt{&#39;h&#39;}; Version() if $opt{&#39;V&#39;}; $config = Config::ApacheFormat-&gt;new( expand_vars=&gt;1,hash_directives =&gt;[qw( PostfixBase )],valid_blocks=&gt;[qw( Server )]     ); # Use the new config file if its specified if ($opt{&#39;c&#39;}) { $config-&gt;read($opt{&#39;c&#39;}); } else { $config-&gt;read(&quot;/etc/getcrr.conf&quot;)   or die &quot;Config File: $!&quot;; } Setup_Log(); Create_PID(); Setup_ForkManager($config-&gt;get(&quot;MaxProc&quot;)); Setup_Defaults();# Log completed initialization@Server = $config-&gt;get(&quot;Server&quot;);$LOG-&gt;info(&quot;Loaded &quot;. ($#Server + 1) .&quot; Total Servers&quot;);# Iterate over our Server hashforeach my $sid (@Server) {  my $host = $config-&gt;block($sid);  # Skip it if the record&#39;s ACTIVE boolean is &lt; 1  if ($host-&gt;get(&quot;Active&quot;) &lt; 0) {    $LOG-&gt;info(&quot;Skipping Record: &quot;. join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)) .&quot; - &quot;. $host-&gt;get(&quot;Host&quot;));    next;  } elsif ($host-&gt;get(&quot;Active&quot;) == 1) {    push @mynetworks,      &quot;/^&quot;. inet_ntoa(inet_aton($host-&gt;get(&quot;Host&quot;))) .&quot;\\/32\$/OK\n&quot;;  }   # Fork off the children and get going on the queries  my $pid = $_pm-&gt;start($host) and next;   if ($host-&gt;get(&quot;Type&quot;) =~ /Exchange/) { GetExchange($host); }  elsif ($host-&gt;get(&quot;Type&quot;) =~ /Nitix/) { GetNitix($host); }  else {    $LOG-&gt;error(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: &#39;&quot;. $host-&gt;get(&quot;Type&quot;) .&quot;&#39; is unknown server type.&quot;);    $_pm-&gt;finish;  }  # Closing the forked process  $_pm-&gt;finish;}# Ensure all the child processes finish$_pm-&gt;wait_all_children; # Generate all the Postfix Files Write_Networks($config-&gt;get(&quot;MyNetworks&quot;)); Write_Relay_Domains($config-&gt;get(&quot;RelayDomains&quot;)); Write_Transport($config-&gt;get(&quot;TransportMaps&quot;)); Write_Relay_Recipients($config-&gt;get(&quot;RelayRecipients&quot;)); Write_SenderScores($config-&gt;get(&quot;SenderScoresFile&quot;))   if ($config-&gt;get(&quot;SenderScoresFile&quot;));# We&#39;re done, so remove the PID file.unlink $config-&gt;get(&quot;PIDFile&quot;);$LOG-&gt;debug(&quot;Removed PID file:&quot;. $config-&gt;get(&quot;PIDFile&quot;)); Bench_End();################################################################################# DESCRIPTION:Does the Benchmark open and logs it to the $LOG# PARAMETERS:None# RETURN:Nothing# NOTES:################################################################################sub Bench_Begin(){  $_t[1] = new Benchmark;}################################################################################# DESCRIPTION:Does the Benchmark diff and writes it to $LOG# PARAMETERS:None# RETURN:Nothing# NOTES:################################################################################sub Bench_End(){  $_t[2] = new Benchmark;  $_t[0] = timediff($_t[2], $_t[1]);  $LOG-&gt;info(&quot;$0 took: &quot;. timestr($_t[0]));}################################################################################# DESCRIPTION:Creates the PID file if it doesn&#39;t alreay exist# PARAMETERS:None# RETURN:Nothing# NOTES:Dies if PIDFile exists################################################################################sub Create_PID(){   Die_Clean(&quot;$0 is already running or ended improperly&quot;,            &quot;$0 is already running or ended improperly.\n&quot;.               &quot;Either delete &quot;. $config-&gt;get(&quot;PIDFile&quot;) .&quot;or wait for the process to end.\n&quot;)    if (-e $config-&gt;get(&quot;PIDFile&quot;));  open (PID, &quot;&gt;&quot;.$config-&gt;get(&quot;PIDFile&quot;));  print PID $$;  close (PID);  $LOG-&gt;debug(&quot;Created PID file: &quot;. $config-&gt;get(&quot;PIDFile&quot;));}################################################################################# DESCRIPTION:Removes the PID file and dies with @param text# PARAMETERS:Text of $LOG-&gt;fatal(), Text of die()# RETURN:Nothing# NOTES:################################################################################sub Die_Clean($$){  my ($fatal, $die) = @_;  $LOG-&gt;fatal($fatal);  unlink $config-&gt;get(&quot;PIDFile&quot;);  $LOG-&gt;debug(&quot;Removed PID file: &quot;. $config-&gt;get(&quot;PIDFile&quot;));  Bench_End();  die($die);}################################################################################# DESCRIPTION:Queries Exchange Server for email addresses# PARAMETERS:$host hash# RETURN:Nothing# NOTES:################################################################################sub GetExchange($){  my $host = shift;  # Connecting to Active Directory domain controllers  $LOG-&gt;debug(&quot;Beginning &quot;. join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)));  unless ($ldap = Net::LDAP-&gt;new($host-&gt;get(&quot;IP&quot;))) {    $LOG-&gt;warn($host-&gt;get(&quot;Host&quot;). &quot;: Error connecting to specified domain controllers $@ \n&quot;);    $_pm-&gt;finish;    next;  }  my $mesg = $ldap-&gt;bind ( dn =&gt; $host-&gt;get(&quot;User&quot;),                          password =&gt; $host-&gt;get(&quot;Pass&quot;));  if ( $mesg-&gt;code()) {      $LOG-&gt;warn ($host-&gt;get(&quot;Host&quot;). &quot;:\n&quot;. &quot;error:&quot;, $mesg-&gt;code(),&quot;\n&quot;,&quot;error name: &quot;,$mesg-&gt;error_name(),          &quot;\n&quot;, &quot;error text: &quot;,$mesg-&gt;error_text(),&quot;\n&quot;);      $_pm-&gt;finish;      next;  }  # How many LDAP query results to grab for each paged round  # Set to under 1000 for Active Directory  my $page = Net::LDAP::Control::Paged-&gt;new( size =&gt; 990 );  @ldap_args = (   base     =&gt; $host-&gt;get(&quot;Base&quot;),# Change to grab various objects (Contacts, Public Folders, etc.)# A minimal filter for just users with email would be:# filter =&gt; &quot;(&amp;(sAMAccountName=*)(mail=*))&quot;        filter =&gt; &quot;(&amp; (mailnickname=*) (| (&amp;(objectCategory=person)                      (objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))                      (&amp;(objectCategory=person)(objectClass=user)(|(homeMDB=*)                      (msExchHomeServerName=*)))(&amp;(objectCategory=person)(objectClass=contact))                      (objectCategory=group)(objectCategory=publicFolder) ))&quot;,        control  =&gt; [ $page ],        attrs  =&gt; &quot;proxyAddresses&quot;,  );  my $cookie;  while(1) {    # Perform search    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Performming Search&quot;);    my $mesg = $ldap-&gt;search( @ldap_args );    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Search Completed&quot;);    # Setup filenames and open the files    my $DC_DOMAIN = $config-&gt;get(&quot;Libdir&quot;). &quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_domain&quot;;    my $DC_RECIPIENT = $config-&gt;get(&quot;Libdir&quot;). &quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients&quot;;    my $DC_TRANSPORT = $config-&gt;get(&quot;Libdir&quot;). &quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_transport&quot;;    open DC_DOMAIN, &quot;&gt;$DC_DOMAIN&quot;;    open DC_RECIPIENT, &quot;&gt;$DC_RECIPIENT&quot;;    open DC_TRANSPORT, &quot;&gt;$DC_TRANSPORT&quot;;    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Opened Lib Files&quot;);    # Print the headers for each file    print DC_DOMAIN $HEAD; print DC_RECIPIENT $HEAD; print DC_TRANSPORT $HEAD;    # Filtering results for proxyAddresses attributes      $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Filtering Results&quot;);    foreach my $entry ( $mesg-&gt;entries ) {      my $name = $entry-&gt;get_value( &quot;cn&quot; );      # LDAP Attributes are multi-valued, so we have to print each one.      foreach my $mail ( $entry-&gt;get_value( &quot;proxyAddresses&quot; ) ) {        # Test if the Line starts with one of the following lines:        # proxyAddresses: [smtp|SMTP]:        # and also discard this starting string, so that $mail is only the        # address without any other characters...        if ( $mail =~ s/^(smtp|SMTP)://gs ) {          # Escape &#39;/&#39; in addresses      $mail =~ s/\//\\\//g;  # Split the address into domains to build the relay_domains file  my ($u, $domain) = split (&#39;@&#39;, $mail);  $relay_domains-&gt;{$domain} = $host-&gt;get(&quot;Host&quot;);  # Address the address to the array          print DC_RECIPIENT &quot;/^&quot;. $mail .&quot;\$/OK\n&quot;;         }      }    }    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Wrote out $DC_RECIPIENT&quot;);        # Create the $DC_DOMAIN file    foreach my $dom ( keys %{$relay_domains} ) {      print DC_DOMAIN   &quot;/$dom\$/OK\n&quot;.&quot;/\\.?$dom\$/OK\n&quot;;       print DC_TRANSPORT  &quot;/$dom\$/smtp:[&quot;. $host-&gt;get(&quot;IP&quot;) .&quot;]\n&quot;.        &quot;/\\.?$dom\$/smtp:[&quot;. $host-&gt;get(&quot;IP&quot;) .&quot;]\n&quot;;    }    undef $relay_domains;    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Wrote out $DC_DOMAIN&quot;);    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Wrote out $DC_TRANSPORT&quot;);    close DC_DOMAIN; close DC_RECIPIENT; close DC_TRANSPORT;    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Closed Lib Files&quot;);    # Only continue on LDAP_SUCCESS    $mesg-&gt;code and last;    # Get cookie from paged control    my($resp)  = $mesg-&gt;control( LDAP_CONTROL_PAGED ) or last;    $cookie    = $resp-&gt;cookie or last;    # Set cookie in paged control    $page-&gt;cookie($cookie);    $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Completed&quot;);  }  if ($cookie) {    # We had an abnormal exit, so let the server know we do not want any more    $page-&gt;cookie($cookie);    $page-&gt;size(0);    $ldap-&gt;search( @ldap_args );    $LOG-&gt;warn(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: LDAP query unsuccessful&quot;);    $_pm-&gt;finish;  }  # Completed a server  $LOG-&gt;debug(join(&quot; &quot;,$host-&gt;get(&quot;Company&quot;)). &quot;: Completed&quot;);}################################################################################# DESCRIPTION:Sets up global program defaults# PARAMETERS:None# RETURN:Nothing# NOTES:################################################################################sub Setup_Defaults(){  # Prepare and write the file header  my ($now) = strftime(&quot;%Y-%b-%d %H:%M:%S &quot;, localtime(time));  $HEAD =  &lt;&lt;HEAD;# File automatically generated# DO NOT EDIT BY HAND.  YOUR CHANGES WILL BE LOST.# Last created on: $nowHEAD  # Add the localhost class to @mynetworks  push @mynetworks,&quot;/^127.0.0.0\\/8\$/OK\n&quot;;  return;}################################################################################# DESCRIPTION:Sets up everything for $LOG# PARAMETERS:None# RETURN:Help text to STDOUT# NOTES:################################################################################sub Setup_Log(){ # Setup the logging functionality # Logging Levels: WARN,DEBUG,ERROR,INFO,FATAL $LOG = get_logger(); $LOG-&gt;level($INFO); $LOG-&gt;level($DEBUG) if ($config-&gt;get(&quot;Debug&quot;)); $_appender = Log::Log4perl::Appender-&gt;new(   &quot;Log::Dispatch::File&quot;,   filename =&gt; $config-&gt;get(&quot;LogFile&quot;),   mode   =&gt; &quot;append&quot;, ); # Create the log formatting $_layout = Log::Log4perl::Layout::PatternLayout-&gt;new(   &quot;%d{MMM dd HH:mm:ss} %p&gt; %F{1}[%P]: %L: %m%n&quot;); $LOG-&gt;add_appender($_appender); $_appender-&gt;layout($_layout); return;}################################################################################# DESCRIPTION:Sets up everything for the Parallel Forkmanager# PARAMETERS:None# RETURN:Nothing# NOTES:################################################################################sub Setup_ForkManager($){ # Begin ForkManager my $_max_procs = shift; $_pm = new Parallel::ForkManager($_max_procs);  # Log at process fork $_pm -&gt;run_on_start(   sub { my ($pid, $host) = @_;     $LOG-&gt;debug(&quot;Forking process PID: $pid\n&quot;);   } );  # Log at process copmletion $_pm -&gt;run_on_finish(   sub { my ($pid, $exit_code, $host) = @_;     $LOG-&gt;debug(&quot;Finishing up process PID: $pid\n&quot;);   } );  $_pm-&gt;run_on_wait(   sub {     $LOG-&gt;debug(&quot;Waiting for children to finish&quot;)   },   5.0 ); $LOG-&gt;debug(&quot;ForkManger initialized&quot;); return;} ################################################################################# DESCRIPTION:Prints the Usage Menu to STDOUT# PARAMETERS:None# RETURN:Help text to STDOUT# NOTES:################################################################################sub Usage(){  print &lt;&lt;USAGE;$0 -chV   -cUse this config file (default: /etc/config/getcrr.conf)  -hPrints out this help menu  -VPrints out version informationUSAGEexit(0);}################################################################################# DESCRIPTION:Prints the Version to STDOUT# PARAMETERS:None# RETURN:Version text to STDOUT# NOTES:################################################################################sub Version(){  my $VERSION = do { my @r = (q$Revision: 1.6 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%03d&quot; x $#r, @r };  print &lt;&lt;VERSION;Get Concurrent Relay Recipients v$VERSIONVERSIONexit(0);}################################################################################# DESCRIPTION:Write the NETWORKS file# PARAMETERS:Location of MyNetworks map# RETURN:Nothing# NOTES:################################################################################sub Write_Networks($){  my $NETWORKS = shift;  open NETWORKS, &quot;&gt;$NETWORKS&quot; or    Die_Clean(&quot;Error Opening $NETWORKS: $!&quot;, &quot;Error Opening $NETWORKS: $!&quot;);  # Lock the file  flock NETWORKS, LOCK_EX;  print NETWORKS $HEAD;  print NETWORKS @mynetworks;  flock NETWORKS, LOCK_UN;  close NETWORKS;  $LOG-&gt;info(&quot;Wrote $NETWORKS&quot;);  return;}################################################################################# DESCRIPTION:Write the Relay_Domains file# PARAMETERS:Location of the RelayDomains map# RETURN:Nothing# NOTES:################################################################################sub Write_Relay_Domains($){  my $DOMAINS = shift;  my (@exclude_domains);  # Begin iterating over the domain files in the directory  $LOG-&gt;debug(&quot;Creating $DOMAINS file&quot;);    # Only write the file once all the queries are successful  open DOMAINS, &quot;&gt;$DOMAINS&quot; or    Die_Clean(&quot;Cannot Open $DOMAINS: $!&quot;, &quot;Cannot Open $DOMAINS: $!&quot;);    # Lock the file  flock DOMAINS, LOCK_EX;    print DOMAINS $HEAD;    foreach my $sid (@Server) {    my $host = $config-&gt;block($sid);    @exclude_domains = $host-&gt;get(&quot;ExcludeDomain&quot;);    next if $host-&gt;get(&quot;Active&quot;) == -1;    $LOG-&gt;debug(&quot;Processing &quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_domain file&quot;);    open DC_DOMAIN, $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_domain&quot;      or do {        $LOG-&gt;warn(&quot;Error opening file: &quot;. $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_domain&quot;);        next;        };    while (my $line = &lt;DC_DOMAIN&gt;) {      next unless $line =~ /^\/.*$/;      my $domain = $1 if ($line =~ /^\/\.?(.*)\$\/.*$/);      print DOMAINS $line        unless (grep { m/$domain/ } @exclude_domains );    }    close DC_DOMAIN;  }    flock DOMAINS,LOCK_UN;  close DOMAINS;    $LOG-&gt;info(&quot;Wrote $DOMAINS&quot;);  return;}################################################################################# DESCRIPTION:Write the Relay_Recipients file# PARAMETERS:None# RETURN:Nothing# NOTES:################################################################################sub Write_Relay_Recipients($){  my $RECIP = shift;  my (@exclude_domains);  $LOG-&gt;debug(&quot;Creating $RECIP file&quot;);    # Only write the file once all the queries are successful  open RECIP, &quot;&gt;$RECIP&quot; or    Die_Clean(&quot;Cannot Open $RECIP: $!&quot;, &quot;Cannot Open $RECIP: $!&quot;);    # Lock the file  flock RECIP, LOCK_EX;    print RECIP $HEAD;  foreach my $sid (@Server) {    my $host = $config-&gt;block($sid);    @exclude_domains = $host-&gt;get(&quot;ExcludeDomain&quot;);    next if $host-&gt;get(&quot;Active&quot;) == -1;    $LOG-&gt;debug(&quot;Processing &quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients file&quot;);    open DC_RECIP, $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients&quot;      or do {        $LOG-&gt;warn(&quot;Error opening file: &quot;. $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients&quot;);        next;        };    while (my $line = &lt;DC_RECIP&gt;) {      next unless $line =~ /^\/.*$/;      my ($user,$domain) = ($1,$2) if ($line =~ /^\/\^(.*?)\@(.*?)\$\/.*OK$/);      do {        print RECIP $line;        $domains-&gt;{$domain} = 1;      } unless (grep { m/$domain/ } @exclude_domains );    }    close DC_RECIP;  }    print RECIP &quot;\n\n&quot;.      &quot;# REJECT all other emails not destined for a user in our domains.\n&quot;.      &quot;\n&quot;;  foreach my $dom ( keys %{$domains} ) {    $dom =~ s/OK/REJECT/;    print RECIP &quot;/^.*\@$dom\$/REJECT\n&quot;;  }  flock RECIP, LOCK_UN;  close RECIP;    $LOG-&gt;info(&quot;Wrote $RECIP&quot;);    return;}################################################################################# DESCRIPTION:Prints the SPAM recipients to the SPAM hash file# PARAMETERS:Hash of domains to be added# RETURN:Nothing# NOTES:################################################################################sub Write_SenderScores($){  my $SCORES = shift;  $LOG-&gt;debug(&quot;Creating $SCORES file&quot;);    # Only write the file once all the queries are successful  open SCORES, &quot;&gt;$SCORES&quot; or    Die_Clean(&quot;Cannot Open $SCORES: $!&quot;, &quot;Cannot Open $SCORES: $!&quot;);    # Lock the file  flock SCORES, LOCK_EX;    print SCORES $HEAD;  foreach my $sid (@Server) {    my $host = $config-&gt;block($sid);    next if $host-&gt;get(&quot;Active&quot;) == -1;    $LOG-&gt;debug(&quot;Processing &quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients file&quot;);    open DC_SCORES, $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients&quot;      or do {        $LOG-&gt;warn(&quot;Error opening file: &quot;. $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_recipients&quot;);        next;        };    while (my $line = &lt;DC_SCORES&gt;) {      next unless $line =~ /^\/.*$/;      my ($user,$domain) = ($1,$2) if ($line =~ /^\/\^(.*?)\@(.*?)\$\/.*OK$/);      # The format of the SPAM_SITES file      # .example.com-4.0      print SCORES &quot;$user\@$domain&quot;. $config-&gt;get(&quot;WLSenderScore&quot;) .&quot;\n&quot;;      $domains-&gt;{$domain} = 1;    }    close DC_SCORES;  }  # Add the whitelist and blacklist sender specified in the config file  my (@wl) = $config-&gt;get(&quot;WLSenders&quot;);  my (@bl) = $config-&gt;get(&quot;BLSenders&quot;);  do {    print SCORES &quot;\n\n&quot;.  &quot;# Additional Whitelist senders\n&quot;;    foreach my $sender (@wl) {      print SCORES &quot;$sender&quot;. $config-&gt;get(&quot;WLSenderScore&quot;) .&quot;\n&quot;;    }   } if ($config-&gt;get(&quot;WLSenderScore&quot;));  do {    print SCORES &quot;\n\n&quot;.    &quot;# Additional Blacklist senders\n&quot;;    foreach my $sender (@bl) {      print SCORES &quot;$sender&quot;. $config-&gt;get(&quot;BLSenderScore&quot;) .&quot;\n&quot;;    }  } if ($config-&gt;get(&quot;BLSenderScore&quot;));    print SCORES &quot;\n\n&quot;.      &quot;# SCORES all other emails seemingly from a user in one of our domains.\n&quot;.      &quot;\n&quot;;  foreach my $dom ( keys %{$domains} ) {    print SCORES &quot;.$dom&quot;. $config-&gt;get(&quot;BLLocalSenderScore&quot;) .&quot;\n&quot;    unless ($dom =~ /\$\//);  }  flock SCORES, LOCK_UN;  close SCORES;    $LOG-&gt;info(&quot;Wrote $SCORES&quot;);    return;}################################################################################# DESCRIPTION:Write the TRANSPORT file# PARAMETERS:Location of the Transport map# RETURN:Nothing# NOTES:################################################################################sub Write_Transport($){  my $TRANSPORT = shift;  my (@exclude_domains);  $LOG-&gt;debug(&quot;Creating $TRANSPORT file&quot;);    # Only write the file once all the queries are successful  open TRANSPORT, &quot;&gt;$TRANSPORT&quot; or    Die_Clean(&quot;Cannot Open $TRANSPORT: $!&quot;, &quot;Cannot Open $TRANSPORT: $!&quot;);    # Lock the file  flock TRANSPORT, LOCK_EX;    print TRANSPORT $HEAD;  foreach my $sid (@Server) {    my $host = $config-&gt;block($sid);    @exclude_domains = $host-&gt;get(&quot;ExcludeDomain&quot;);    next if $host-&gt;get(&quot;Active&quot;) == -1;    $LOG-&gt;debug(&quot;Processing &quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_transport file&quot;);    open DC_TRANSPORT, $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_transport&quot;      or do {        $LOG-&gt;warn(&quot;Error opening file: &quot;. $config-&gt;get(&quot;Libdir&quot;) .&quot;/&quot;. $host-&gt;get(&quot;Host&quot;) .&quot;_transport&quot;);        next;        };    while (my $line = &lt;DC_TRANSPORT&gt;) {      next unless $line =~ /^\/.*$/;      my $domain = $1 if ($line =~ /^\/\.?(.*)\$\/.*$/);      print TRANSPORT $line        unless (grep { m/$domain/ } @exclude_domains );    }    close DC_TRANSPORT;  }  my (@bmx) = $config-&gt;get(&quot;BackupMX&quot;);  do {    print TRANSPORT &quot;\n\n&quot;.       &quot;# Secondary MX Records\n\n&quot;;    foreach my $server (@bmx) {      print TRANSPORT &quot;/^.*\$/relay:[$server]\n&quot;;    }   } if ($config-&gt;get(&quot;BackupMX&quot;));    flock TRANSPORT, LOCK_UN;  close TRANSPORT;    $LOG-&gt;info(&quot;Wrote $TRANSPORT&quot;);    return;}1;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Job schedule task inventory (shonorio)</title>
    <link>http://prlmnks.org/html/558029.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/558029.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;################################################################################# Program     : Job Iventory# Description : Do a job inventory on all computers passed by command line, and#               output theses job information as tab formated.# Author      : Solli M. Honorio shonorio[at]perl[dot]org[dot]br# License     : under the GPL (GNU Public License)################################################################################use Win32::TaskScheduler;use strict;######################################################################################################## G L O B A L  V A R I A B L E S ########################my %status_code = ( &#39;267008&#39; =&gt; &#39;Ready&#39;,                    &#39;267009&#39; =&gt; &#39;Running&#39;,                    &#39;267010&#39; =&gt; &#39;Disabled&#39;,                    &#39;267011&#39; =&gt; &#39;Has not run&#39;,                    &#39;267012&#39; =&gt; &#39;No more runs scheduled&#39;,                    &#39;267013&#39; =&gt; &#39;Not scheduled&#39;,                    &#39;267014&#39; =&gt; &#39;Terminated by User&#39;,                    &#39;267015&#39; =&gt; &#39;No valid triggers&#39;,                    &#39;267016&#39; =&gt; &#39;Event triggers dont have set run times&#39;,                    &#39;267017&#39; =&gt; &#39;Trigger not found&#39;,                    &#39;267018&#39; =&gt; &#39;Properties not all set&#39;,                    &#39;267019&#39; =&gt; &#39;No running task to terminate&#39;,                    &#39;267020&#39; =&gt; &#39;Task scheduler not installed&#39;,                    &#39;267021&#39; =&gt; &#39;Can not open task&#39;,                    &#39;267022&#39; =&gt; &#39;Invalid task&#39;,                    &#39;267023&#39; =&gt; &#39;No account information defined&#39;,                    &#39;267024&#39; =&gt; &#39;Acount name not found&#39;,                    &#39;267025&#39; =&gt; &#39;Account DB corrupt&#39;,                    &#39;267026&#39; =&gt; &#39;Security services only on NT&#39;,                    &#39;267027&#39; =&gt; &#39;Unknown object version&#39; );my %trigger_type = ( 0 =&gt; &#39;Once&#39;,                     1 =&gt; &#39;Daily&#39;,                     2 =&gt; &#39;Weekly&#39;,                     3 =&gt; &#39;Monthly Date&#39;,                     4 =&gt; &#39;Monthly Dow&#39;,                     5 =&gt; &#39;On idle&#39;,                     6 =&gt; &#39;At SystemStart&#39;,                     7 =&gt; &#39;At Logon&#39;);my %days_of_week = ( &#39;01&#39; =&gt; &#39;Sunday&#39;,                     &#39;02&#39; =&gt; &#39;Monday&#39;,                     &#39;04&#39; =&gt; &#39;Tuesday&#39;,                     &#39;08&#39; =&gt; &#39;Wednesday&#39;,                     &#39;16&#39; =&gt; &#39;Thursday&#39;,                     &#39;32&#39; =&gt; &#39;Friday&#39;,                     &#39;64&#39; =&gt; &#39;Saturday&#39;);my %months       = ( &#39;0001&#39; =&gt; &#39;January&#39;,                     &#39;0002&#39; =&gt; &#39;February&#39;,                     &#39;0004&#39; =&gt; &#39;March&#39;,                     &#39;0008&#39; =&gt; &#39;April&#39;,                     &#39;0016&#39; =&gt; &#39;May&#39;,                     &#39;0032&#39; =&gt; &#39;June&#39;,                     &#39;0064&#39; =&gt; &#39;July&#39;,                     &#39;0128&#39; =&gt; &#39;August&#39;,                     &#39;0256&#39; =&gt; &#39;September&#39;,                     &#39;0512&#39; =&gt; &#39;October&#39;,                     &#39;1024&#39; =&gt; &#39;November&#39;,                     &#39;2048&#39; =&gt; &#39;December&#39;);my %which_week = (  1 =&gt; &#39;Fist week&#39;,                    2 =&gt; &#39;Second week&#39;,                    3 =&gt; &#39;Third week&#39;,                    4 =&gt; &#39;Fourth week&#39;,                    5 =&gt; &#39;Last week&#39; );######################## G L O B A L  V A R I A B L E S ############################################################################################################################################################################################################### D O   J O B   I N V E N T O R Y ########################my %jobs_processed;for ( @ARGV ) {    if ( my @array = get_job_info ($_) ) {        @{$jobs_processed{$_}} = @array;    }}####################### D O   J O B   I N V E N T O R Y ############################################################################################################################################################################################################## O U T P U T   I N F O R M A T I O N #####################print &quot;Computer\t&quot;;print &quot;Job_Name\t&quot;;print &quot;Application_Name\t&quot;;print &quot;Parameters\t&quot;;print &quot;WorkDirectory\t&quot;;print &quot;Comment\t&quot;;print &quot;MostRecentRunTime\t&quot;;print &quot;NextRunTime\t&quot;;print &quot;MaxRunTime\t&quot;;print &quot;Priority\t&quot;;print &quot;Status\t&quot;;print &quot;User\t&quot;;print &quot;Creator\t&quot;;print &quot;Error\t&quot;;print &quot;Flag_Delete when done\t&quot;;print &quot;Flag_Disabled}\t&quot;;print &quot;Flag_Dont start if on batteries\t&quot;;print &quot;Flag_Hidden\t&quot;;print &quot;Flag_Interactive\t&quot;;print &quot;Flag_Kill if going on batteries\t&quot;;print &quot;Flag_Kill on idle end\t&quot;;print &quot;Flag_Restart on idle resume\t&quot;;print &quot;Flag_Run if connected to internet\t&quot;;print &quot;Flag_Run only if docked\t&quot;;print &quot;Flag_Start only if idle\t&quot;;print &quot;Flag_System required\t&quot;;print &quot;Trigger_String\t&quot;;print &quot;Trigger_Type\t&quot;;print &quot;Trigger_StartDay\t&quot;;print &quot;Trigger_EndDay\t&quot;;print &quot;Trigger_StartTime\t&quot;;print &quot;Trigger_Duration\t&quot;;print &quot;Trigger_Interval\t&quot;;print &quot;Trigger_Schedule_DaysInterval\t&quot;;print &quot;Trigger_Schedule_WeeksInterval\t&quot;;print &quot;Trigger_Schedule_WeeksDays\t&quot;;print &quot;Trigger_Schedule_Days\t&quot;;print &quot;Trigger_Schedule_WhichWeek\t&quot;;print &quot;Trigger_Schedule_Months\n&quot;;foreach my $cp ( sort keys %jobs_processed ) {    foreach my $job ( @{$jobs_processed{$cp}} ) {        foreach my $idx ( sort keys %{$job-&gt;{Trigger}} ) {            print &quot;$cp\t&quot;;            print &quot;$job-&gt;{Name}\t&quot;;            print &quot;$job-&gt;{AppName}\t&quot;;            print &quot;$job-&gt;{Parameters}\t&quot;;            print &quot;$job-&gt;{WorkDirectory}\t&quot;;            print &quot;$job-&gt;{Comment}\t&quot;;            print &quot;$job-&gt;{MostRecentRunTime}\t&quot;;            print &quot;$job-&gt;{NextRunTime}\t&quot;;            print &quot;$job-&gt;{MaxRunTime}\t&quot;;            print &quot;$job-&gt;{Priority}\t&quot;;            print &quot;$job-&gt;{Status}\t&quot;;            print &quot;$job-&gt;{User}\t&quot;;            print &quot;$job-&gt;{Creator}\t&quot;;            print &quot;$job-&gt;{Error}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Delete when done&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{Disabled}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Dont start if on batteries&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{Hidden}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{Interactive}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Kill if going on batteries&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Kill on idle end&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Restart on idle resume&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Run if connected to internet&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Run only if docked&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;Start only if idle&#39;}\t&quot;;            print &quot;$job-&gt;{Flag}-&gt;{&#39;System required&#39;}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{String}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Type}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{StartDay}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{EndDay}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{StartTime}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Duration}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Interval}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Schedule}{DaysInterval}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Schedule}{WeeksInterval}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Schedule}{WeeksDays}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Schedule}{Days}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Schedule}{WhichWeek}\t&quot;;            print &quot;$job-&gt;{Trigger}{$idx}{Schedule}{Months}\n&quot;;        }    }}###################### O U T P U T   I N F O R M A T I O N #####################################################################################################sub get_job_info {    my $computer_name = shift;    my $scheduler     = Win32::TaskScheduler-&gt;New();    my @jobs;        if ( $scheduler-&gt;SetTargetComputer(&quot;\\\\$computer_name&quot;) ) {        foreach my $job_name ( $scheduler-&gt;Enum() ) {            my %job;            $job_name  =~ s/\.job$//i;            $job{Name} = $job_name;                    if ( $scheduler-&gt;Activate($job{Name}) ) {                my ( $pri, $status, $error, $flags, $time_milli_seconds );                $scheduler-&gt;GetPriority($pri);                $scheduler-&gt;GetStatus($status);                $scheduler-&gt;GetExitCode($error);                $flags = $scheduler-&gt;GetFlags();                $job{Flag}{&#39;Interactive&#39;}                  = ( $flags &amp; $scheduler-&gt;TASK_FLAG_INTERACTIVE ) ? 1 : 0;                $job{Flag}{&#39;Delete when done&#39;}             = ( $flags &amp; $scheduler-&gt;TASK_FLAG_DELETE_WHEN_DONE ) ? 1 : 0;                $job{Flag}{&#39;Disabled&#39;}                     = ( $flags &amp; $scheduler-&gt;TASK_FLAG_DISABLED ) ? 1 : 0;                $job{Flag}{&#39;Start only if idle&#39;}           = ( $flags &amp; $scheduler-&gt;TASK_FLAG_START_ONLY_IF_IDLE ) ? 1 : 0;                $job{Flag}{&#39;Kill on idle end&#39;}             = ( $flags &amp; $scheduler-&gt;TASK_FLAG_KILL_ON_IDLE_END ) ? 1 : 0;                $job{Flag}{&#39;Dont start if on batteries&#39;}   = ( $flags &amp; $scheduler-&gt;TASK_FLAG_DONT_START_IF_ON_BATTERIES ) ? 1 : 0;                $job{Flag}{&#39;Kill if going on batteries&#39;}   = ( $flags &amp; $scheduler-&gt;TASK_FLAG_KILL_IF_GOING_ON_BATTERIES ) ? 1 : 0;                $job{Flag}{&#39;Run only if docked&#39;}           = ( $flags &amp; $scheduler-&gt;TASK_FLAG_RUN_ONLY_IF_DOCKED ) ? 1 : 0;                $job{Flag}{&#39;Hidden&#39;}                       = ( $flags &amp; $scheduler-&gt;TASK_FLAG_HIDDEN ) ? 1 : 0;                $job{Flag}{&#39;Run if connected to internet&#39;} = ( $flags &amp; $scheduler-&gt;TASK_FLAG_RUN_IF_CONNECTED_TO_INTERNET ) ? 1 : 0;                $job{Flag}{&#39;Restart on idle resume&#39;}       = ( $flags &amp; $scheduler-&gt;TASK_FLAG_RESTART_ON_IDLE_RESUME ) ? 1 : 0;                $job{Flag}{&#39;System required&#39;}              = ( $flags &amp; $scheduler-&gt;TASK_FLAG_SYSTEM_REQUIRED ) ? 1 : 0;                if ( $pri eq $scheduler-&gt;REALTIME_PRIORITY_CLASS ) {                    $job{Priority} = &#39;Real time&#39;;                } elsif ( $pri eq $scheduler-&gt;HIGH_PRIORITY_CLASS ) {                    $job{Priority} = &#39;High&#39;;                } elsif ( $pri eq $scheduler-&gt;NORMAL_PRIORITY_CLASS ) {                    $job{Priority} = &#39;Normal&#39;;                } elsif ( $pri eq $scheduler-&gt;IDLE_PRIORITY_CLASS ) {                    $job{Priority} = &#39;Idle&#39;;                } else {                    $job{Priority} = &#39;Unknown&#39;;                }                            $job{User}              = $scheduler-&gt;GetAccountInformation();                $job{AppName}           = $scheduler-&gt;GetApplicationName();                $job{Parameters}        = $scheduler-&gt;GetParameters();                $job{WorkDirectory}     = $scheduler-&gt;GetWorkingDirectory();                $job{Status}            = $status_code{$status};                $job{Error}             = $error;                $job{Comment}           = $scheduler-&gt;GetComment();                $job{Creator}           = $scheduler-&gt;GetCreator();                $job{NextRunTime}       = format_hour($scheduler-&gt;GetNextRunTime());                $job{MostRecentRunTime} = format_hour($scheduler-&gt;GetMostRecentRunTime());                if ( ( $time_milli_seconds = $scheduler-&gt;GetMaxRunTime() ) &gt; -1 ) {                    my ($hours, $minutes, $secounds);                    $secounds = $time_milli_seconds / 1000;                    $hours    = int ( $secounds / 3600 );                    $minutes  = int ( ( $secounds - ( $hours * 3600 ) ) / 60 );                    $secounds = int ( ( $secounds - ( ( $hours * 3600 ) + ( $minutes * 60 ) ) ) );                    $job{MaxRunTime} = sprintf &quot;%d:%02d:%02d&quot;,$hours,$minutes,$secounds;                }                for ( my $idx = 0; $idx &lt; $scheduler-&gt;GetTriggerCount(); $idx++ ) {                    my ( %trigger );                    $scheduler-&gt;GetTrigger( $idx, \%trigger );                    $job{Trigger}{$idx}{String}    = $scheduler-&gt;GetTriggerString($idx);                    $job{Trigger}{$idx}{Type}      = $trigger_type{$trigger{&quot;TriggerType&quot;}};                    $job{Trigger}{$idx}{StartDay}  = sprintf &quot;%04d-%02d-%02d&quot;, $trigger{BeginYear}, $trigger{BeginMonth}, $trigger{BeginDay};                    $job{Trigger}{$idx}{EndDay}    = sprintf &quot;%04d-%02d-%02d&quot;, $trigger{EndYear}, $trigger{EndMonth}, $trigger{EndDay};                    $job{Trigger}{$idx}{StartTime} = sprintf &quot;%02d:%02d&quot;, $trigger{StartHour}, $trigger{StartMinute};                    $job{Trigger}{$idx}{Duration}  = sprintf &quot;%02d:%02d&quot;, ( int $trigger{MinutesDuration} / 60 ),                                                                          ( $trigger{MinutesDuration} - ( ( int $trigger{MinutesDuration} / 60 ) ) * 60 );                    $job{Trigger}{$idx}{Interval}  = sprintf &quot;%02d:%02d&quot;, ( int $trigger{MinutesInterval} / 60 ),                                                                          ( $trigger{MinutesInterval} - ( ( int $trigger{MinutesInterval} / 60 ) ) * 60 );                    if ( $trigger{&quot;Type&quot;} ) {                        # build a schedule structure                        if ( $trigger{&#39;TriggerType&#39;} == $scheduler-&gt;TASK_TIME_TRIGGER_DAILY ) {                            $job{Trigger}{$idx}{Schedule}{DaysInterval} = $trigger{&#39;Type&#39;}{DaysInterval};                        } elsif ( $trigger{&#39;TriggerType&#39;} == $scheduler-&gt;TASK_TIME_TRIGGER_WEEKLY ) {                            $job{Trigger}{$idx}{Schedule}{WeeksInterval} = $trigger{&#39;Type&#39;}{WeeksInterval};                            # do a loop and return the list of week days                            $job{Trigger}{$idx}{Schedule}{WeeksDays}     = join &#39;,&#39;, map { ( $_ &amp; $trigger{&#39;Type&#39;}{DaysOfTheWeek} ) ? $days_of_week{$_} : () } sort keys %days_of_week;                        } elsif ( $trigger{&quot;TriggerType&quot;} == $scheduler-&gt;TASK_TIME_TRIGGER_MONTHLYDATE ) {                            $job{Trigger}{$idx}{Schedule}{Days}   = $trigger{&#39;Type&#39;}{Days};                            # do a loop and return the list of months                            $job{Trigger}{$idx}{Schedule}{Months} = join &#39;,&#39;, map { ( $_ &amp; $trigger{&#39;Type&#39;}{Months} ) ? $months{$_} : () } sort keys %months;                        } elsif ( $trigger{&quot;TriggerType&quot;} == $scheduler-&gt;TASK_TIME_TRIGGER_MONTHLYDOW ) {                            $job{Trigger}{$idx}{Schedule}{WhichWeek} = $which_week{$trigger{&#39;Type&#39;}{WhichWeek}};                             $job{Trigger}{$idx}{Schedule}{WeeksDays} = $days_of_week{$trigger{&#39;Type&#39;}{DaysOfTheWeek}};                            # do a loop and return the list of months                            $job{Trigger}{$idx}{Schedule}{Months} = join &#39;,&#39;, map { ( $_ &amp; $trigger{&#39;Type&#39;}{Months} ) ? $months{$_} : () } sort keys %months;                        }                    }                }                push @jobs, \%job;            } else {                print STDERR &quot;Could not activate the job $job{Name} at computer $computer_name\n&quot;;            }        }        $scheduler-&gt;End();        return @jobs;    } else {        print STDERR &quot;Could not connect the computer $computer_name\n&quot;;        return ();    }}sub format_hour {    my ($ms, $sec, $min, $hour, $day, $dayofweek, $month, $year) = @_;    return sprintf &quot;%04d-%02d-%02d %02d:%02d:%02d&quot;,$year,$month,$day,$hour,$min,$sec;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Another Server Info Snooper (AsIs) ;) (Alexander)</title>
    <link>http://prlmnks.org/html/557617.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/557617.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -w# bourne.pl &quot;monkified&quot; v1.0# bart lines 5 &amp; 29, and theorbtwo for ! delimiters line 36use strict;############## note: six assumptions are made here...## 1) $USER legal characters are alphanumeric, &quot;_&quot;, or &quot;-&quot;## 2) $USER is between 3 and 16 characters in length## 3) your default shell is a bourne-like shell (like bash)## 4) you know enough bourne shell to not get in trouble## 5) your $HOME directory is /home/$USER## 6) you accept that you are using this at your own riskmy @cmds = split /\n/, &lt;&lt;&#39;--CMDs--&#39;;##############  editwhoamipwdidecho \$PATH=$PATHecho \$PERL5LIB=$PERL5LIBperl -V############## no edit--CMDs--my $i=4;my $size=@cmds;my $me=`whoami`;my $dir=`pwd`;$me=~s/\n//;$dir=~s/\n//;$dir=~s!\/home\/[\w-]{3,16}\/!\/!;my $prompt=&quot;$me\@~$dir&gt;&quot;;print &quot;Content-type: text/plain\n\n&quot;;while ($i &lt;= $size - 4) { my $cmd=$cmds[$i]; print $prompt,&quot;$cmd\n&quot;,`$cmd`,&quot;\n&quot;; $i++; }&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Massage the driving directions (in USA) (parv)</title>
    <link>http://prlmnks.org/html/556128.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/556128.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!perl#  This program massages the driving directions (in USA) for plain text#  printing (preferably in monospace font, w/ a blank line between each non#  empty line), with these prioririties (in no particular order) ...#   - up-case road names, exit numbers, places#   - low-case everything else#   - expand n, w, e, s to north, west, east, south#   - shorten road type (like mailing address), e.g. &#39;road&#39; to &#39;rd&#39;, &#39;lane&#39; to#     &#39;ln&#39;, etc.#   - removes the annoying &#39;go&#39; from &#39;go &lt;this much&gt;&#39;use warnings; use strict;my ( $geo_pos , $roads ) = ( get_geo_pos() , get_road() );my @relative_pos = map uc( $_ ) , qw(left middle center right) ;#  Got a better name for this variable?my $less_important_than_roads_places =  qr{ \b      ( bear | stay | head | continue | follow | go | take | turn       | entry | ramp | (?: to | fore? )w[oa]rds?       | on.?to | on | to | for | at | off?  | then | t?here | from       | an?d?       | (?: h(?:ou)?r | min(?:ute)? | second | moment )s?       | ph(?:one)? | fax | e.?mail | home | office | work | cell | mobile      )      \b    }xi;my $misc_edits =  {    &#39;and&#39; =&gt; &#39;&amp;&#39;  , &#39;hour&#39; =&gt; &#39;hr&#39;  , &#39;minutes?&#39; =&gt; &#39;min&#39;  , &#39;seconds&#39; =&gt; &#39;second&#39;  , &#39;phone&#39; =&gt; &#39;ph&#39;  , &#39;fore?w[oa]rd&#39; =&gt; &#39;forward&#39;  , &#39;toword&#39; =&gt; &#39;toward&#39;  } ;{  local $^I = &#39;&#39; ;  while ( &lt;&gt; )  {    s{ \s+ the \s+ }/ /xig;    s{ \b go (?: \s+ for )? \s+ (\d) }/ $1/xige;    $_ = uc $_;    s{ (\d) \W* ( mi(?:le)? | ft) \b }/&quot;$1~&quot; . lc $2/xige;    s{ $less_important_than_roads_places }/lc $1/xige;    for my $map ( $roads , $geo_pos , $misc_edits )    {      while ( my ( $k , $v ) = each %$map )      {        s[ \b $k \b ]/$v/xig;      }    }    for my $r ( values %$roads )    {      s/\b $r \./$r/xig;    }    s/^[ \t]+//g;    s/[ \t]+$//g;    s/[ \t]+/ /g;    print;  }}sub get_geo_pos{  my @points =    qw(        east west north south        north-east north-west south-east south-west        east-north east-south west-north west-south      ) ;  my %points ;  foreach ( @points )  {    m{^ ([a-z])[a-z]+ (?: \W+ ( [a-z])[a-z]+ )? $}xi;    $points{ $2 ? &quot;$1$2&quot; : $1 } = uc $_ ;  }  return { %points };}sub get_road{  my %roads =    (      &#39;avenue&#39; =&gt; &#39;ave&#39;    , &#39;av&#39; =&gt; &#39;ave&#39;    , &#39;circle&#39; =&gt; &#39;crl&#39;    , &#39;court&#39; =&gt; &#39;ct&#39;    , &#39;crt&#39; =&gt; &#39;ct&#39;    , &#39;drive&#39; =&gt; &#39;dr&#39;    , &#39;lane&#39; =&gt; &#39;ln&#39;    , &#39;pk&#39; =&gt; &#39;pike&#39;    , &#39;parkway&#39; =&gt; &#39;pkwy&#39;    , &#39;pky&#39; =&gt; &#39;pkwy&#39;    , &#39;road&#39; =&gt; &#39;rd&#39;    , &#39;route&#39; =&gt; &#39;rt&#39;    , &#39;street&#39; =&gt; &#39;st&#39;    , &#39;tpk&#39; =&gt; &#39;turnpike&#39;    , &#39;turn.?pk&#39; =&gt; &#39;turnpike&#39;    );  $_ = uc $_ for values %roads;  return { %roads };}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>perltoxmi (g0n)</title>
    <link>http://prlmnks.org/html/555854.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/555854.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;################################################################################################################ perltoxmi - extract class definitions from oo perl code, and write out xmi for import into CASE tools# Charles Colbourn June 2006################################################################################################################# HISTORY## 0.01CColbourn20060616Rough first version################################################################################################################# TO DO## Error checking# Write to file instead of STDOUT# Clean up, abstract and make readable# detect require as well as use# detect double quoted attrib names just in case################################################################################################################# Usage# perltoxmi MyClass.pm MyOtherClass.pm &gt; classes.xmi# OR# cat *.pm |perltoxmi &gt;classes.xmi################################################################################################################# Notes## The XMI output is cut and pasted from ArgoUML output. Pretty it isn&#39;t, but it seems to work# Export your classes into xmi, then import xmi into Argo (works with v0.20 definitely). Can use &#39;add namespace# to class diagram&#39;, and &#39;layout&#39; to do an initial layout.# It exports any classes included with &#39;use&#39; but outside the files it&#39;s been passed as interfaces (which aren&#39;t# automatically added into class diagrams, handily - otherwise there would be hundreds of lines to &#39;strict&#39;)## It&#39;s a dirty, dirty hack, but it does what I need :-)################################################################################################################## 16 hex digits in countermy ($header,$classtemplate,$attribtemplate,$methodtemplate,$generalisetemplate,$footer,$interfacetemplate,$associationtemplate);{local $/ = &#39;%%ENDOFTEMPLATE%%&#39;;$header = &lt;DATA&gt;;$classtemplate = &lt;DATA&gt;;$interfacetemplate = &lt;DATA&gt;;$attribtemplate = &lt;DATA&gt;;$methodtemplate = &lt;DATA&gt;;$generalisetemplate = &lt;DATA&gt;;$associationtemplate = &lt;DATA&gt;;$footer = &lt;DATA&gt;;}my $counter = 2000;my $package;my %obj;while (&lt;&gt;){if ($_ =~/package ([\w:]+);/){$package = $1;$obj{$1} = {};}if ($_=~/use\s+([\w\:]+);/){$obj{$package}{uses}{$1}++;}if ($_ =~/use base\s+(?:qw\(|\&#39;|\&quot;)([\w\:\s]+)/){my (@parents) = $1=~/([\w\:]+)/g;for (@parents){$obj{$package}{parents}{$_}++}}if ($_ =~/sub\s+(\w+)/){#print $package.&quot;::&quot;.$1.&quot;\n&quot;;$obj{$package}{methods}{$1}++;}if ($_ =~/\$self-&gt;\{[\&#39;]*([\w\s]*)\}/){#print $package.&quot;-&gt;$1\n&quot;$obj{$package}{attribs}{$1}++;}}my %classnametocounter;my %generalisations;my %associations;my $interfacexml;my %interfaces;my $xml = &quot;&quot;;for $package (keys %obj){my $classprintcounter = sprintf(&quot;%016X&quot;,++$counter);my $class = $classtemplate;$class=~s/%%CLASSNAME%%/$package/g;$class=~s/%%COUNTER%%/$classprintcounter/g;my $attribsxml = &quot;&quot;;for (keys %{$obj{$package}{attribs}}){my $attrib = $attribtemplate;$attrib=~s/%%ATTRIBNAME%%/$_/;my $printcounter = sprintf(&quot;%016X&quot;,++$counter);$attrib =~s/%%COUNTER%%/$printcounter/;my $visibility = &quot;public&quot;;if ($_=~/^\_/){$visibility = &quot;private&quot;}$attrib =~s/%%VISIBILITY%%/$visibility/g;$attribsxml .= $attrib;}my $methodsxml = &quot;&quot;;for (keys %{$obj{$package}{methods}}){my $method = $methodtemplate;$method=~s/%%METHODNAME%%/$_/;my $printcounter = sprintf(&quot;%016X&quot;,++$counter);$method =~s/%%COUNTER%%/$printcounter/;my $visibility = &quot;public&quot;;if ($_=~/^\_/){$visibility = &quot;private&quot;}$method =~s/%%VISIBILITY%%/$visibility/g;$methodsxml .= $method;}$classnametocounter{$package} = $classprintcounter;for (keys %{$obj{$package}{parents}}){$generalisations{$package} = $_;}for (keys %{$obj{$package}{uses}}){$interfaces{$_}++;$associations{$package}{$_}++;}$class =~s/%%ATTRIBXML%%/$attribsxml/;$class =~s/%%METHODXML%%/$methodsxml/;$xml .= $class;}for my $intname (keys %interfaces){if ($obj{$intname}){next} # don&#39;t create an interface if the class is in read scopemy $printcounter = sprintf(&quot;%016X&quot;,++$counter);my $interface = $interfacetemplate;$interface=~s/%%INTERFACENAME%%/$intname/g;$interface=~s/%%COUNTER%%/$printcounter/g;$classnametocounter{$intname} = $printcounter;$xml .= $interface;}for (keys %generalisations){my $generalisation = $generalisetemplate;my $childcounter = $classnametocounter{$_};my $parentcounter = $classnametocounter{$generalisations{$_}};$generalisation =~s/%%CHILDCOUNTER%%/$childcounter/;$generalisation =~s/%%PARENTCOUNTER%%/$parentcounter/;my $printcounter = sprintf(&quot;%016X&quot;,++$counter);$generalisation =~s/%%COUNTER%%/$printcounter/;#take out the association - we don&#39;t want both a vanilla association and a generalisationif ($associations{$_}{$generalisations{$_}}){delete $associations{$_}{$generalisations{$_}}}$xml .= $generalisation;}for my $package(keys %associations){for my $association (keys %{$associations{$package}}){my $associationxml = $associationtemplate;my $usingclasscounter = $classnametocounter{$package};my $usedclasscounter = $classnametocounter{$association};$associationxml =~s/%%USINGCLASS%%/$usingclasscounter/;$associationxml =~s/%%USEDCLASS%%/$usedclasscounter/;my $printcounter = sprintf(&quot;%016X&quot;,++$counter);$associationxml =~s/%%COUNTER%%/$printcounter/;my $usedclassendcounter = sprintf(&quot;%016X&quot;,++$counter);$associationxml =~s/%%USEDENDCOUNTER%%/$usedclassendcounter/;my $usingclassendcounter = sprintf(&quot;%016X&quot;,++$counter);$associationxml =~s/%%USINGENDCOUNTER%%/$usingclassendcounter/;$xml .= $associationxml;}}# get rid of the template markers$xml=~s/%%ENDOFTEMPLATE%%//sg;$header =~s/%%ENDOFTEMPLATE%%//sg;$footer=~s/%%ENDOFTEMPLATE%%//sg;print $header.&quot;\n&quot;;print $xml;print $footer.&quot;\n&quot;;__DATA__&lt;?xml version = &#39;1.0&#39; encoding = &#39;UTF-8&#39; ?&gt;&lt;XMI xmi.version = &#39;1.2&#39; xmlns:UML = &#39;org.omg.xmi.namespace.UML&#39; timestamp = &#39;Thu Jun 15 12:59:02 BST 2006&#39;&gt;  &lt;XMI.header&gt;  &lt;XMI.header&gt;    &lt;XMI.documentation&gt;      &lt;XMI.exporter&gt;ArgoUML (using Netbeans XMI Writer version 1.0)&lt;/XMI.exporter&gt;      &lt;XMI.exporterVersion&gt;0.20.x&lt;/XMI.exporterVersion&gt;    &lt;/XMI.documentation&gt;    &lt;XMI.metamodel xmi.name=&quot;UML&quot; xmi.version=&quot;1.4&quot;/&gt;  &lt;/XMI.header&gt;&lt;/XMI.header&gt;  &lt;XMI.content&gt;    &lt;UML:Model xmi.id = &#39;.:0000000000000001&#39; name = &#39;UNNAMED&#39; isSpecification = &#39;false&#39;      isRoot = &#39;false&#39; isLeaf = &#39;false&#39; isAbstract = &#39;false&#39;&gt;%%ENDOFTEMPLATE%%      &lt;UML:Namespace.ownedElement&gt;        &lt;UML:Class xmi.id = &#39;.:%%COUNTER%%&#39; name = &#39;%%CLASSNAME%%&#39; visibility = &#39;public&#39;          isSpecification = &#39;false&#39; isRoot = &#39;false&#39; isLeaf = &#39;false&#39; isAbstract = &#39;false&#39;          isActive = &#39;false&#39;&gt;          &lt;UML:Classifier.feature&gt;%%ATTRIBXML%%%%METHODXML%%                      &lt;/UML:Classifier.feature&gt;        &lt;/UML:Class&gt;   &lt;/UML:Namespace.ownedElement&gt;%%ENDOFTEMPLATE%%      &lt;UML:Namespace.ownedElement&gt;        &lt;UML:Interface xmi.id = &#39;.:%%COUNTER%%&#39; name = &#39;%%INTERFACENAME%%&#39; visibility = &#39;public&#39;          isSpecification = &#39;false&#39; isRoot = &#39;false&#39; isLeaf = &#39;false&#39; isAbstract = &#39;false&#39;          isActive = &#39;false&#39;/&gt;&lt;/UML:Namespace.ownedElement&gt;%%ENDOFTEMPLATE%%            &lt;UML:Attribute xmi.id = &#39;.:%%COUNTER%%&#39; name = &#39;%%ATTRIBNAME%%&#39; visibility = &#39;%%VISIBILITY%%&#39;              isSpecification = &#39;false&#39; ownerScope = &#39;instance&#39; changeability = &#39;changeable&#39;              targetScope = &#39;instance&#39;&gt;            &lt;/UML:Attribute&gt;%%ENDOFTEMPLATE%%            &lt;UML:Operation xmi.id = &#39;.:%%COUNTER%%&#39; name = &#39;%%METHODNAME%%&#39; visibility = &#39;%%VISIBILITY%%&#39;              isSpecification = &#39;false&#39; ownerScope = &#39;instance&#39; isQuery = &#39;false&#39; concurrency = &#39;sequential&#39;              isRoot = &#39;false&#39; isLeaf = &#39;false&#39; isAbstract = &#39;false&#39;&gt;            &lt;/UML:Operation&gt;%%ENDOFTEMPLATE%%&lt;UML:Namespace.ownedElement&gt;        &lt;UML:Generalization xmi.id = &#39;.:%%COUNTER%%&#39; isSpecification = &#39;false&#39;&gt;          &lt;UML:Generalization.child&gt;            &lt;UML:Class xmi.idref = &#39;.:%%CHILDCOUNTER%%&#39;/&gt;          &lt;/UML:Generalization.child&gt;          &lt;UML:Generalization.parent&gt;            &lt;UML:Class xmi.idref = &#39;.:%%PARENTCOUNTER%%&#39;/&gt;          &lt;/UML:Generalization.parent&gt;        &lt;/UML:Generalization&gt;&lt;/UML:Namespace.ownedElement&gt;%%ENDOFTEMPLATE%%&lt;UML:Namespace.ownedElement&gt;        &lt;UML:Association xmi.id = &#39;.:%%COUNTER%%&#39; name = &#39;uses&#39; isSpecification = &#39;false&#39;          isRoot = &#39;false&#39; isLeaf = &#39;false&#39; isAbstract = &#39;false&#39;&gt;          &lt;UML:Association.connection&gt;            &lt;UML:AssociationEnd xmi.id = &#39;.:%%USINGENDCOUNTER%%&#39; visibility = &#39;public&#39;              isSpecification = &#39;false&#39; isNavigable = &#39;false&#39; ordering = &#39;unordered&#39; aggregation = &#39;none&#39;              targetScope = &#39;instance&#39; changeability = &#39;changeable&#39;&gt;              &lt;UML:AssociationEnd.participant&gt;                &lt;UML:Class xmi.idref = &#39;.:%%USINGCLASS%%&#39;/&gt;              &lt;/UML:AssociationEnd.participant&gt;            &lt;/UML:AssociationEnd&gt;            &lt;UML:AssociationEnd xmi.id = &#39;.:%%USEDENDCOUNTER%%&#39; visibility = &#39;public&#39;              isSpecification = &#39;false&#39; isNavigable = &#39;true&#39; ordering = &#39;unordered&#39; aggregation = &#39;none&#39;              targetScope = &#39;instance&#39; changeability = &#39;changeable&#39;&gt;              &lt;UML:AssociationEnd.participant&gt;                &lt;UML:Interface xmi.idref = &#39;.:%%USEDCLASS%%&#39;/&gt;              &lt;/UML:AssociationEnd.participant&gt;            &lt;/UML:AssociationEnd&gt;          &lt;/UML:Association.connection&gt;        &lt;/UML:Association&gt;&lt;/UML:Namespace.ownedElement&gt;%%ENDOFTEMPLATE%%    &lt;/UML:Model&gt;  &lt;/XMI.content&gt;&lt;/XMI&gt;%%ENDOFTEMPLATE%%&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>MoveCeiling (bpoag)</title>
    <link>http://prlmnks.org/html/555649.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/555649.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl## MoveCeiling v0.2 written 061206:1122 by BJP## MoveCeiling will watch and automatically increase the size of an AIX filesystem# given user-specified parameters.## Usage: moveceiling &lt;ceiling in MB&gt; &lt;filesystem&gt; &lt;increment size&gt; &lt;sleep time&gt; &lt;space to preserve&gt; &lt;notify counter&gt; &lt;email address&gt;# Example: moveceiling 500 /tmp 64 3200 5 foo@bar.com# English: Keep 500MB free in /tmp. If you have to add space, add it in 64MB chunks. Preserve 3200MB in the volume group.#          Remind me every 5 times you have to increase space, and send that reminder to foo@bar.com#use Mail::Sendmail;$ceilingSize=$ARGV[0];$targetFS=$ARGV[1];$incrementSize=$ARGV[2];$sleepTime=$ARGV[3];$preserveAmount=$ARGV[4];$notifyCounter=$ARGV[5];$mailRecipient=$ARGV[6];$mailSender=$ENV{&quot;USER&quot;}.&quot;\@&quot;.&quot;localhost&quot;;if ($#ARGV!=6){ showUsage(); exit();}spinUpRoutine();mainRoutine();spinDownRoutine();sub showUsage(){ print &quot;\n MoveCeiling&#39;s job is to watch a filesystem, and increase it&#39;s size if the\n&quot;; print &quot; amount of free space in that filesystem falls below threshold. MoveCeiling\n&quot;; print &quot; is much smarter than it used to be, but you should still use it with caution. \n&quot;; print &quot;\n&quot;; print &quot;      Usage: moveceiling &lt;ceiling in MB&gt; &lt;filesystem&gt; &lt;increment size&gt; &lt;sleep time&gt; &lt;space to preserve&gt; &lt;notify counter&gt; &lt;email address&gt;\n&quot;; print &quot;    Example: moveceiling 500 /tmp 64 30 5 foo\@bar.com\n&quot;; print &quot; In English: Every 30 seconds, check to see if /tmp has at least 500MB free. \n&quot;; print &quot;             If it sinks below 500MB, add another 64MB. For every 5 times I \n&quot;; print &quot;             add more space, i&#39;ll send a status message to foo\@bar.com.\n&quot;; print &quot;\n\n&quot;; exit();}sub spinUpRoutine(){ print &quot;\nMoveCeiling: I will make sure $targetFS has at least $ceilingSize MB free.&quot;; print &quot;\nMoveCeiling: If I have to increase it&#39;s size, I will do so in $incrementSize MB increments.&quot;; print &quot;\nMoveCeiling: Every $notifyCounter times I do so, i&#39;ll drop a note to $mailRecipient.&quot;; print &quot;\nMoveCeiling: I&#39;ll stop adding storage if the volume group has less than $preserveAmount MB remaining.&quot;; print &quot;\nMoveCeiling: Starting up..\n&quot;; ## Check to see if the filesystem actually exists... @dfContents=split(/\s+/,`df -m | grep &quot; $targetFS\$&quot;`); if(length($targetFS)==length($dfContents[6])) {  print &quot;MoveCeiling: Examining $dfContents[6]..\n&quot;; } else {  print &quot;MoveCeiling: Uh-oh.. Can&#39;t find the filesystem you specified ($targetFS)..!  Exiting.\n\n&quot;;  exit(); } ## So far so good. Pull up the VG info for this filesystem.. $dfContents[0]=~/\/dev\//; $targetLV=$&#39;; @lslvContents=split(/\s+/,`lslv $targetLV|head -n1` ); $targetVG=$lslvContents[5]; print &quot;MoveCeiling: $targetFS belongs to logical volume $targetLV inside $targetVG.\n&quot;; @lsvgDump=split(/\s+/,`lsvg -L $targetVG | head -n4 | tail -n1`); $lsvgDump[6]=~/\(/; $targetVGSpaceRemaining=$&#39;; print &quot;MoveCeiling: $targetVG has $targetVGSpaceRemaining MB remaining, of which $preserveAmount MB will be preserved.\n\n&quot;;}sub mainRoutine(){ while(true) {  @dfContents=split(/\s+/,`df -m | grep &quot; $targetFS\$&quot;`);  chomp($dateString=`date`);  print &quot;MoveCeiling: $dfContents[2] MB remaining in $targetFS as of $dateString.\n&quot;;         @lsvgDump=split(/\s+/,`lsvg -L $targetVG | head -n4 | tail -n1`);          $lsvgDump[6]=~/\(/;         $targetVGSpaceRemaining=$&#39;;  if($dfContents[2] &lt; $ceilingSize) # Tricky logic time..  {   if($targetVGSpaceRemaining &gt;= ($preserveAmount+$incrementSize))   {    print &quot;MoveCeiling: Less than $ceilingSize MB remaining! Adding $incrementSize MB to $targetFS..\n&quot;;    system(&quot;echo `date` -- MoveCeiling: Less than $ceilingSize MB remaining! Adding $incrementSize MB to $targetFS.. &gt;&gt;/tmp/moveceiling.log&quot;);    `chfs -a size=+&quot;$incrementSize&quot;M $targetFS`;    $incrementCounter++;    if($incrementCounter==$notifyCounter)    {     sendNotification();     $incrementCounter=0;    }   }   else   {    system(&quot;echo `date` -- MoveCeiling: Preserve limit reached. Committing suicide. $targetFS last seen with $dfContents[2] MB free, $targetVGSpaceRemaining MB remaining in $targetG.  &gt;&gt;/tmp/moveceiling.log&quot;);    print &quot;MoveCeiling: Increasing $targetFS by $incrementSize MB would eat into the preserved area! \n&quot;;    print &quot;MoveCeiling: Preparing suicide note to $mailRecipient..\n&quot;;    sendSuicideNote();    print &quot;MoveCeiling: My hands are tied! I&#39;m sorry!\n&quot;;    spinDownRoutine();    exit();   }  }  else  {   print &quot;MoveCeiling: More than $ceilingSize MB remaining..No increase needed.\n&quot;;  }  print &quot;MoveCeiling: $targetVGSpaceRemaining MB remaining in $targetVG. Sleeping for $sleepTime seconds..\n\n&quot;;  sleep($sleepTime); }} sub sendSuicideNote(){        %mail=( To =&gt; $mailRecipient,                From =&gt; $mailSender,                Subject =&gt; &quot;MoveCeiling Suicide Notice&quot;,                Message =&gt; &quot;Preserve limit reached -- Data loss may be imminent. $targetFS last seen with $dfContents[2] MB free, $targetVGSpaceRemaining MB remaining in $targetVG. );                sendmail(%mail); print &quot;MoveCeiling: Suicide note sent.\n&quot;;}sub sendNotification(){ print &quot;MoveCeiling: Sending a friendly reminder to $mailRecipient..\n&quot;; %mail=( To =&gt; $mailRecipient,  From =&gt; $mailSender,  Subject =&gt; &quot;MoveCeiling Update&quot;,  Message =&gt; &quot;$targetFS still growing. Now at $dfContents[2] MB in size with $targetVGSpaceRemaining MB remaining in $targetVG.&quot; );  sendmail(%mail); print &quot;MoveCeiling: Mail sent.\n&quot;;}sub spinDownRoutine(){ print &quot;MoveCeiling: Spinning down..\n\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>MoveCeiling (bpoag)</title>
    <link>http://prlmnks.org/html/555648.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/555648.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl## MoveCeiling v0.2 written 061206:1122 by BJP## MoveCeiling will watch and automatically increase the size of an AIX filesystem# given user-specified parameters.## Usage: moveceiling &lt;ceiling in MB&gt; &lt;filesystem&gt; &lt;increment size&gt; &lt;sleep time&gt; &lt;space to preserve&gt; &lt;notify counter&gt; &lt;email address&gt;# Example: moveceiling 500 /tmp 64 3200 5 foo@bar.com# English: Keep 500MB free in /tmp. If you have to add space, add it in 64MB chunks. Preserve 3200MB in the volume group.#          Remind me every 5 times you have to increase space, and send that reminder to foo@bar.com#use Mail::Sendmail;$ceilingSize=$ARGV[0];$targetFS=$ARGV[1];$incrementSize=$ARGV[2];$sleepTime=$ARGV[3];$preserveAmount=$ARGV[4];$notifyCounter=$ARGV[5];$mailRecipient=$ARGV[6];$mailSender=$ENV{&quot;USER&quot;}.&quot;\@&quot;.&quot;localhost&quot;;if ($#ARGV!=6){        showUsage();        exit();}spinUpRoutine();mainRoutine();spinDownRoutine();sub showUsage(){        print &quot;\n MoveCeiling&#39;s job is to watch a filesystem, and increase it&#39;s size if the\n&quot;;        print &quot; amount of free space in that filesystem falls below threshold. MoveCeiling\n&quot;;        print &quot; is much smarter than it used to be, but you should still use it with caution. \n&quot;;        print &quot;\n&quot;;        print &quot;      Usage: moveceiling &lt;ceiling in MB&gt; &lt;filesystem&gt; &lt;increment size&gt; &lt;sleep time&gt; &lt;space to preserve&gt; &lt;notify counter&gt; &lt;email address&gt;\n&quot;;        print &quot;    Example: moveceiling 500 /tmp 64 30 5 foo\@bar.com\n&quot;;        print &quot; In English: Every 30 seconds, check to see if /tmp has at least 500MB free. \n&quot;;        print &quot;             If it sinks below 500MB, add another 64MB. For every 5 times I \n&quot;;        print &quot;             add more space, i&#39;ll send a status message to foo\@bar.com.\n&quot;;        print &quot;\n\n&quot;;        exit();}sub spinUpRoutine(){        print &quot;\nMoveCeiling: I will make sure $targetFS has at least $ceilingSize MB free.&quot;;        print &quot;\nMoveCeiling: If I have to increase it&#39;s size, I will do so in $incrementSize MB increments.&quot;;        print &quot;\nMoveCeiling: Every $notifyCounter times I do so, i&#39;ll drop a note to $mailRecipient.&quot;;        print &quot;\nMoveCeiling: I&#39;ll stop adding storage if the volume group has less than $preserveAmount MB remaining.&quot;;        print &quot;\nMoveCeiling: Starting up..\n&quot;;        ## Check to see if the filesystem actually exists...        @dfContents=split(/\s+/,`df -m | grep &quot; $targetFS\$&quot;`);        if(length($targetFS)==length($dfContents[6]))        {                print &quot;MoveCeiling: Examining $dfContents[6]..\n&quot;;        }        else        {                print &quot;MoveCeiling: Uh-oh.. Can&#39;t find the filesystem you specified ($targetFS)..!  Exiting.\n\n&quot;;                exit();        }        ## So far so good. Pull up the VG info for this filesystem..        $dfContents[0]=~/\/dev\//;        $targetLV=$&#39;;        @lslvContents=split(/\s+/,`lslv $targetLV|head -n1` );        $targetVG=$lslvContents[5];        print &quot;MoveCeiling: $targetFS belongs to logical volume $targetLV inside $targetVG.\n&quot;;        @lsvgDump=split(/\s+/,`lsvg -L $targetVG | head -n4 | tail -n1`);        $lsvgDump[6]=~/\(/;        $targetVGSpaceRemaining=$&#39;;        print &quot;MoveCeiling: $targetVG has $targetVGSpaceRemaining MB remaining, of which $preserveAmount MB will be preserved.\n\n&quot;;}sub mainRoutine(){        while(true)        {                @dfContents=split(/\s+/,`df -m | grep &quot; $targetFS\$&quot;`);                chomp($dateString=`date`);                print &quot;MoveCeiling: $dfContents[2] MB remaining in $targetFS as of $dateString.\n&quot;;                @lsvgDump=split(/\s+/,`lsvg -L $targetVG | head -n4 | tail -n1`);                $lsvgDump[6]=~/\(/;                $targetVGSpaceRemaining=$&#39;;                if($dfContents[2] &lt; $ceilingSize) # Tricky logic time..                {                        if($targetVGSpaceRemaining &gt;= ($preserveAmount+$incrementSize))                        {                                print &quot;MoveCeiling: Less than $ceilingSize MB remaining! Adding $incrementSize MB to $targetFS..\n&quot;;                                system(&quot;echo `date` -- MoveCeiling: Less than $ceilingSize MB remaining! Adding $incrementSize MB to $targetFS.. &gt;&gt;/tmp/moveceiling.log&quot;);                                `chfs -a size=+&quot;$incrementSize&quot;M $targetFS`;                                $incrementCounter++;                                if($incrementCounter==$notifyCounter)                                {                                        sendNotification();                                        $incrementCounter=0;                                }                        }                        else                        {                                system(&quot;echo `date` -- MoveCeiling: Preserve limit reached. Committing suicide. $targetFS last seen with $dfContents[2] MB free, $targetVGSpaceRemaiing MB remaining in $targetVG.  &gt;&gt;/tmp/moveceiling.log&quot;);                                print &quot;MoveCeiling: Increasing $targetFS by $incrementSize MB would eat into the preserved area! \n&quot;;                                print &quot;MoveCeiling: Preparing suicide note to $mailRecipient..\n&quot;;                                sendSuicideNote();                                print &quot;MoveCeiling: My hands are tied! I&#39;m sorry!\n&quot;;                                spinDownRoutine();                                exit();                        }                }                else                {                        print &quot;MoveCeiling: More than $ceilingSize MB remaining..No increase needed.\n&quot;;                }                print &quot;MoveCeiling: $targetVGSpaceRemaining MB remaining in $targetVG. Sleeping for $sleepTime seconds..\n\n&quot;;                sleep($sleepTime);        }}sub sendSuicideNote(){        %mail=( To =&gt; $mailRecipient,                From =&gt; $mailSender,                Subject =&gt; &quot;MoveCeiling Suicide Notice&quot;,                Message =&gt; &quot;Preserve limit reached -- Data loss may be imminent. $targetFS last seen with $dfContents[2] MB free, $targetVGSpaceRemaining MB remaining in $targetVG. );                sendmail(%mail);        print &quot;MoveCeiling: Suicide note sent.\n&quot;;}sub sendNotification(){        print &quot;MoveCeiling: Sending a friendly reminder to $mailRecipient..\n&quot;;        %mail=( To =&gt; $mailRecipient,                From =&gt; $mailSender,                Subject =&gt; &quot;MoveCeiling Update&quot;,                Message =&gt; &quot;$targetFS still growing. Now at $dfContents[2] MB in size with $targetVGSpaceRemaining MB remaining in $targetVG.&quot; );                sendmail(%mail);        print &quot;MoveCeiling: Mail sent.\n&quot;;}sub spinDownRoutine(){        print &quot;MoveCeiling: Spinning down..\n\n&quot;;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title> (Anonymous Monk)</title>
    <link>http://prlmnks.org/html/555381.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/555381.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;Ook. Ook. Ook.. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook!  Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook.. Ook?. Ook. Ook. Ook. Ook! Ook. Ook? Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook! Ook! Ook! Ook! Ook! O Ook. Ook? Ook. Ook! Ook! Ook? Ook! Ook. Ook? Ook. Ook. Ook. Ook. Ook! Ook Ook. Ook. Ook.. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook! Ook! Ook! Ook! Ook! Ook! Ook Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook? Ook. Ook. Ook? Ook. Ook? Ook. Ook. Ook? Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ooj! Ook! Ook! Ook! Ook. Ook! Ook. Ook. Ook. Ook. Ook. Ook. Ook. Ook! Ook. Ook. Ook? Ook Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook! Ook. Ook. Ook? Ook. Ook. Ook! Ook. Ook. Ook? Ook! Ook.&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Format POD as XHTML with embedded stylesheet (TGI)</title>
    <link>http://prlmnks.org/html/554548.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/554548.html</guid>

    <description>
        &lt;p&gt;Perl source:&lt;/p&gt;&lt;pre class=&quot;block_code&quot;&gt;use warnings;use strict;use Pod::Xhtml;use File::Basename;my $stylesheet = &#39;&#39;;if ( open( STYLE, &#39;&lt;&#39;, &#39;podder.css&#39; ) ) {    $stylesheet = join &#39;&#39;, &lt;STYLE&gt;;} elsif ( defined $PerlApp::VERSION ) {    $stylesheet = PerlApp::get_bound_file(&#39;podder.css&#39;);}my $style = &lt;&lt;&quot;END_XHTML&quot;;&lt;style&gt;$stylesheet&lt;/style&gt;END_XHTMLforeach my $file ( @ARGV ) {    my $base = basename( $file, &#39;.pod&#39;, &#39;.pm&#39;, &#39;.pl&#39;);    my $p = Pod::Xhtml-&gt;new;    $p-&gt;addHeadText( $style );    $p-&gt;parse_from_file( $file, &quot;$base.xhtml&quot; );}&lt;/pre&gt;&lt;p&gt;Here&#39;s the perlapp prject file to generate an executable:&lt;/p&gt;&lt;pre class=&quot;block_code&quot;&gt;PAP-Version: 1.0Packer: C:\Program Files\ActiveState Perl Dev Kit 6.0 Deployment\bin\perlapp.exeBind: podder.css[file=podder.css,text,mode=666]Clean: Exe: podder.exeScript: podder.plShared: none&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Simple Hit Counter (Anonymous Monk)</title>
    <link>http://prlmnks.org/html/552233.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/552233.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl -w#Simple hit counter#To include in a webpage (HTML), put &lt;!--#exec cmd=&quot;PATHTOCGISCRIPT.cgi&quot;--&gt; in the document#Replacing PATHTOCGISCRIPT with the url to the CGI script (this script).#For PHP, within the &lt;?php and ?&gt; tags, include &quot;virtual(&quot;PATHTOCGISCRIPT.cgi&quot;);&quot;#without the quotes.  Also, you need to create#a file named hits.txt for the script to access.  It can#be blank#Script copyright 2006 GreyFox of hacktek.net #VARIABLES$file = &quot;hits.txt&quot;;#READINGopen (COUNT,&quot;&lt;$file&quot;) or die &quot;Counter error 1&quot;;$hits = &lt;COUNT&gt;;close COUNT;#INCREMENTING$hits++;#CONTENTprint &quot;Hits: $hits&quot;;#SAVINGopen (COUNT,&quot;&gt;$file&quot;) or die &quot;Counter error 2&quot;;print COUNT $hits;close COUNT;&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>MakeDVDArchive (HuckinFappy)</title>
    <link>http://prlmnks.org/html/550155.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/550155.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perl=head1 NAMEMakeDVDArchives - A script to create DVD archives and the associated kover files=head1 SYNOPSIS MakeDVDArchives [ -bgcolor &lt;hex color&gt; ] [ -config &lt; filename &gt; ] [ -man ]                 [ -coverdir &lt;directory&gt; ] [ -help ] [ -media &lt;type&gt; ]                 [ -outdir &lt;directory&gt; ] [ -outfile &lt;filename&gt; ]                 [ -srcdir &lt;directory&gt; ] [ -title &lt;line 1&gt; -title &lt;line2&gt; ]   MakeDVDArchives -srcdir /music/dead/shn_1981_project -outfile 81.data \                   -title &#39;Grateful Dead&#39; -title &#39;1981 Archive&#39;=head1 OPTIONS=over=item B&lt;-bgcolor&gt;The hex color code you want the background of your covers to appear as.  The default is #ffffff (white)=item B&lt;-config&gt;If you want to use a config file other than ~/.dvdarchiverc, you can provide the name here=item B&lt;-coverdir&gt;The directory to write the kover files out to.  Defaults to ~/DVDCovers=item B&lt;-help&gt;A brief help message=item B&lt;-man&gt;Complete documentation=item B&lt;-media&gt;One of:  &#39;dvd+r&#39;, &#39;dvd-r&#39;, &#39;dvd+r+dl&#39;, &#39;dvd-r+dl&#39;, depending on what sort of media you are burning to=item B&lt;-outdir&gt;Directory where you want the data about your DVDs written.Defaults to the current working directory=item B&lt;-outfile&gt;The name of the file to store the data to.  Defaults to &#39;dvdarchive.data&#39;=item B&lt;-srcdir&gt;The directory to archive.Defaults to the current working directory=item B&lt;-title&gt;This flag should be used if it is used at all.  The two values are used to define both the kover filenames, as well as the actual titles printed on the kovers.  For example, the default is the equivalent of:   -title DVD -title ArchiveThis would result in filenames like:   DVD_Archive_DVD_1_and_2.koverAnd the title of that cover would read:        DVD      Archive     Disc 1 &amp; 2=back=head1 DESCRIPTIONB&lt;MakeDVDArchives&gt; will read the contents of a large directory, and divide itup into appropriate sized chunks for assorted sizes of DVD media.  It willthen:  1.  Create a datafile describing what is on each DVD  2.  Divide the DVDs into sets of two, for storage in dual jewel cases  3.  Create XML files for each set, for use with the program &#39;kover&#39;      for printing the covers for each set.  The default covers are only      the back insert, including spine text, so no insert for the      front is printed.   4.  Burn the DVDs, prompting you to insert blanks as appropriateThe configuration can be controlled either via the command line, or the~/.dvdarchiverc file.  This is a completely linux-centric program.  It uses growisofs to writethe DVDs, and the files for the covers it creates are for printing via the&#39;kover&#39; program, part of the KDE suite.=head1 DEPENDENCIESThis script requires the following modules which may not be installedin your perl installation:  - Config::Std  - IO::Handle  - IO::Prompt  - Object::InsideOut  - Params::Validate  - Pod::Usage  - Switch  - XML::Simple=head1 CONFIGURATION FILEA lot of the configuration options have to do with controlling the outputto the covers for Kover to print.  I don&#39;t know much about that....I&#39;vewritten out files that work, but some of the config options are a mystery to me.Hopefully everything works fine without this configuration file even existing.But you can cut &amp; paste the following into ~/.dvdarchiverc [Program Defaults] coverdir       = /home/stampes/personalDocuments/DVDCovers #mediatype      = dvd+r outputdir      = /home/stampes/personalDocuments/ArchiveData #outputfile     = dvdarchive.data #sourcedir      = &#39;.&#39; #title          = DVD #title          = Archive [Kover Content] color        = #000000 font         = Monospace fontsettings = Monospace,9,-1,5,50,0,0,0,0,0 italic       = 0 size         = 9 weight       = 50 [Kover General] bgcolor = #ffffff [Kover Inlet] font         = Helvetica fontsettings = helvetica,10,-1,5,50,0,0,0,0,0 italic       = 0 size         = 10 spinetext    = 0 weight       = 75 [Kover Title] color        = #000000 display      = 0 font         = DejaVu Serif fontsettings = DejaVu Serif,20,-1,5,75,0,0,0,0,0 italic       = 0 size         = 20 weight       = 75 [Burn] command      = /usr/bin/growisofs flags        = -dvd-compat -speed=16 -R -J -pad -Z device       = /dev/hdi flagsuffix   = -graft-points=cutMAIN: {   #+-------------------------------------------------------------------------   # Load programming pragmas to keep us honest   #+-------------------------------------------------------------------------   use strict;   use warnings;   #+-------------------------------------------------------------------------   # Define constants   #+-------------------------------------------------------------------------   use constant {      #+---------------------------------------------------------------------      # Defaults for various default values      #+---------------------------------------------------------------------      DEFAULT_CONFIG      =&gt; &quot;$ENV{HOME}/.dvdarchiverc&quot;,      DEFAULT_COVER_DIR   =&gt; &quot;$ENV{HOME}/DVDCovers&quot;,      DEFAULT_MEDIA_TYPE  =&gt; &#39;dvd+r&#39;,      DEFAULT_OUTPUT_FILE =&gt; &#39;dvdarchive.data&#39;,      DEFAULT_OUTPUT_DIR  =&gt; &#39;.&#39;,      DEFAULT_SRC_DIR     =&gt; &#39;.&#39;,      DEFAULT_TITLE       =&gt; [ &#39;DVD&#39;, &#39;Archive&#39; ],      #+---------------------------------------------------------------------      # Constants for media data.  For each type of data define a       # command line string to describe if, and the size of it.  If      # new sizes/names of media are introduced, the switch statement      # which determines capacity based on media type will need an      # addition as well.      #+---------------------------------------------------------------------      DVD_PLUS_R          =&gt; &#39;dvd+r&#39;,      DVD_MINUS_R         =&gt; &#39;dvd-r&#39;,      DVD_PLUS_R_DL       =&gt; &#39;dvd+r+dl&#39;,      DVD_MINUS_R_DL      =&gt; &#39;dvd-r+dl&#39;,      DVD_PLUS_R_SIZE     =&gt; 4700372992,      DVD_PLUS_R_DL_SIZE  =&gt; 8543692390,      # I don&#39;t use these so I didn&#39;t bother looking it up      DVD_MINUS_R_SIZE    =&gt; 0,      DVD_MINUS_R_DL_SIZE =&gt; 0,   };   #+-------------------------------------------------------------------------   # Load needed Modules     #+-------------------------------------------------------------------------   use Config::Std;   use File::Basename;   use Getopt::Long;   use IO::Handle;   use IO::Prompt;   use Pod::Usage;   use Switch &#39;Perl6&#39;;   #+-------------------------------------------------------------------------   # For an application such as this, prefer autoflushed buffers   #+-------------------------------------------------------------------------   *STDOUT-&gt;autoflush();   *STDERR-&gt;autoflush();   #+-------------------------------------------------------------------------   # Non-Command line globals   #+-------------------------------------------------------------------------   my $capacity;   my %argv;   #+-------------------------------------------------------------------------   # Command line globals   #+-------------------------------------------------------------------------   my $bgcolor;   my $configFile = DEFAULT_CONFIG;   my $coverDir;   my $debug = 0;   my $justburn;   my $man;   my $mediaType;   my $help;   my $outputDir;   my $outputFile;   my $srcDir;   my @title;   #+-------------------------------------------------------------------------   # React if no command line options were provided   #+-------------------------------------------------------------------------   pod2usage(&quot;$0: No files given.&quot;)  if (@ARGV == 0);   #+-------------------------------------------------------------------------   # @ARGV gets munged by Getopt::Long, and we want to be able to look later   # to see what options we got on the command line, so build a hash for    # lookup   #+-------------------------------------------------------------------------   for ( @ARGV ) {      if ( $_ =~ /^-/ ) {         $argv{ $_ } = 1;      }   }   #+-------------------------------------------------------------------------   # Parse the command line and print a usage message if needed   #+-------------------------------------------------------------------------   GetOptions( &#39;bgcolor=s&#39;   =&gt; \$bgcolor,               &#39;config=s&#39;    =&gt; \$configFile,               &#39;coverdir=s&#39;  =&gt; \$coverDir,               &#39;debug&#39;       =&gt; \$debug,               &#39;help&#39;        =&gt; \$help,               &#39;justburn&#39;    =&gt; \$justburn,               &#39;man&#39;         =&gt; \$man,               &#39;media=s&#39;     =&gt; \$mediaType,               &#39;outdir=s&#39;    =&gt; \$outputDir,               &#39;outfile=s&#39;   =&gt; \$outputFile,               &#39;srcdir=s&#39;    =&gt; \$srcDir,               &#39;title=s@&#39;    =&gt; \@title, )      or pod2usage( { -message =&gt; &#39;Invalid command line argument.&#39; } );   if ( $help ) {      pod2usage( -message =&gt; &#39;Printing Help Message.&#39;,                 -exitval =&gt; 1, );   }   if ( $man ) {      pod2usage( -message =&gt; &#39;Printing documentation.&#39;,                 -exitval =&gt; 1,                 -verbose =&gt; 2 );   }   #+-------------------------------------------------------------------------   # Load the config file.  Then try to resolve values.  The precedence is:   # - Use the command line value if provided   # - Otherwise the the config file value if provided   # - Otherwise use the default value   #+-------------------------------------------------------------------------   my $rh_config = LoadConfig( { configfile =&gt; $configFile } );   if ( not $argv{ -media } ) {      if ( my $configType = $rh_config-&gt;{&#39;Program Defaults&#39;}-&gt;{ mediatype } ) {         $mediaType = $configType;      } else {         $mediaType = DEFAULT_MEDIA_TYPE;      }   }   if ( not $argv{ -coverdir } ) {      if ( my $configCoverDir =               $rh_config-&gt;{&#39;Program Defaults&#39;}-&gt;{ coverdir } ) {         $coverDir = $configCoverDir;      } else {         $coverDir = DEFAULT_COVER_DIR;      }   }   if ( not $argv{ -outdir } ) {      if ( my $configSaveDir =               $rh_config-&gt;{&#39;Program Defaults&#39;}-&gt;{ outputdir } ) {         $outputDir = $configSaveDir;      } else {         $outputDir = DEFAULT_OUTPUT_DIR;      }   }   if ( not $argv{ -outfile } ) {      if ( my $configSaveFile =               $rh_config-&gt;{&#39;Program Defaults&#39;}-&gt;{ outputfile } ) {         $outputFile = $configSaveFile;      } else {         $outputFile = DEFAULT_OUTPUT_FILE;      }   }   if ( not $argv{ -srcdir } ) {      if (my $configSrcDir = $rh_config-&gt;{&#39;Program Defaults&#39;}-&gt;{ sourcedir }) {         $srcDir = $configSrcDir;      } else {         $srcDir = DEFAULT_SRC_DIR;      }   }   if ( not $argv{ -title } ) {      if ( my $configTitle = $rh_config-&gt;{&#39;Program Defaults&#39;}-&gt;{ title } ) {         @title = @{ $configTitle }      } else {         @title = @{ DEFAULT_TITLE() };      }   }   #+-------------------------------------------------------------------------   # If options impacting the kover data were given, simply modify the   # existing config with the new data for later use   #+-------------------------------------------------------------------------   if ( $bgcolor ) {      $rh_config-&gt;{&#39;Kover General&#39;}-&gt;{ &#39;bgcolor&#39; } = $bgcolor;   }   #+-------------------------------------------------------------------------   # Determine the media capacity for the media to be used   #+-------------------------------------------------------------------------   given ( $mediaType ) {      when ( DVD_PLUS_R )     { $capacity = DVD_PLUS_R_SIZE;     }      when ( DVD_MINUS_R )    { $capacity = DVD_MINUS_R_SIZE;    }      when ( DVD_PLUS_R_DL )  { $capacity = DVD_PLUS_R_DL_SIZE;  }      when ( DVD_MINUS_R_DL ) { $capacity = DVD_MINUS_R_DL_SIZE; }   }   #+-------------------------------------------------------------------------   # Print a message explaining to the user what is about to happen and   # make sure that&#39;s OK with them   #+-------------------------------------------------------------------------   my $printCapacity = sprintf &#39;%2.2f&#39;, $capacity / 1024 / 1024 / 1024;   my $saveAs = &quot;$outputDir/$outputFile&quot;;   my $userMessage = &lt;&lt;&quot;   END_USER_MESSAGE&quot;;   |   |   Here&#39;s what is going to happen now:   |      Directory to archive = $srcDir   |      Media Type           = $mediaType   |      Media Capacity       = $printCapacity GB   END_USER_MESSAGE   unless ( $justburn ) {      $userMessage .= &lt;&lt;&quot;      END_USER_MESSAGE&quot;;      |      Save list of DVDs as = $saveAs      |      Write Cover data to  = $coverDir      |      Title Data is        = $title[0]      |                             $title[1]      |      END_USER_MESSAGE   }   $userMessage =~ s{^.+?\|}{}sgmx;   print $userMessage;   my $prompt = &quot;Continue? ( [Y]es/[N]o ): &quot;;   my $response =       prompt(          $prompt,             &#39;-require&#39; =&gt; {                &quot;Invalid Selection.\n$prompt&quot; =&gt; qr/^[yn]$/i             },            &#39;-one_char&#39; );   print &quot;\n&quot;;   if ( $response =~ /^[Nn]$/ ) { exit; }   #+-------------------------------------------------------------------------   # Get the list of contents of the directory.  This should be made more    # platform-neutral, but I&#39;m too lazy to look up the perl replacement for    # this right now.  Once the list of raw data is aquired, create a set   # of objects representing the entries   #+-------------------------------------------------------------------------   my @read          = `du -sb $srcDir/*/.`;   my @directories   = map { s{/.$}{} } @read;   my $ra_dvdEntries = CreateDVDEntries( { contents =&gt; \@directories } );   #+-------------------------------------------------------------------------   # Divide up the data into appropriately sized chunks and create a set of    # DVD objects representing those chunks   #+-------------------------------------------------------------------------   my $ra_DVDs       = CreateDVDs( { contents =&gt; $ra_dvdEntries,                                      capacity =&gt; $capacity,                                     title    =&gt; \@title } );   unless ( $justburn ) {      #+----------------------------------------------------------------------      # TOFIX:  This is a part that could be more generic.  A &#39;Set&#39; in this      # context is defined as a set of two DVDs.  That&#39;s because I use dual      # cases and want to print appropriate covers for them.  A &#39;Set&#39; should      # become a more generic concept with the user defining the size of the       # set defined by the user      #+----------------------------------------------------------------------      my $ra_Sets       = CreateSets( { dvds =&gt; $ra_DVDs } );      #+----------------------------------------------------------------------      # Write the output file.  This is currently a flat text file, but I have      # hopes it will become a SQLite database or somesuch      #+----------------------------------------------------------------------      WriteData( { dvds   =&gt; $ra_DVDs,                    output =&gt; $saveAs });      #+----------------------------------------------------------------------      # Create the kovers for the KDE program &#39;Kover&#39; to print      #+----------------------------------------------------------------------      CreateKovers( { sets     =&gt; $ra_Sets,                       title    =&gt; \@title,                       coverdir =&gt; $coverDir,                      config   =&gt; $rh_config } );   }   #+-------------------------------------------------------------------------   # Finally, burn all the DVDs   #+-------------------------------------------------------------------------   BurnDVDs( { dvds   =&gt; $ra_DVDs,               config =&gt; $rh_config-&gt;{ Burn },               debug  =&gt; $debug} );}=head1 DEVELOPER DOCUMENTATION OF SUBROUTINESThe following is the documentation for all subroutines in the script=cut#+----------------------------------------------------------------------------# This guarantees a different scope for the main code and the subroutines, # ensuring all variables are properly scoped#+----------------------------------------------------------------------------SUBS:{   #+-------------------------------------------------------------------------   # Default command for burning the DVD   #+-------------------------------------------------------------------------   use constant {      DEFAULT_COMMAND =&gt; &#39;/usr/bin/growisofs&#39;,      DEFAULT_DEVICE  =&gt; &#39;/dev/dvd&#39;,      DEFAULT_FLAGS   =&gt; &#39;-dvd-compat -speed=16 -R -J -pad -Z&#39;,      DEFAULT_SUFFIX  =&gt; &#39;-graft-points&#39;,   };   use strict;   use warnings;   use Params::Validate qw( :all );#---------------------------------------------------------------------------#  Documentation for CreateDVDEntries()#---------------------------------------------------------------------------=head1 B&lt;CreateDVDEntries( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;contents&gt;An array that&#39;s the output from du -b=back=item I&lt;Return values&gt;=over=item B&lt;array ref&gt;a reference to an array of DVD::Entry objects=back=item I&lt;Description&gt;Takes an array ref containing the contents of the directory and the sizeof each item, and creates an array of DVD::Entry objects representing thosecontents=back=cut#---------------------------------------------------------------------------#  End of Documentation for CreateDVDEntries()#---------------------------------------------------------------------------   sub CreateDVDEntries {      validate( @_, { contents =&gt;                        { optional  =&gt; 0,                         type      =&gt; ARRAYREF },                    } );      my $rh_args = $_[0];      my $ra_data = $rh_args-&gt;{ contents };      my @dvdEntries;      for my $entry ( @{ $ra_data } ) {         chomp $entry;         next unless ( $entry );         my ( $size, $source ) = split /\s+/, $entry;         my $name = basename $source;         push @dvdEntries, DVD::Entry-&gt;new( name   =&gt; $name,                                            size   =&gt; $size,                                            source =&gt; $source );      }      return \@dvdEntries;   }#---------------------------------------------------------------------------#  Documentation for CreateDVDs()#---------------------------------------------------------------------------=head1 B&lt;CreateDVDs( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;contents&gt;A ref to an array of DVD::Entry objects=item B&lt;capacity&gt;The size of the media being used, in bytes=item B&lt;title&gt;A ref to a 2-element array representing the title for the DVDs=back=item I&lt;Return values&gt;=over=item B&lt;array ref&gt;a reference to an array of DVD objects=back=item I&lt;Description&gt;Given a set of DVD::Entry objects and the known capacity of the media,creates a set of DVD objects representing what will be stored on eachDVD and the title of it=back=cut#---------------------------------------------------------------------------#  End of Documentation for CreateDVDs()#---------------------------------------------------------------------------   sub CreateDVDs {      validate( @_, { contents =&gt;                        { optional  =&gt; 0,                         type      =&gt; ARRAYREF,                         { &#39;Contains DVD::Entry objects&#39; =&gt;                              sub {                                  for ( @{ $_[0] } ) {                                    unless ( $_-&gt;isa( &#39;DVD::Entry&#39; ) ) {                                       return 0;                                    }                                 }                                 return 1;                              },                         }                      },                      capacity =&gt;                        { optional =&gt; 0 },                      title    =&gt;                       { optional =&gt; 0,                         type     =&gt; ARRAYREF },                    } );      my $rh_args      = $_[0];      my $ra_contents  = $rh_args-&gt;{ contents };      my $capacity     = $rh_args-&gt;{ capacity };      my $ra_TitleText = $rh_args-&gt;{ title };      my $ContentsMax = $#{ $ra_contents };      my @DVDs;      my $id = 1;      my $index = 0;      my $currentDVD;      my $track = 1;      while ( $index &lt;= $ContentsMax ) {         my $dir      = $ra_contents-&gt;[ $index ];         my $dirSize  = $dir-&gt;GetSize();         my $dvdSize  = $currentDVD ? $currentDVD-&gt;GetSize() : 0;         if ( $dvdSize + $dirSize &lt; $capacity ) {            $dir-&gt;SetNumber( $track++ );            unless ( $currentDVD ) {               my $currentTitle = join &#39; &#39;, @{ $ra_TitleText }, &quot;DVD #$id&quot;;               $currentDVD = DVD-&gt;new( id    =&gt; $id++,                                       title =&gt; $currentTitle );            }            $currentDVD-&gt;AddContent( $dir );            $index++;            next;         } else {            push @DVDs, $currentDVD;            $currentDVD = undef;            $track = 1;         }      }      if ( $currentDVD ) {           push @DVDs, $currentDVD;      }      return \@DVDs;   }#---------------------------------------------------------------------------#  Documentation for CreateSets()#---------------------------------------------------------------------------=head1 B&lt;CreateSets( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;dvds&gt;A ref to an array of DVD objects=back=item I&lt;Return values&gt;=over=item B&lt;array ref&gt;a reference to an array of DVD::Set objects=back=item I&lt;Description&gt;Given a set of DVD objects, creates a set of DVD::Set objects representingthe two DVDs going into a set, for packaging in dual jewel cases=back=cut#---------------------------------------------------------------------------#  End of Documentation for CreateSets()#---------------------------------------------------------------------------   sub CreateSets {      validate( @_, { dvds =&gt;                        { optional  =&gt; 0,                         type      =&gt; ARRAYREF,                         callbacks =&gt;                           { &#39;Contains DVD objects&#39; =&gt;                              sub {                                  for ( @{ $_[0] } ) {                                    unless ( $_-&gt;isa( &#39;DVD&#39; ) ) {                                       return 0;                                    }                                 }                                 return 1;                              },                         }                       }                    } );      my $rh_args  = $_[0];      my $ra_DVDs  = $rh_args-&gt;{ dvds };      my @sets;      my ( $start, $end ) = ( 0, 1 );      while ( $start &lt;= $#{ $ra_DVDs } ) {         my $dvd1 = $ra_DVDs-&gt;[ $start ];         my $dvd2 = $ra_DVDs-&gt;[ $end ] || undef;         $start += 2;         $end   += 2;         my $contents = $dvd2 ? [ $dvd1, $dvd2 ] : [ $dvd1 ];         my $set = DVD::Set-&gt;new( dvds  =&gt; $contents );         push @sets, $set;         if ( not $dvd2 ) {            last;         }      }      return \@sets;   }#---------------------------------------------------------------------------#  Documentation for LoadConfig()#---------------------------------------------------------------------------=head1 B&lt;LoadConfig( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;configfile&gt;Absolute path of the config file to load=back=item I&lt;Return values&gt;=over=item B&lt;hash ref&gt;a reference to a hash representing the config=back=item I&lt;Description&gt;Load the config file=back=cut#---------------------------------------------------------------------------#  End of Documentation for LoadConfig()#---------------------------------------------------------------------------   sub LoadConfig {      my ( $rh_args ) = ( @_ );      my  $configFile = $rh_args-&gt;{ configfile };      my $error = 0;      if ( not -e $configFile ) {         warn &quot;$configFile does not exist.\n&quot;;         $error = 1;      } elsif ( not -r $configFile ) {         warn &quot;$configFile not readable.\n&quot;;         $error = 1;      }      my %config;      eval {          read_config $configFile =&gt; %config;      };      if ( $@ ) {         warn &quot;Exception occured reading $configFile: $@\n&quot;;         $error = 1;      }      if ( $error ) {         my $prompt = &quot;Continue with default values? ( [Y]es/[N]o ): &quot;;         my $response =             prompt(                $prompt,                   &#39;-require&#39; =&gt; {                      &quot;Invalid Selection.\n$prompt&quot; =&gt; qr/^[yn]$/i                   },                  &#39;-one_char&#39; );         print &quot;\n&quot;;         if ( $response =~ /^[Nn]$/ ) { exit; }         %config = ();      }      return \%config;   }#---------------------------------------------------------------------------#  Documentation for WriteData()#---------------------------------------------------------------------------=head1 B&lt;WriteData( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;dvds&gt;Reference to an array of DVD objects=item B&lt;output&gt;File to write the data to=back=item I&lt;Description&gt;Writes out a simple text file of what is on each DVD=back=cut#---------------------------------------------------------------------------#  End of Documentation for WriteData()#---------------------------------------------------------------------------   sub WriteData {      validate( @_, { dvds =&gt;                        { optional  =&gt; 0,                         type      =&gt; ARRAYREF,                         callbacks =&gt;                           { &#39;Contains DVD objects&#39; =&gt;                              sub {                                  for ( @{ $_[0] } ) {                                    unless ( $_-&gt;isa( &#39;DVD&#39; ) ) {                                       return 0;                                    }                                 }                                 return 1;                              },                         }                       },                      output =&gt; { optional =&gt; 0 },                     } );      my ( $rh_args ) = ( @_ );      my $ra_DVDs = $rh_args-&gt;{ dvds };      my $outfile = $rh_args-&gt;{ output };      open OUT, &#39;&gt;&#39;, $outfile or die $!;      for my $dvd ( @{ $ra_DVDs } ) {         my $size = $dvd-&gt;GetSize();         $size = $size / 1024 / 1024 / 1024;         printf OUT &quot;\nDVD ID: %2d\n&quot;, $dvd-&gt;GetID();         printf OUT &quot;DVD Size: %4.2f GB\n&quot;, $size;         print OUT &quot;================\n&quot;;         for my $dir ( @{ $dvd-&gt;GetContents() } ) {            my $dirSize = $dir-&gt;GetSize() / 1024 / 1024;            my $sizeTemplate = &#39;%4d&#39;;            my $unit = &#39;MB&#39;;            if ( $dirSize &gt; 1024 ) {               $dirSize = $dirSize / 1024;               $unit = &#39;GB&#39;;               $sizeTemplate = &#39;%2.2f&#39;;            }            printf OUT &quot;\t%2d. %-60s =&gt; $sizeTemplate %2s\n&quot;,                        $dir-&gt;GetNumber(), $dir-&gt;GetName(), $dirSize, $unit;         }      }   }#---------------------------------------------------------------------------#  Documentation for BurnDVDs()#---------------------------------------------------------------------------=head1 B&lt;BurnDVDs( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;dvds&gt;Reference to an array of DVD objects=item B&lt;config&gt;Reference to a hash representing the config=item B&lt;debug&gt;Optional flag to get some debug output=back=item I&lt;Description&gt;Using the commands in the config, burn the DVDs and prompt for user to insert blank media between them=back=cut#---------------------------------------------------------------------------#  End of Documentation for BurnDVDs()#---------------------------------------------------------------------------   sub BurnDVDs {      validate( @_, { dvds =&gt;                        { optional  =&gt; 0,                         type      =&gt; ARRAYREF,                         callbacks =&gt;                           { &#39;Contains DVD objects&#39; =&gt;                              sub {                                  for ( @{ $_[0] } ) {                                    unless ( $_-&gt;isa( &#39;DVD&#39; ) ) {                                       return 0;                                    }                                 }                                 return 1;                              },                         }                       },                      config =&gt; { optional =&gt; 0 },                       debug  =&gt; { optional =&gt; 1 },                     } );      my ( $rh_args ) = ( @_ );      my $ra_DVDs = $rh_args-&gt;{ dvds };      my $config  = $rh_args-&gt;{ config };      my $debug   = $rh_args-&gt;{ debug };      my $command        = $config-&gt;{ command }    || DEFAULT_COMMAND;      my $dvdDevice      = $config-&gt;{ device }     || DEFAULT_DEVICE;      my $flags          = $config-&gt;{ flags }      || DEFAULT_FLAGS;      my $suffix         = $config-&gt;{ flagsuffix } || DEFAULT_SUFFIX;      for my $dvd ( @{ $ra_DVDs } ) {         my $fullcommand = &quot;$command $flags $dvdDevice $suffix &quot;;         my $title = $dvd-&gt;GetTitle();         my $id    = $dvd-&gt;GetID();         for my $entry ( @{ $dvd-&gt;GetContents() } ) {            my $name = $entry-&gt;GetName();            my $src  = $entry-&gt;GetSource();            $fullcommand .= qq{&quot;/$name=$src&quot; };         }         print &quot;Ready to burn $title\n&quot;;         my $prompt = &quot;Select one of the following: [s]kip, [b]urn, [q]uit: &quot;;         my $response =             prompt(                $prompt,                   &#39;-require&#39; =&gt; {                      &quot;Invalid Selection.\n$prompt&quot; =&gt; qr/^[sbq]$/                   },                  &#39;-one_char&#39; );         print &quot;\n&quot;;         if ( $response eq &#39;q&#39; ) { exit; }         if ( $response eq &#39;s&#39; ) { next; }         prompt( &quot;Insert blank DVD for $title and press &lt;RETURN&gt;: &quot; );         print &quot;Preparing to burn DVD...please wait...\n&quot;;         open BURN, &quot;$fullcommand 2&gt;&amp;1 |&quot; or die $!;         while ( &lt;BURN&gt; ) {            chomp;            if ( $debug ) {               print &quot;$_\n&quot;;            } elsif ( /estimate finish/ ) {               print;               print &quot;\cH&quot; x length $_;               next;            } elsif ( /flushing cache/ ) {               print &quot;\nFlushing Cache and Closing DVD...please wait...&quot;;            } elsif ( /^:.+(?:error|failed)/ ) {               print &quot;$_\n&quot;;            }         }         close BURN;         print &quot;\nCompleted Burning $title\n&quot;;         system &quot;eject $dvdDevice&quot;;      }   }#---------------------------------------------------------------------------#  Documentation for CreateKovers()#---------------------------------------------------------------------------=head1 B&lt;CreateKovers( )&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;sets&gt;Reference to an array of DVD::Set objects=item B&lt;config&gt;Reference to a hash representing the config=item B&lt;coverdir&gt;Where to write the Kover files=item B&lt;title&gt;Reference to a two element array representing the config=item B&lt;debug&gt;Optional flag to get some debug output=back=item I&lt;Description&gt;Using the commands in the config, burn the DVDs and prompt for user to insert blank media between them=back=cut#---------------------------------------------------------------------------#  End of Documentation for BurnDVDs()#---------------------------------------------------------------------------   sub CreateKovers {      validate( @_, { sets =&gt;                        { optional  =&gt; 0,                         type      =&gt; ARRAYREF,                         callbacks =&gt;                           { &#39;Contains DVD::Set objects&#39; =&gt;                              sub {                                  for ( @{ $_[0] } ) {                                    unless ( $_-&gt;isa( &#39;DVD::Set&#39; ) ) {                                       return 0;                                    }                                 }                                 return 1;                              },                         }                      },                      coverdir =&gt;                        { optional =&gt; 0 },                      title    =&gt;                       { optional =&gt; 0,                         type     =&gt; ARRAYREF },                      config    =&gt;                       { optional =&gt; 0,                         type     =&gt; HASHREF },                    } );      my ( $rh_args ) = ( @_ );      my $ra_Sets        = $rh_args-&gt;{ sets };      my $ra_TitleText   = $rh_args-&gt;{ title };      my $coverDirectory = $rh_args-&gt;{ coverdir };      my $rh_config      = $rh_args-&gt;{ config };      my $generalSection =          DVD::Kover::General-&gt;new( config =&gt; $rh_config-&gt;{ &#39;Kover General&#39; } );      my $imgSection = DVD::Kover::Images-&gt;new( );      my $inlet =          DVD::Kover::Inlet-&gt;new( config =&gt; $rh_config-&gt;{ &#39;Kover Inlet&#39; } );      for my $set ( @{ $ra_Sets } ) {         my @currentTitle = @{ $ra_TitleText };         my ( $dvd1,$dvd2 ) =  @{ $set-&gt;GetDVDs() };         my $discs  = &quot;DVD &quot;.$dvd1-&gt;GetID();         if ( $dvd2 ) {            $discs .= &#39; &amp; &#39;.$dvd2-&gt;GetID();         }         push @currentTitle, $discs;         my $titleSection =             DVD::Kover::Title-&gt;new( config =&gt; $rh_config-&gt;{ &#39;Kover Title&#39; },                                    text   =&gt; \@currentTitle );         my $file = join &quot;_&quot;, @currentTitle;         $file =~ s/[ ]/_/g;         $file =~ s/[&amp;]/and/;         $file .= &#39;.kover&#39;;         my $ra_Content = [ {}, {},                            &#39;Disc &#39;.$dvd1-&gt;GetID().&#39;:&#39; ];         for my $dir ( @{ $dvd1-&gt;GetContents } ) {           push @{ $ra_Content }, $dir-&gt;GetNumber().&#39;. &#39;.$dir-&gt;GetName();         }         if ( $dvd2 ) {            push @{ $ra_Content }, {};            push @{ $ra_Content }, &#39;Disc &#39;.$dvd2-&gt;GetID().&#39;:&#39;;            for  my $dir ( @{ $dvd2-&gt;GetContents } ) {              push @{ $ra_Content }, $dir-&gt;GetNumber().&#39;. &#39;.$dir-&gt;GetName();            }         }         my $content =             DVD::Kover::Content-&gt;new( text   =&gt; $ra_Content,                                      config =&gt; $rh_config-&gt;{&#39;Kover Content&#39;});         my $kover   = DVD::Kover-&gt;new( title   =&gt; $titleSection,                                        config  =&gt; $rh_config,                                        content =&gt; $content,                                        general =&gt; $generalSection,                                        images  =&gt;  $imgSection,                                        inlet   =&gt;  $inlet );         print &quot;Creating $file\n&quot;;         open OUT, &#39;&gt;&#39;, &quot;$coverDirectory/$file&quot; or die $!;         print OUT $kover-&gt;GetXML();      }   }}=head1 DOCUMENTATION FOR CLASSES The following is the documentation for all classes defined for usein this script.All classes are designed using Object::InsideOut.  In most cases, there areno interesting methods on the classes, they are just data containers.  Assuch, I am documenting the contructors only, and in rare cases the othermore interesting methods.  All attributes have accessors/mutators using thefollowing naming convention (see Object::InsideOut for details):  constructor attribute    |  Accessor   | Mutator  ===================================================          name             |  GetName()  | SetName()=cutBEGIN {#---------------------------------------------------------------------------#  Documentation for DVD::Entry#---------------------------------------------------------------------------=head1 B&lt;DVD::Entry&gt;=head2 B&lt;new()&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;number&gt;The track number on the DVD=item B&lt;name&gt;The name of the entry=item B&lt;size&gt;The size of the entry=item B&lt;source&gt;The absolute path to the source=back=item I&lt;Description&gt;Contructs a DVD::ENtry object representing one item (file or subdirectory)on the DVD=back=cut#---------------------------------------------------------------------------#  End of Documentation for DVD::Entry#---------------------------------------------------------------------------   package DVD::Entry;   {      use strict;      use warnings;      use Object::InsideOut;      my @trackNumber :Field( Get =&gt; &#39;GetNumber&#39;, Set =&gt; &#39;SetNumber&#39; );      my @name        :Field( Get =&gt; &#39;GetName&#39;,   Set =&gt; &#39;SetName&#39; );      my @size        :Field( Get =&gt; &#39;GetSize&#39;,   Set =&gt; &#39;SetSize&#39; );      my @srcPath     :Field( Get =&gt; &#39;GetSource&#39;, Set =&gt; &#39;SetSource&#39; );      my %initArgs :InitArgs = (         track  =&gt; {            Type      =&gt; &#39;Numeric&#39;,            Field     =&gt; \@trackNumber },         name   =&gt; {            Field     =&gt; \@name },         size   =&gt; {            Field     =&gt; \@size },         source =&gt; {            Field     =&gt; \@srcPath }      );   }#---------------------------------------------------------------------------#  Documentation for DVD#---------------------------------------------------------------------------=head1 B&lt;DVD&gt;=head2 B&lt;new()&gt;=over=item I&lt;Parameters&gt;=over=item B&lt;id&gt;An ID number to identify this DVD=item B&lt;contents&gt;A reference to an array of DBD::Entry objects=item B&lt;size&gt;The size of the DVD Data=item B&lt;title&gt;A two element array reference to be used as the title=back=item I&lt;Description&gt;Contructs a DVD::Entry object representing one item (file or subdirectory)on the DVD=back=cut#---------------------------------------------------------------------------#  End of Documentation for DVD#---------------------------------------------------------------------------   package DVD;   {      use strict;      use warnings;      use Object::InsideOut;      my @id       :Field( Get =&gt; &#39;GetID&#39;,       Set =&gt; &#39;SetID&#39; );      my @contents :Field( Get =&gt; &#39;GetContents&#39;, Set =&gt; &#39;SetContents&#39; );      my @size     :Field( Get =&gt; &#39;GetSize&#39;,     Set =&gt; &#39;SetSize&#39; );      my @title    :Field( Get =&gt; &#39;GetTitle&#39;,    Set =&gt; &#39;SetTitle&#39; );      my %initArgs :InitArgs = (         id       =&gt; {            Type      =&gt; &#39;Numeric&#39;,            Field     =&gt; \@id          },         contents =&gt; {            Type      =&gt; &#39;LIST&#39;,            Field     =&gt; \@contents,            Default   =&gt; [ ]          },         size     =&gt; {            Type      =&gt; &#39;Numeric&#39;,            Field     =&gt; \@size,            Default   =&gt; 0          },         title    =&gt; {            Field     =&gt; \@title,         },      );      sub AddContent {         my ( $self, $content ) = @_;         push @{ $self-&gt;GetContents }, $content;         $self-&gt;SetSize( $self-&gt;GetSize() + $content-&gt;GetSize() );      }   }   package DVD::Set;   {      use strict;      use warnings;      use Object::InsideOut;      my @dvds     :Field( Get =&gt; &#39;GetDVDs&#39;,  Set =&gt; &#39;SetDVDs&#39; );      my @title    :Field( Get =&gt; &#39;GetTitle&#39;, Set =&gt; &#39;SetTitle&#39; );      my %initArgs :InitArgs = (         dvds  =&gt; {            Type  =&gt; &#39;LIST&#39;,            Field =&gt; \@dvds }      );      sub AddDVD {         my ( $self, $dvd ) = @_;         push @{ $self-&gt;GetDVDs() }, $dvd;      }   }   package DVD::Kover;   {      use strict;      use warnings;      use Object::InsideOut;      use XML::Simple;      my @content :Field( Get =&gt; &#39;GetContent&#39;, Set =&gt; &#39;SetContent&#39; );      my @general :Field( Get =&gt; &#39;GetGeneral&#39;, Set =&gt; &#39;SetGeneral&#39; );      my @images  :Field( Get =&gt; &#39;GetImages&#39;,  Set =&gt; &#39;SetImages&#39; );      my @inlet   :Field( Get =&gt; &#39;GetInlet&#39;,   Set =&gt; &#39;SetInlet&#39; );      my @name    :Field( Get =&gt; &#39;GetName&#39;,    Set =&gt; &#39;SetName&#39; );      my @title   :Field( Get =&gt; &#39;GetTitle&#39;,   Set =&gt; &#39;SetTitle&#39; );      my @version :Field( Get =&gt; &#39;GetVersion&#39;, Set =&gt; &#39;SetVersion&#39; );      my %initArgs :InitArgs = (         content =&gt; {            Field   =&gt; \@content,            Type    =&gt; &#39;DVD::Kover::Content&#39;,         },         general =&gt; {            Field   =&gt; \@general,            Type    =&gt; &#39;DVD::Kover::General&#39;,         },         images  =&gt; {            Field   =&gt; \@images,            Type    =&gt; &#39;DVD::Kover::Images&#39;,         },         inlet   =&gt; {            Field   =&gt; \@inlet,            Type    =&gt; &#39;DVD::Kover::Inlet&#39;,         },         name    =&gt; {            Field   =&gt; \@name,            Default =&gt; &#39;kover&#39;,         },         title   =&gt; {             Field   =&gt; \@title,            Type    =&gt; &#39;DVD::Kover::Title&#39;,         },         version =&gt; {            Field   =&gt; \@version,            Default =&gt; &#39;2.9.6&#39;         },      );      sub GetAll {         my ( $self ) = @_;         return { content =&gt; $self-&gt;GetContent()-&gt;GetAll(),                  general =&gt; $self-&gt;GetGeneral()-&gt;GetAll(),                  img     =&gt; $self-&gt;GetImages()-&gt;GetAll(),                  inlet   =&gt; $self-&gt;GetInlet()-&gt;GetAll(),                  name    =&gt; $self-&gt;GetName(),                  title   =&gt; $self-&gt;GetTitle()-&gt;GetAll(),                  version =&gt; $self-&gt;GetVersion() };      }      sub GetXML {         my ( $self ) = @_;         return XMLout( $self-&gt;GetAll() );      }   }   package DVD::Kover::Content;   {      use constant {         DEFAULT_COLOR         =&gt; &#39;#000000&#39;,         DEFAULT_FONT          =&gt; &#39;Monospace&#39;,         DEFAULT_FONT_SETTINGS =&gt; &#39;Monospace,9,-1,5,50,0,0,0,0,0&#39;,         DEFAULT_ITALIC        =&gt; 0,         DEFAULT_SIZE          =&gt; 9,         DEFAULT_WEIGHT        =&gt; 50,      };      use strict;      use warnings;      use Object::InsideOut;      my @color        :Field( Get =&gt; &#39;GetColor&#39;,        Set =&gt; &#39;SetColor&#39; );      my @config       :Field( Get =&gt; &#39;GetConfig&#39;,       Set =&gt; &#39;SetConfig&#39; );      my @font         :Field( Get =&gt; &#39;GetFont&#39;,         Set =&gt; &#39;SetFont&#39; );      my @fontSettings :Field( Get =&gt; &#39;GetFontSettings&#39;, Set =&gt; &#39;SetFontSettings&#39; );      my @italic       :Field( Get =&gt; &#39;GetItalic&#39;,       Set =&gt; &#39;SetItalic&#39; );      my @size         :Field( Get =&gt; &#39;GetSize&#39;,         Set =&gt; &#39;SetSize&#39; );      my @text         :Field( Get =&gt; &#39;GetText&#39;,         Set =&gt; &#39;SetText&#39; );      my @weight       :Field( Get =&gt; &#39;GetWeight&#39;,       Set =&gt; &#39;SetWeight&#39; );      my %initArgs :InitArgs = (         text =&gt; {            Field   =&gt; \@text,            Default =&gt; [ ],            Type    =&gt; &#39;LIST&#39;,         },      );      sub _Init :Init {         my ( $self, $args ) = @_;         my $config = $args-&gt;{ config };         $self-&gt;SetConfig( $config );         if ( my $color = $config-&gt;{ color } ) {            $self-&gt;SetColor( $color );         } else {            $self-&gt;SetColor( DEFAULT_COLOR );         }         if ( my $font = $config-&gt;{ font} ) {            $self-&gt;SetFont( $font );         } else {            $self-&gt;SetFont( DEFAULT_FONT );         }         if ( my $fontsettings = $config-&gt;{ fontsettings } ) {            $self-&gt;SetFontSettings( $fontsettings );         } else {            $self-&gt;SetFontSettings( DEFAULT_FONT_SETTINGS );         }         if ( my $italic = $config-&gt;{ italic } ) {            $self-&gt;SetItalic( $italic );         } else {            $self-&gt;SetItalic( DEFAULT_ITALIC );         }         if ( my $size = $config-&gt;{ size } ) {            $self-&gt;SetSize( $size );         } else {            $self-&gt;SetSize( DEFAULT_SIZE );         }         if ( my $weight = $config-&gt;{ weight } ) {            $self-&gt;SetWeight( $weight );         } else {            $self-&gt;SetWeight( DEFAULT_WEIGHT );         }      }      sub GetAll {         my ( $self ) = @_;         return { color         =&gt; $self-&gt;GetColor(),                  font          =&gt; $self-&gt;GetFont(),                  font_settings =&gt; $self-&gt;GetFontSettings(),                  italic        =&gt; $self-&gt;GetItalic(),                  size          =&gt; $self-&gt;GetSize(),                  text          =&gt; $self-&gt;GetText(),                  weight        =&gt; $self-&gt;GetWeight() };      }   }   package DVD::Kover::General;   {      use strict;      use warnings;      use constant {         DEFAULT_BG_COLOR =&gt; &#39;#ffffff&#39;,         DEFAULT_CDDB_ID  =&gt; &#39;&#39;,         DEFAULT_NUMBER   =&gt; 0,      };      use Object::InsideOut;      my @bgColor :Field( Get =&gt; &#39;GetBGColor&#39;, Set =&gt; &#39;SetBGColor&#39; );      my @config  :Field( Get =&gt; &#39;GetConfig&#39;,  Set =&gt; &#39;SetConfig&#39; );      my @CDDBid  :Field( Get =&gt; &#39;GetCDDBid&#39;,  Set =&gt; &#39;SetCDDBid&#39; );      my @number  :Field( Get =&gt; &#39;GetNumber&#39;,  Set =&gt; &#39;SetNumber&#39; );      sub _Init :Init {         my ( $self, $args ) = @_;         my $config = $args-&gt;{ config };         $self-&gt;SetConfig( $config );         if ( my $bgcolor = $config-&gt;{ bgcolor } ) {            $self-&gt;SetBGColor( $bgcolor );         } else {            $self-&gt;SetBGColor( DEFAULT_BG_COLOR );         }         if ( my $cddbID = $config-&gt;{ cddb_id } ) {            $self-&gt;SetCDDBid( $cddbID );         } else {            $self-&gt;SetCDDBid( DEFAULT_CDDB_ID );         }         if ( my $number = $config-&gt;{ number } ) {            $self-&gt;SetNumber( $number );         } else {            $self-&gt;SetNumber( DEFAULT_CDDB_ID );         }      }      sub GetAll {         my ( $self ) = @_;         return { bgcolor =&gt; $self-&gt;GetBGColor(),                  cddb_id =&gt; $self-&gt;GetCDDBid(),                  number  =&gt; $self-&gt;GetNumber() };      }   }   package DVD::Kover::Images;   {      use strict;      use warnings;      use Object::InsideOut;      my @images :Field( Get =&gt; &#39;GetImages&#39;, Set =&gt; &#39;SetImages&#39; );      my %initArgs :InitArgs = (         img =&gt; {            Field   =&gt; \@images,            Default =&gt; [ { mode   =&gt; 0,                           src    =&gt; &#39;&#39;,                           target =&gt; 0 },                         { mode   =&gt; 0,                           src    =&gt; &#39;&#39;,                           target =&gt; 0 },                         { mode   =&gt; 0,                           src    =&gt; &#39;&#39;,                           target =&gt; 0 },                       ],            Type    =&gt; &#39;LIST&#39;         }      );      sub GetAll {         my ( $self ) = @_;         return $self-&gt;GetImages();      }   }   package DVD::Kover::Inlet;   {      use strict;      use warnings;      use constant {         DEFAULT_FONT          =&gt; &#39;Helvetica&#39;,         DEFAULT_FONT_SETTINGS =&gt; &#39;helvetica,10,-1,5,50,0,0,0,0,0&#39;,         DEFAULT_ITALIC        =&gt; 0,         DEFAULT_SIZE          =&gt; 10,         DEFAULT_SPINE_TEXT    =&gt; 0,         DEFAULT_WEIGHT        =&gt; 75,      };      use Object::InsideOut;      my @config      :Field( Get =&gt; &#39;GetConfig&#39;,       Set =&gt; &#39;SetConfig&#39; );      my @font        :Field( Get =&gt; &#39;GetFont&#39;,         Set =&gt; &#39;SetFont&#39; );      my @fontSettings :Field( Get =&gt; &#39;GetFontSettings&#39;, Set =&gt; &#39;SetFontSettings&#39; );      my @italic      :Field( Get =&gt; &#39;GetItalic&#39;,       Set =&gt; &#39;SetItalic&#39; );      my @size        :Field( Get =&gt; &#39;GetSize&#39;,         Set =&gt; &#39;SetSize&#39; );      my @spineText   :Field( Get =&gt; &#39;GetSpineText&#39;,    Set =&gt; &#39;SetSpineText&#39; );      my @weight      :Field( Get =&gt; &#39;GetWeight&#39;,       Set =&gt; &#39;SetWeight&#39; );      my %initArgs :InitArgs = (         spinetext =&gt; {            Default =&gt; 0,            Field   =&gt; \@spineText,         },      );      sub _Init :Init {         my ( $self, $args ) = @_;         my $config = $args-&gt;{ config };         $self-&gt;SetConfig( $config );         if ( my $font = $config-&gt;{ font} ) {            $self-&gt;SetFont( $font );         } else {            $self-&gt;SetFont( DEFAULT_FONT );         }         if ( my $fontsettings = $config-&gt;{ fontsettings } ) {            $self-&gt;SetFontSettings( $fontsettings );         } else {            $self-&gt;SetFontSettings( DEFAULT_FONT_SETTINGS );         }         if ( my $italic = $config-&gt;{ italic } ) {            $self-&gt;SetItalic( $italic );         } else {            $self-&gt;SetItalic( DEFAULT_ITALIC );         }         if ( my $size = $config-&gt;{ size } ) {            $self-&gt;SetSize( $size );         } else {            $self-&gt;SetSize( DEFAULT_SIZE );         }         if ( my $weight = $config-&gt;{ weight } ) {            $self-&gt;SetWeight( $weight );         } else {            $self-&gt;SetWeight( DEFAULT_WEIGHT );         }      }      sub GetAll {         my ( $self ) = @_;         return {                  font          =&gt; $self-&gt;GetFont(),                  font_settings =&gt; $self-&gt;GetFontSettings(),                  italic        =&gt; $self-&gt;GetItalic(),                  size          =&gt; $self-&gt;GetSize(),                  spine_text    =&gt; $self-&gt;GetSpineText(),                  weight        =&gt; $self-&gt;GetWeight() };      }   }   package DVD::Kover::Title;   {      use strict;      use warnings;      use constant {         DEFAULT_COLOR         =&gt; &#39;#000000&#39;,         DEFAULT_DISPLAY       =&gt; 0,         DEFAULT_FONT          =&gt; &#39;DejaVu Serif&#39;,         DEFAULT_FONT_SETTINGS =&gt; &#39;DejaVu Serif,20,-1,5,75,0,0,0,0,0&#39;,         DEFAULT_ITALIC        =&gt; 0,         DEFAULT_SIZE          =&gt; 20,         DEFAULT_WEIGHT        =&gt; 75,      };      use Object::InsideOut;      my @color        :Field( Get =&gt; &#39;GetColor&#39;,        Set =&gt; &#39;SetColor&#39; );      my @config       :Field( Get =&gt; &#39;GetConfig&#39;,       Set =&gt; &#39;SetConfig&#39; );      my @display      :Field( Get =&gt; &#39;GetDisplay&#39;,      Set =&gt; &#39;SetDisplay&#39; );      my @font         :Field( Get =&gt; &#39;GetFont&#39;,         Set =&gt; &#39;SetFont&#39; );      my @fontSettings :Field( Get =&gt; &#39;GetFontSettings&#39;, Set =&gt; &#39;SetFontSettings&#39; );      my @italic       :Field( Get =&gt; &#39;GetItalic&#39;,       Set =&gt; &#39;SetItalic&#39; );      my @size         :Field( Get =&gt; &#39;GetSize&#39;,         Set =&gt; &#39;SetSize&#39; );      my @text         :Field( Get =&gt; &#39;GetText&#39;,         Set =&gt; &#39;SetText&#39; );      my @weight       :Field( Get =&gt; &#39;GetWeight&#39;,       Set =&gt; &#39;SetWeight&#39; );      my %initArgs :InitArgs = (         text =&gt; {            Default =&gt; [],            Field   =&gt; \@text,            Type    =&gt; &#39;LIST&#39;,         },      );      sub _Init :Init {         my ( $self, $args ) = @_;         my $config = $args-&gt;{ config };         $self-&gt;SetConfig( $config );         if ( my $color = $config-&gt;{ color } ) {            $self-&gt;SetColor( $color );         } else {            $self-&gt;SetColor( DEFAULT_COLOR );         }         if ( my $display = $config-&gt;{ display } ) {            $self-&gt;SetDisplay( $display );         } else {            $self-&gt;SetDisplay( DEFAULT_DISPLAY );         }         if ( my $font = $config-&gt;{ font} ) {            $self-&gt;SetFont( $font );         } else {            $self-&gt;SetFont( DEFAULT_FONT );         }         if ( my $fontsettings = $config-&gt;{ fontsettings } ) {            $self-&gt;SetFontSettings( $fontsettings );         } else {            $self-&gt;SetFontSettings( DEFAULT_FONT_SETTINGS );         }         if ( my $italic = $config-&gt;{ italic } ) {            $self-&gt;SetItalic( $italic );         } else {            $self-&gt;SetItalic( DEFAULT_ITALIC );         }         if ( my $size = $config-&gt;{ size } ) {            $self-&gt;SetSize( $size );         } else {            $self-&gt;SetSize( DEFAULT_SIZE );         }         if ( my $weight = $config-&gt;{ weight } ) {            $self-&gt;SetWeight( $weight );         } else {            $self-&gt;SetWeight( DEFAULT_WEIGHT );         }      }      sub GetAll {         my ( $self ) = @_;         return { color         =&gt; $self-&gt;GetColor(),                  display       =&gt; $self-&gt;GetDisplay(),                  font          =&gt; $self-&gt;GetFont(),                  font_settings =&gt; $self-&gt;GetFontSettings(),                  italic        =&gt; $self-&gt;GetItalic(),                  size          =&gt; $self-&gt;GetSize(),                  text          =&gt; $self-&gt;GetText(),                  weight        =&gt; $self-&gt;GetWeight() };      }   }}__END__&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>psh (jettero)</title>
    <link>http://prlmnks.org/html/548787.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/548787.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use Data::Dumper; $Data::Dumper::Indent = $Data::Dumper::Sortkeys = 1;use Term::ReadLine;if( $ARGV[0] eq &quot;-h&quot; or $ARGV[0] eq &quot;--help&quot; ) { exec &quot;perldoc&quot;, $0; exit 900 }my $term = new Term::ReadLine &#39;psh&#39;;my $OUT  = $term-&gt;OUT || \*STDOUT;my @s = ();*d = *Dumper;BEGIN {    eval &quot;require Math::Units::PhysicalValue; import Math::Units::PhysicalValue(qw(PV))&quot;;    unless( $@ ) {        *pv = *PV;        *p = *PV;    }}$SIG{INT} = sub { exit 0 };$SIG{HUP} = sub { exit 0 };print &quot;Welcome to Paul&#39;s perl shell &quot;, q($Revision: 1.16 $), &quot; (type &#39;help&#39; for documentation)\n&quot;;for my $file (&quot;$ENV{HOME}/.psh_stack&quot;, &quot;$ENV{HOME}/.pshrc&quot;) {    if( -f $file and open IN, $file ) {        local $/; my $thefile = &lt;IN&gt;;        no strict &quot;vars&quot;;        eval $thefile;         die &quot;(while evaluating $file): $@&quot; if $@;    }}END {    eval { # try it... don&#39;t freak out if it doesn&#39;t work        $term-&gt;write_history(&quot;$ENV{HOME}/.psh_history&quot;);    };    open SOUT, &quot;&gt;$ENV{HOME}/.psh_stack&quot; or die &quot;couldn&#39;t save psh stack-data: $!&quot;;    print SOUT q(my $the_stack;);    print SOUT &quot;&quot;, Data::Dumper-&gt;Dump([\@s], [qw(the_stack)]);    print SOUT q(        @s = @$the_stack if ref $the_stack;        print &quot;[loaded &quot;, int @s, &quot; symbols into the stack.]\n&quot;;    );    close SOUT;}my $cmd  = 0;eval { # try it, but don&#39;t freak out if it fails...    $term-&gt;read_history(&quot;$ENV{HOME}/.psh_history&quot;);    print &quot;[loaded &quot;, int ($term-&gt;GetHistory), &quot; command(s) from history file]\n&quot;;};print &quot;\n&quot;;$term-&gt;ornaments(&#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;);our $PS1; $PS1 = &quot;\\# psh&gt; &quot; unless $PS1;while ( defined ($_ = $term-&gt;readline(&amp;sub_ps1_vars($PS1))) ) {    s/^\s*//; s/\s*$//; s/[\r\n]//g;    s/\bs(\d+)/\$s[$1]/g;    print &quot;\r\e[2K&quot;; # move to start of line and erase it    $cmd ++;    if( m/^(?:q|e|quit|exit)/ ) {        exit;    } elsif( m/^\/?(?:hist|last)\s*(\d*)/ ) {        my @hist = reverse $term-&gt;GetHistory;        my $max = ($1&gt;0 ? $1-1 : $#hist);        for my $i ( reverse 0 .. $max ) {            print &quot;$i - $hist[$i]\n&quot;;        }    } elsif( m/^\/?(?:help)/ ) {        system(&quot;perldoc&quot;, $0);    } elsif( m/^\/?(?:man|m)\b\s*(.+)/ ) {        system(&quot;man&quot;, &amp;argparse($1));    } elsif( m/^\s*&#39;\s*(.+)/ and my $args = &amp;balanced_single_quotes($1) ) {        system(&amp;argparse($args));    } elsif( m/^\/?(?:doc|func|f)\b\s*(.+)/ ) {        system(&quot;perldoc&quot;, &quot;-f&quot;, &amp;argparse($1));    } elsif( m/^\/?(?:s|l|stack|list)\b\s*(\d*)/ ) {        my $max = ($1&gt;0 ? $1-1 : $#s);        for my $i ( reverse 0 .. $max ) {            my $r = &quot;&quot;;            if( my $R = ref $s[$i] ) {                $r = &quot;\t\t[$R]&quot;;            }            print &quot;s$i = $s[$i]$r\n&quot;;        }    } elsif( m/./ ) {        my $val; NOSTRICT: {            no strict &quot;vars&quot;;            $val = eval $_;        }        if( $@ ) {            $@ =~ s/\s*line \d+\.$//;            $@ =~ s/at\s*\(eval\s*\d+\)/in command #$cmd/;            warn &quot;ERROR: $@\n&quot;;        } else {            &amp;do_val( $val );            print &quot;s0 = $val\n&quot;;        }        # this is actually automatic        # $term-&gt;addhistory($_) if /\S/;    }    print &quot;\n&quot;;}sub sub_ps1_vars {    my $p = shift;    $p =~ s/\\#/$cmd/eg;    return $p;}sub do_val {    my $v = shift;    unshift @s, $v unless &quot;$s[$#s]&quot; eq &quot;$v&quot;;    pop @s while @s &gt; 50;}sub argparse {    my $args = shift;    #TODO: handle quotes    return split /\s+/, $args;}sub balanced_single_quotes {    my $v = shift;    my $cnt = () = $v =~ m/\&#39;/g;    return undef unless ($cnt/2) == int ($cnt/2);    return $v;}__END__=head1 NAMEpsh -- yet another perl shell, complete with fun=head1 SYNOPSISI wanted a hilfe (pike shell) or python shell like setup forperl.  Because I designed the shell through actual use, I endedup including a few handy shortcuts and commands.=head1 THE STACKEverything returned from expressions you type is dumped into thestack (@s).  The most recent value is s0.  You can type the literal&#39;s0&#39; anywhere in an expression and psh will substitue &#39;$s[0]&#39;(which also works).  You can similarly type &#39;s15&#39; for &#39;$s[15]&#39;.The @s never grows bigger than 50.You can view the stack with: &#39;list&#39;, &#39;l&#39;, &#39;stack&#39;, and &#39;s&#39;.These commands take an optional number (e.g. &#39;l 10&#39;) argument tolimit the lines printed.=head1 STRICTNESSYour expressions are evaluated under &#39;use strict&#39;; but also underno strict &#39;vars&#39;.  Warnings are not enabled, but you can &#39;usewarnings&#39; in your .pshrc.=head1 HISTORYThe history is nothing fancy.  I highly recommend installingTerm::ReadLine::Gnu, but that is a personal preference I suppose.** However, your history will NOT save until you install it **You can list your history with &#39;last&#39;.  Presently there is no wayto actually execute something from history other than the obviousarrow keys and/or vim keys (iff applicable).=head1 COMPLETE COMMAND LISTYou can lead each command with a &#39;/&#39; if you desire.  Why wouldyou want to? IRC and TinyFugue habits?  The &#39;/&#39; is optional.    last, hist        - show the history    s, l, stack, list - show the stack    man, m            - fork of man &lt;something&gt;    doc, func, f      - fork of perldoc -f &lt;something&gt;    &#39;                 - arbitrary fork (checks for unbalanced &#39;s)    help              - this document    q, e, quit, exit  - exit=head1 COMPLETE LIST OF SUBSTITUTIONS    *p  = *PV     -- from Math::Units::PhysicalValue (if available)    *pv = *PV     -- from Math::Units::PhysicalValue (if available)    *d  = *Dumper -- from Data::Dumper               (if available)    s/\bs(\d+)/\$s[$1]/g; # s0 becomes $s[0] and s2 becomes $s[2]=head2 GLOB SUB EXAMPLES    (Disclaimer: This may be a plug for PV. Meh.)        psh&gt; p &quot;3,000 ft&quot;    psh&gt; p &quot;2 minutes&quot;    psh&gt; (s1/s2) + &quot;0 miles/hour&quot;Violla, s0 is now set to 17.05 miles/hour!Lastly, because you probably do not even have PV installed, but most likely do have Data::Dumper (since it&#39;s required):    psh&gt; [qw(lol dude!)]    psh&gt; d s0    psh&gt; d [1, 2, 3]Oh and one more because strange attractors are neat.    psh&gt; 7    psh&gt; sqrt s0    psh&gt; sqrt s0    psh&gt; sqrt s0=head1 FILES    $ENV{HOME}/.psh_history - contains your command history    $ENV{HOME}/.psh_stack   - contains your stack in a Data::Dumper format    $ENV{HOME}/.pshrc       - evaled at starttime if it exists=head1 PS1I intend to add many bash substitutions, but for now only \# (cmdnumber) actually works.  You can (and possibly should) set yourPS1 in your .pshrc. I choose this because I like blue:    $PS1 = &quot;\e[1;34m\\# psh&gt;\e[0;37m &quot;;=head1 AUTHORPaul Miller &lt;japh@voltar-confed.org&gt;=head1 VERSION$Id: psh,v 1.16 2006/05/11 17:14:33 jettero Exp $=head1 COPYRIGHTPublic Domain!  I relinquish all my rights to anything written in thisdocument/program.  However, I politely request that you leave myname on the project unless you rewrite, add, or alter the projectin such a way that the diff -u is bigger than the original sourcefile.=head1 SEE ALSONOTE: In a few ways this is a reduplication of the perl debugger.In many other ways, it is most definitely not.perl(1), perldebug(1), perldebtut(1)=cut&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>find directory ACL change in a tree (Discipulus)</title>
    <link>http://prlmnks.org/html/548669.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/548669.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;use strict;use warnings;use Win32::FileSecurity qw(Get EnumerateRights);use Data::Compare;open LOG, &quot;&gt;c:/scripts/acl3.log&quot;;select LOG;my $basedir = &#39;C:/inetpub/wwwroot/&#39;;my @sottrarre = split /\//, $basedir;my $targdir =  &#39;yourfolder/&#39;;my $iniziale = $basedir.$targdir;my @cartelle = &amp;recursive($iniziale);my %livelli =  &amp;per_livelli(@cartelle);    print &quot;PERMESSI DELLA ROOT\n\n&quot;;    &amp;secdump($iniziale);    print &quot;\n#######\n&quot;;foreach my $lvl(sort keys %livelli){      foreach my $item(keys %{$livelli{$lvl}} )      {        next if $item=~/_private|_vti_cnf|_vti_log|_vti_pvt|_vti_script|_vti_txt/;##skip vicious FrontPage dirs        &amp;compara_madre($item,$lvl);      }}my $now = time();print &quot;\n\nTEMPO TOTALE TRASCORSO: &quot;,$now-$^T,&quot; SECONDI\n\n&quot;;################################################################################sub compara_madre{    my $figlio = shift;    my $lvl = shift;    return if $lvl == 0;    my $madre;    my $diff;    if ($figlio =~/[\w\d\.\s-]+\/$/){$diff = $&amp;}    $madre = $figlio;    $madre =~s/$diff$//;    unless (Compare \$livelli{$lvl-1}{$madre}, \$livelli{$lvl}{$figlio} ){            print &quot;################\n#DIFFERENZE TRA:\n$figlio\tFIGLIA DI\n$madre\n################\n&quot;;        foreach my $usr(keys %{$livelli{$lvl}{$figlio}}){            if (not defined $livelli{$lvl}{$figlio}{$usr})                {print &quot;nessuna entry in $figlio per $usr\n&quot;;return}            if (not defined $livelli{$lvl-1}{$madre}{$usr})                {print &quot;nessuna entry in $madre per $usr\n&quot;;return}            if  ($livelli{$lvl}{$figlio}{$usr} != $livelli{$lvl-1}{$madre}{$usr})            {                       print &quot;MADRE: $madre\n&quot;;                       print &quot;\t\tUSER: $usr\n&quot;;                       my @happy;                       EnumerateRights( $livelli{$lvl-1}{$madre}{$usr}, \@happy ) ;                       print &quot;\n\t&quot;,join( &quot;\n\t&quot;, @happy ), &quot;\n&quot;;                       print &quot;FIGLIO: $figlio\n&quot;;                       print &quot;\t\tUSER: $usr\n&quot;;                       my @happytoo;                       EnumerateRights( $livelli{$lvl}{$figlio}{$usr}, \@happytoo ) ;                       print &quot;\n\t&quot;,join( &quot;\n\t&quot;, @happytoo ), &quot;\n&quot;;            }          }          print &quot;\n#######\n&quot;;    }}################################################################################sub recursive{ my $root  = shift;  my @dirs  = ($root);  for my $path (@dirs){    opendir ( CART, $path ) or next;   # skip dirs we can&#39;t read    while (my $file = readdir CART) {      next if $file eq &#39;.&#39; or $file eq &#39;..&#39;; # skip dot files      next if -l $path.$file;                # skip sym links        if ( -d $path.$file ) {             push @dirs, $path.$file.&quot;/&quot;;     # add dir to list               }    }    closedir CART; }  return @dirs;}################################################################################sub per_livelli{    my @dirs = @_;    my %livelli;    foreach my $ele (@dirs){             my @temp = split /\//, $ele;             $livelli{$#temp-$#sottrarre-1}{$ele}=&amp;filsec($ele);    }  return   %livelli;}################################################################################sub filsec{        my $cart = shift;        my %hash;        next unless -e $cart ;        if ( Get( $cart, \%hash ) ) {return \%hash;}        else {print STDERR &quot;Error #&quot;, int( $! ), &quot;: $!&quot; ;}}################################################################################sub secdump{        my ($cart, $name, $mask, @happy, %hash)= (shift, undef, undef, undef, undef);        if ( Get( $cart, \%hash ) ) {while( ($name, $mask) = each %hash ) {print &quot;$name: $mask\n\t&quot;;}}        else {print( &quot;Error #&quot;, int( $! ), &quot;: $!&quot; ) ;}}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>Strangely addictive Tk::Zinc based game (thundergnat)</title>
    <link>http://prlmnks.org/html/547577.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/547577.html</guid>

    <description>
        &lt;pre class=&quot;block_code&quot;&gt;use warnings;use strict;use Tk;use Tk::Zinc;use Time::HiRes qw( gettimeofday tv_interval );my ( $window_width, $window_height ) = ( 1000, 800 );my $top    = 30;my $bottom = $window_height - $top;my $left   = $top;my $right  = $window_width - $left;my ( %ball, %wall, %time, %parameter );my $delay_init = 0;$ball{velocity} = [ 0, 0 ];if ( $ARGV[0] and $ARGV[0] !~ /\D/ ) {    $delay_init = $ARGV[0];    set_parameters($delay_init);}elsif ( $ARGV[0] and $ARGV[0] =~ /\D/ ) {    die&quot;Pass a numeric delay in milliseconds to override auto update speed detection.Something in the range 20-80 is recommended. For example:\n$0 50\n&quot;;}else {    set_parameters(50);}my $mw = MainWindow-&gt;new;$mw-&gt;geometry(&quot;${window_width}x$window_height&quot;);$mw-&gt;resizable( 0, 0 );my $zframe = $mw-&gt;Frame-&gt;pack( -expand =&gt; 1, -fill =&gt; &#39;both&#39; );my $zinc = $zframe-&gt;Zinc(    -backcolor =&gt; &#39;black&#39;,    -render    =&gt; 1  )-&gt;pack(    -fill   =&gt; &#39;both&#39;,    -expand =&gt; 1,  );my $group = $zinc-&gt;add( &#39;group&#39;, 1, -visible =&gt; 1 );{    $ball{radius} = 20;    my $x = $window_width / 2;    my $y = $window_height / 2;    $ball{position} = [ $x, $y ];    $ball{widget} = $zinc-&gt;add(        &#39;arc&#39;, $group,        [            [ $x - $ball{radius}, $y - $ball{radius} ],            [ $x + $ball{radius}, $y + $ball{radius} ]        ],        -filled    =&gt; 1,        -fillcolor =&gt;          &#39;=radial -20 -20|#ffffff 0|#f700f7 48|#900090 80|#ab00ab 100&#39;,        -linewidth =&gt; 0,        -visible   =&gt; 1,    );}$wall{widget} = $zinc-&gt;add(    &#39;curve&#39;, $group,    [        [ $left,  $top ],        [ $right, $top ],        [ $right, $bottom ],        [ $left,  $bottom ],        [ $left,  $top ]    ],    -linecolor =&gt; &#39;#00ff00&#39;,    -linewidth =&gt; 6,    -priority  =&gt; 100,    -visible   =&gt; 1,);$time{current}{widget} = $zinc-&gt;add(    &#39;text&#39;, $group,    -position =&gt; [ $window_width / 8, 0 ],    -color    =&gt; &#39;#c0c000&#39;,    -font     =&gt; &quot;Times 14&quot;,    -visible  =&gt; 1,);$time{power}{widget} = $zinc-&gt;add(    &#39;text&#39;, $group,    -position =&gt; [ $window_width / 8 * 3, 0 ],    -color    =&gt; &#39;#c0c000&#39;,    -font     =&gt; &quot;Times 14&quot;,    -visible  =&gt; 1,);$time{high}{widget} = $zinc-&gt;add(    &#39;text&#39;, $group,    -position =&gt; [ $window_width / 8 * 5, 0 ],    -color    =&gt; &#39;#c0c000&#39;,    -font     =&gt; &quot;Times 14&quot;,    -visible  =&gt; 1,);$zframe-&gt;bind( &#39;&lt;Enter&gt;&#39; =&gt; sub { $zframe-&gt;configure( -cursor =&gt; &#39;dot&#39; ) } );$zframe-&gt;bind( &#39;&lt;Leave&gt;&#39; =&gt; sub { $zframe-&gt;configure( -cursor =&gt; &#39;arrow&#39; ) } );$time{current}{value} = gettimeofday;$time{high}{value}    = 0;my $repeat = $mw-&gt;repeat( $parameter{delay}, \&amp;update );MainLoop;sub update {    my ( $x,  $y )  = @{ $ball{position} };    my ( $dx, $dy ) = @{ $ball{velocity} };    my ( $mx, $my ) =      ( $mw-&gt;pointerx - $mw-&gt;x, $mw-&gt;pointery - $mw-&gt;y );    # mouse position    my $ximpulse = 0;    my $yimpulse = 0;    $parameter{repel} -= $parameter{repel_decay};            #power decay    my $elapsed = tv_interval( [ $time{current}{value} ], [gettimeofday] );    $zinc-&gt;itemconfigure( $time{current}{widget},        -text =&gt; ( sprintf &quot;Current %.2f Secs.&quot;, $elapsed ) );    my $percent = sprintf &quot;%.1f&quot;,      $parameter{repel} / $parameter{repel_start} * 100;    $zinc-&gt;itemconfigure( $time{power}{widget}, -text =&gt; &quot;$percent% Power&quot; );    if ( $time{high}{value} &lt; $elapsed ) {        $time{high}{value} = $elapsed;        $zinc-&gt;itemconfigure( $time{high}{widget},            -text =&gt; ( sprintf &quot;High  %0.2f : $percent%%&quot;, $elapsed ) );    }    if (    $my &gt; $top - $ball{radius}        and $my &lt; $bottom + $ball{radius}        and $mx &gt; $left - $ball{radius}        and $mx &lt; $right + $ball{radius} )    {        my $y_component = $y - $my;        my $x_component = $x - $mx;        my $impulse     = $parameter{repel} * $parameter{delay}**.3 * 150 /          ( $y_component**2 + $x_component**2 );        $yimpulse = $y_component * $impulse;        $ximpulse = $x_component * $impulse;    }    $dx *= .99;    # a little velocity decay.    $dy *= .99;    if (   ( $x - $ball{radius} + $dx &lt; $left )        or ( $x + $ball{radius} + $dx &gt; $right ) )    {        $dx = -$dx;        reset_time( $elapsed, $percent );    }    if (   ( $y - $ball{radius} + $dy &lt; $top )        or ( $y + $ball{radius} + $dy &gt; $bottom ) )    {        $dy = -$dy * .75;        reset_time( $elapsed, $percent );    }    $zinc-&gt;translate( $ball{widget}, $dx, $dy );    $dy += $parameter{gravity} + $yimpulse;    $dx += $ximpulse;    my ( $x0, $y0, $x1, $y1 ) = $zinc-&gt;bbox( $ball{widget} );    $ball{position} = [ ( $x0 + $x1 ) / 2, ( $y0 + $y1 ) / 2 ];    $ball{velocity} = [ $dx, $dy ];    unless ( $delay_init and $elapsed ) {        $delay_init = $elapsed;        set_parameters( int( $delay_init * 250 ) );        $repeat-&gt;cancel;        $mw-&gt;repeat( $parameter{delay}, \&amp;update );    }}sub reset_time {    my ( $elapsed, $percent ) = @_;    printf &quot;%.2f Seconds : %.1f%% Power\n&quot;, $elapsed, $percent      if $elapsed &gt; 10;    $time{current}{value} = gettimeofday;    $parameter{repel} = $parameter{repel_start};}sub set_parameters {    $parameter{delay}       = shift;    $parameter{gravity}     = $parameter{delay} / 15;    $parameter{repel_start} = $parameter{gravity}**.5 / 3;    $parameter{repel}       = $parameter{repel_start};    $parameter{repel_decay} =      $parameter{repel_start} / ( 70000 / $parameter{delay} );    print &quot;Delay set to $parameter{delay} ms.\n\n&quot; if $delay_init;}&lt;/pre&gt;
    </description>
</item>

        

<item>
    <title>script-starter (frodo72)</title>
    <link>http://prlmnks.org/html/546975.html</link>
    <guid isPermaLink="true">http://prlmnks.org/html/546975.html</guid>

    <description>
        This is the template (living in Linux, I put it into &lt;tt class=&quot;inline_code&quot;&gt;$HOME/.module-starter/script.tpl&lt;/tt&gt;):&lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;use Carp;use Pod::Usage qw( pod2usage );use Getopt::Long qw( :config gnu_getopt );use version; my $VERSION = qv(&#39;0.0.1&#39;);my %config;GetOptions(\%config, &#39;usage&#39;, &#39;help&#39;, &#39;man&#39;, &#39;version&#39;);pod2usage(&quot;$0 v$VERSION&quot;) if $config{version};pod2usage(-verbose =&gt; 99, -sections =&gt; &#39;USAGE&#39;) if $config{usage};pod2usage(-verbose =&gt; 99, -sections =&gt; &#39;EXAMPLES|USAGE|OPTIONS&#39;)  if $config{help};pod2usage(-verbose =&gt; 2) if $config{man};# Other recommended modules (uncomment to use):#  use IO::Prompt;#  use Readonly;#  use Data::Dumper;#  use Log::Log4perl qw( :easy );# Script implementation here__END__=head1 NAME&lt;SCRIPT-NAME&gt; - [A line to describe the script]=head1 VERSIONSee version at beginning of script, variable $VERSION.=head1 EXAMPLES   shell$ &lt;SCRIPT-NAME&gt;=for the author:   Some brief example to show the most common usage for the script. This   will probably be the most read section, so include meaningful   examples.  =head1 USAGE   &lt;SCRIPT-NAME&gt; [--usage] [--help] [--man] [--version]=for the author:   Include a complete usage block of text, like any other good command  =head1 DESCRIPTION=for the author:   A complete description of the script and its characteristics, with a   possible structure into deeper sections (via =head2, =head3). Leave   options description for the next section!=head1 OPTIONS=for the author   A description of all the available options that the script accepts.   The pre-defined ones are already included, of course.=over=item --usageprint a concise usage line and exit.=item --helpprint a somewhat more verbose help, showing usage, this description ofthe options and some examples from the synopsis.=item --manprint out the full documentation for the script.=item --versionprint the version of the script.=back=head1 DIAGNOSTICS=for the author   Include all error messages and possible exit conditions, even those   that &quot;should never happen&quot;.=over=item C&lt;&lt; Error message here, perhaps with %s placeholders &gt;&gt;[Description of first error...]=item C&lt;&lt; Another error message here &gt;&gt;[Description of another error...][... and so on...]=back=head1 CONFIGURATION AND ENVIRONMENT=for the author   Describe any configuration file that is used by the script, and   any environment variable that affects the its behaviour. Include   details about the position of the files, their formats, etc.  &lt;SCRIPT-NAME&gt; requires no configuration files or environment variables.=head1 DEPENDENCIES=for the author   A list of all modules the script is based for, together with an   indication of their version and the required perl version.None.=head1 BUGS AND LIMITATIONS=for the author   A list of all known problem about the script, with an indication of   when (and if) they will be eventually solved. Also include a   description of all feature restrictions and limitations.No bugs have been reported.Please report any bugs or feature requests to the AUTHOR=head1 AUTHORFlavio Poletti C&lt;flavio [at] polettix.it&gt;=head1 LICENCE AND COPYRIGHTCopyright (c) 2006, Flavio Poletti C&lt;flavio [at] polettix.it&gt;. All rights reserved.This script is free software; you can redistribute it and/ormodify it under the same terms as Perl itself. See L&lt;perlartistic&gt;and L&lt;perlgpl&gt;.=head1 DISCLAIMER OF WARRANTYBECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTYFOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHENOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIESPROVIDE THE SOFTWARE &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHEREXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THEENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITHYOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALLNECESSARY SERVICING, REPAIR, OR CORRECTION.IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITINGWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/ORREDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BELIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USETHE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEINGRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR AFAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IFSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OFSUCH DAMAGES.=cut&lt;/pre&gt;This is the script that creates a new script based on the template above, I named it &lt;tt class=&quot;inline_code&quot;&gt;script-starter&lt;/tt&gt;&lt;pre class=&quot;block_code&quot;&gt;#!/usr/bin/perluse strict;use warnings;use Carp;use Pod::Usage ();use version; my $VERSION = qv(&#39;0.0.1&#39;);my $original = &quot;$ENV{HOME}/.module-starter/script.tpl&quot;;# Other recommended modules (uncomment to use):#  use IO::Prompt;#  use Perl6::Export;#  use Perl6::Slurp;#  use Perl6::Say;#  use Regexp::Autoflags;#  use Readonly;# Script implementation heremy $script_name = shift;if (! defined $script_name ) {   Pod::Usage::pod2usage(-verbose =&gt; 1);   exit 0;}if ($script_name =~ /-h|--help/) {   Pod::Usage::pod2usage(-verbose =&gt; 2);   exit 0;}croak &quot;file &#39;$script_name&#39; already exists, stopped&quot; if -e $script_name;open my $input_fh, &#39;&lt;&#39;, $original  or croak &quot;open() for original &#39;$original&#39;: $!&quot;;open my $output_fh, &#39;&gt;&#39;, $script_name  or croak &quot;open() on &#39;$script_name&#39;: $!&quot;;while (&lt;$input_fh&gt;) {   s/&lt;SCRIPT-NAME&gt;/$script_name/g;   print {$output_fh} $_;}close $input_fh;close $output_fh;__END__=head1 NAMEscript-starter - create the base for a new script=head1 VERSIONThis document describes script-starter version 0.0.1=head1 SYNOPSIS   # Ask for help   shell$ script-starter      # Generate a new script from the template   shell$ script-starter nome-script  =head1 DESCRIPTIONThis script helps to create other scripts, in a way much similar tomodule-starter. It takes the $original script (see start of script)and copies to the destination one, setting the script name on thefly.=head1 INTERFACEThe script requires only one argument, which should be a validfilename for a non-existing file.When called without options, it prints the examples in the L&lt;SYNOPSIS&gt;.When called with -h/--help, it perldoc-s the script to show thishelp page.=head1 DIAGNOSTICS=over=item C&lt;&lt; file &#39;$script_name&#39; already exists, stopped at... &gt;&gt;The name of the script to be generated refers to an already existing file.This is not allowed, script-starter won&#39;t let you shoot at your feet soeasily. Note that there is still space for a race condition between theexistence test and the actual file open for writing, be sure to aim well.=item C&lt;&lt; open() for original &#39;/path/to/template&#39;: &lt;specific error&gt; &gt;&gt;There was a problem opening the template file.=item C&lt;&lt; open() on &#39;/path/to/target-script&#39;: &lt;specific error&gt; &gt;&gt;There was a problem opening the target file.=back=head1 CONFIGURATION AND ENVIRONMENTGiven the fact that I&#39;ll never publish this script, it can be easilytweaked modifing the C&lt;$original&gt; variable at the beginning, whichpoints to the template model.=head1 DEPENDENCIESA few:=over=item -version=item -Pod::Usage=back=head1 INCOMPATIBILITIESNone reported.=head1 BUGS AND LIMITATIONSNo bugs have been reported.Please report any bugs or feature requests through http://rt.cpan.org/=head1 AUTHORFlavio Poletti C&lt;&lt; flavio@polettix.it &gt;&gt;=head1 LICENCE AND COPYRIGHTCopyright (c) 2006, Flavio Poletti C&lt;&lt; flavio@polettix.it &gt;&gt;. All rights reserved.This script is free software; you can redistribute it and/ormodify it under the same terms as Perl itself. See L&lt;perlartistic&gt;and L&lt;perlgpl&gt;.Questo script  software libero: potete ridistribuirlo e/omodificarlo negli stessi termini di Perl stesso. Vedete ancheL&lt;perlartistic&gt; e L&lt;perlgpl&gt;.=head1 DISCLAIMER OF WARRANTYBECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTYFOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHENOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIESPROVIDE THE SOFTWARE &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, EITHEREXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIEDWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THEENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITHYOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALLNECESSARY SERVICING, REPAIR, OR CORRECTION.IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITINGWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/ORREDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BELIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL,OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USETHE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEINGRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR AFAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IFSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OFSUCH DAMAGES.=head1 NEGAZIONE DELLA GARANZIAPoich questo software viene dato con una licenza gratuita, nonc&#39; alcuna garanzia associata ad esso, ai fini e per quanto permessodalle leggi applicabili. A meno di quanto possa essere specificatoaltrove, il proprietario e detentore del copyright fornisce questosoftware &quot;cos com&#39;&quot; senza garanzia di alcun tipo, sia essa espressao implicita, includendo fra l&#39;altro (senza per limitarsi a questo)eventuali garanzie implicite di commerciabilit e adeguatezza peruno scopo particolare. L&#39;intero rischio riguardo alla qualit edalle prestazioni di questo software rimane a voi. Se il softwaredovesse dimostrarsi difettoso, vi assumete tutte le responsabilited i costi per tutti i necessari servizi, riparazioni o correzioni.In nessun caso, a meno che ci non sia richiesto dalle leggi vigentio sia regolato da un accordo scritto, alcuno dei detentori del dirittodi copyright, o qualunque altra parte che possa modificare, o redistribuirequesto software cos come consentito dalla licenza di cui sopra, potressere considerato responsabile nei vostri confronti per danni, iviinclusi danni generali, speciali, incidentali o conseguenziali, derivantidall&#39;utilizzo o dall&#39;incapacit di utilizzo di questo software. Ciinclude, a puro titolo di esempio e senza limitarsi ad essi, la perditadi dati, l&#39;alterazione involontaria o indesiderata di dati, le perditesostenute da voi o da terze parti o un fallimento del software adoperare con un qualsivoglia altro software. Tale negazione di garanziarimane in essere anche se i dententori del copyright, o qualsiasi altraparte,  stata avvisata della possibilit di tali danneggiamenti.Se decidete di utilizzare questo software, lo fate a vostro rischioe pericolo. Se pensate che i termini di questa negazione di garanzianon si confacciano alle vostre esigenze, o al vostro modo diconsiderare un software, o ancora al modo in cui avete sempre trattatosoftware di terze parti, non usatelo. Se lo usate, accettate espressamentequesta negazione di garanzia e la piena responsabilit per qualsiasitipo di danno, di qualsiasi natura, possa derivarne.=cut&lt;/pre&gt;
    </description>
</item>

    </channel>
</rss>
