<?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];prin