Fwd: Patches

Kirk Bauer <[email protected]>
Newsgroups gmane.comp.log.logwatch.devel
Message-ID <[email protected]>
Stefan,

I have relayed your patches to the logwatch developers list.  Thank
you, and sorry if I lost your previous ones, life has been hectic.


---------- Forwarded message ----------
From: Stefan <[email protected]>
Date: Tue, Jul 7, 2009 at 8:11 AM
Subject: Patches
To: [email protected]


Hello Kirk,

I don't know if you have received my patches, but I don't think so since I
haven't got an answer or seen them on the mailinglist or in CVS. So I try it
again.

All patches are against the CVS Version.

Greetings
Stefan

PS:

**Unknown Entries** dhcpd:
   Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not
specified in the config file:


**Unmatched Entries** clamav
 Not loading PUA signatures.
 TCP: Bound to address 127.0.0.1 on port 3310
 TCP: Setting connection queue length to 15
 LOCAL: Unix socket file /var/lib/clamav/clamd-socket
 LOCAL: Setting connection queue length to 15
 Limits: Global size limit set to 104857600 bytes.
 Limits: File size limit set to 26214400 bytes.
 Limits: Recursion level limit set to 16.
 Limits: Files limit set to 10000.

**Unmatched Entries** smartd
 smartd 5.39 2008-10-24 22:33 [x86_64-suse-linux-gnu] (openSUSE RPM) Copyright
(C) 2002-8 by Bruce Allen, http://smartmontools.sourceforge.net
 Device: /dev/sda, type changed from 'scsi' to 'sat'
 Device: /dev/sda [SAT], state read from
/var/lib/smartmontools/smartd.SAMSUNG_HD753LJ-S13UJ90QB02712.ata.state
 Device: /dev/sda [SAT], state written to
/var/lib/smartmontools/smartd.SAMSUNG_HD753LJ-S13UJ90QB02712.ata.state

_______________________________________________
Logwatch-Devel mailing list
[email protected]
http://www2.list.logwatch.org:81/mailman/listinfo/logwatch-devel
clamav.patch (text/x-patch, 2.8 KB)
--- clamav	2008-07-01 01:07:51.000000000 +0200
+++ /home/general/Projekte/clamav.new	2009-06-11 23:18:17.000000000 +0200
@@ -50,6 +50,8 @@
        ( $ThisLine =~ /^Mail: Recursion level limit set to \d+/ ) or
        ( $ThisLine =~ /clamd shutdown\s+succeeded/ ) or
        ( $ThisLine =~ /clamd startup\s+succeeded/ ) or
+       ( $ThisLine =~ /Not loading PUA signatures/ ) or
+       ( $ThisLine =~ /^(?:LOCAL|TCP): Setting connection queue length to/ ) or
        ( $ThisLine =~ /^No stats for Database check/ )) {
        # We do not care about these.
    } elsif (($Check) = ($ThisLine =~ /^SelfCheck: (.*?)\.?\s?\n/i)) {
@@ -63,6 +65,19 @@
       $DaemonStop++;
    } elsif (($ThisLine =~ /Daemon started/)) {
       $DaemonStart++;
+   } elsif (($ThisLine =~ /LOCAL: Unix socket file ([^ \n]*)/)) {
+      $SocketFile{$1}++;
+   } elsif (($ThisLine =~ /TCP: Bound to address ([^ ]*) on port (\d+)/)) {
+      $BoundToIP{$1}++;
+      $BoundToPort{$1}=$2;
+   } elsif (($ThisLine =~ /Limits: Global size limit set to (\d+) bytes/)) {
+      $GSizeLimit{$1}++;
+   } elsif (($ThisLine =~ /Limits: File size limit set to (\d+) bytes/)) {
+      $FSizeLimit{$1}++;
+   } elsif (($ThisLine =~ /Limits: Recursion level limit set to (\d+)/ )) {
+      $RecursionLimit{$1}++;
+   } elsif (($ThisLine =~ /Limits: Files limit set to (\d+)/ )) {
+      $FilesLimit{$1}++;
    } else {
       push @OtherList,$ThisLine;
    }
@@ -94,6 +109,52 @@
    print "\nVirus database reloaded $DatabaseReloads time(s) (last time with $DatabaseViruses viruses)\n";
 }
 
+if ($Detail > 8) {
+   if (keys %SocketFile) {
+      print "\nBound to Unix socket:\n";
+      foreach $Socket (keys %SocketFile) {
+         print "\t$Socket\t$SocketFile{$Socket} Time(s)\n";
+      }
+   }
+   if (keys %BoundToIP) {
+      print "Bound to IP:Port:\n";
+      foreach $IP (keys %BoundToIP) {
+         print "\t$IP:$BoundToPort{$IP}\t\t\t$BoundToIP{$IP} Time(s)\n";
+      }
+   }
+   
+   if (keys %GSizeLimit) {
+      print "Global size limit:\t";
+      foreach $limit (keys %GSizeLimit) {
+         $limit = int $limit/1024/1024;
+         print "$limit MB\t";
+      }
+      print "\n";
+   }
+   if (keys %FSizeLimit) {
+      print "File size limit:\t";
+      foreach $limit (keys %FSizeLimit) {
+         $limit = int $limit/1024/1024;
+         print "$limit MB\t";
+      }
+      print "\n";
+   }
+   if (keys %RecursionLimit) {
+      print "Recursion level limit:\t";
+      foreach $limit (keys %RecursionLimit) {
+         print "$limit\t";
+      }
+      print "\n";
+   }
+   if (keys %FilesLimit) {
+      print "Files limit:\t\t";
+      foreach $limit (keys %FilesLimit) {
+         print "$limit\t";
+      }
+      print "\n";
+   }
+}
+   
 if (($#OtherList >= 0) and (not $IgnoreUnmatched)){
    print "\n**Unmatched Entries**\n";
    print @OtherList;
smartd.patch (text/x-patch, 1.7 KB)
--- smartd	2009-06-10 21:48:39.000000000 +0200
+++ /home/general/Projekte/smartd.new	2009-06-11 23:29:39.000000000 +0200
@@ -101,12 +101,17 @@
        # ignore
    } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), is in STANDBY mode, skipping checks/ )) {
        # ignore
+   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), type changed from \'\w+\' to \'\w+\'/ )) {
+       # ignore
+   } elsif ( ($Device) = ($ThisLine =~ /^Device: ([^,]+), state (?:read from|written to)/ )) {
+       # ignore
    } elsif ( $ThisLine =~ /^file \/var\/run\/smartd.pid written containing PID [0-9]+/ ) {
        # ignore
    } elsif ( ($Device,$Msg) = ($ThisLine =~ /^ *$/ )) {
        # ignore empty lines
    } elsif ( ($ThisLine =~ /^smartd version/)
           || ($ThisLine =~ /^Home page/)
+          || ($ThisLine =~ /^smartd .* Copyright \(C\) [0-9-]+ by Bruce Allen/)
           || ($ThisLine =~ /configuration file/i)
           || ($ThisLine =~ /\[trip Temperature is \d+ Celsius\]/)
           || ($ThisLine =~ /^Monitoring/)
@@ -118,8 +123,8 @@
 	  || ($ThisLine =~ /Device (.*), SATA disks accessed via libata are not currently supported by smartmontools./) 
 	  || ($ThisLine =~ /Device: (.*), IE \(SMART\) not enabled, skip device Try '.*' to turn on SMART features/) 
 	  || ($ThisLine =~ /Device: (.*), Bad IEC (SMART) mode page, err=-5, skip device/)
-     || ($ThisLine =~ /Drive: DEVICESCAN, implied '-a' Directive on line [\d]+ of file/)
-     || ($ThisLine =~ /packet devices \[this device CD\/DVD\] not SMART capable/) )
+	  || ($ThisLine =~ /Drive: DEVICESCAN, implied '-a' Directive on line [\d]+ of file/)
+	  || ($ThisLine =~ /packet devices \[this device CD\/DVD\] not SMART capable/) )
    {
        # ignore
fail2ban.patch (text/x-patch, 977 B)
--- fail2ban	2008-08-18 18:07:46.000000000 +0200
+++ /home/general/Projekte/fail2ban.new	2009-06-11 02:30:35.000000000 +0200
@@ -66,11 +66,14 @@
     if ( ($ThisLine =~ /..,... DEBUG: /) or
 	 ($ThisLine =~ /..,... \S*\s*: DEBUG /) or # syntax of 0.7.? fail2ban
 	 ($ThisLine =~ /..,... INFO: (Fail2Ban v.* is running|Exiting|Enabled sections:)/) or
-    ($ThisLine =~ /INFO.*Log rotation detected for/) or
+	 ($ThisLine =~ /INFO\s+Log rotation detected for/) or
+	 ($ThisLine =~ /INFO\s+Jail.+(?:stopped|started|uses poller)/) or
+	 ($ThisLine =~ /INFO\s+Changed logging target to/) or
+	 ($ThisLine =~ /INFO\s+Creating new jail/) or
 	 ($ThisLine =~ /..,... \S+\s*: INFO\s+(Set |Socket|Exiting|Gamin|Created|Added|Using)/) or # syntax of 0.7.? fail2ban
 	 ($ThisLine =~ /..,... WARNING: Verbose level is /) or
 	 ($ThisLine =~ /..,... WARNING: Restoring firewall rules/)
-	 )
+       )
     {
 	if ( $Debug >= 6 ) {
 	    print STDERR "DEBUG($DebugCounter): line ignored\n";
emerge.patch (text/x-patch, 1.4 KB)
--- emerge	2008-07-01 01:07:51.000000000 +0200
+++ /home/general/Projekte/emerge.new	2009-06-11 01:51:12.000000000 +0200
@@ -51,12 +51,15 @@
       ($ThisLine =~ /Starting rsync with/i) or
       ($ThisLine =~ /Merging/) or
       ($ThisLine =~ /Unmerging./) or
+      ($ThisLine =~ /Resuming merge/) or
       ($ThisLine =~ /AUTOCLEAN/) or
       ($ThisLine =~ />>> emerge /) or
+      ($ThisLine =~ />>> depclean/) or      
       ($ThisLine =~ /\*\*\* emerge /) or
       ($ThisLine =~ /Cleaning/) or      
       ($ThisLine =~ /Updating world file/) or
-      ($ThisLine =~ /Post-Build/) 
+      ($ThisLine =~ /Post-Build/) or 
+      ($ThisLine =~ /Starting retry \d+ of \d+ with/) 
     ) {
       # Don't care about these...
    } 
@@ -72,6 +75,8 @@
       $NumberOfPackageUnmerged++;
    } elsif ( $ThisLine =~ s/^Dep Installed: ([^ ]+)/$1 / ) {
       $PackageDepInstalled{$ThisLine}++;
+   } elsif ( $ThisLine =~ /exiting unsuccessfully with status \'(\d)\'/ ) {
+      $ExitUnsuccessfull{$1}++;
    } else {
       # Report any unmatched entries...
       push @OtherList,$ThisLine;
@@ -111,6 +116,12 @@
        print "   ". $ThisOne;
    }
 }
+if (keys %ExitUnsuccessfull) {
+   print "\nUnsuccessfull exit with:\n";
+   foreach $ThisOne (keys %ExitUnsuccessfull) {
+       print "   Status $ThisOne : $ExitUnsuccessfull{$ThisOne} Time(s)\n";
+   }
+}
 
 if ($#OtherList >= 0) {
    print "\n**Unmatched Entries**\n";
vsftpd.patch (text/x-patch, 4.3 KB)
--- vsftpd	2008-07-15 16:57:32.000000000 +0200
+++ /home/general/Projekte/vsftpd.new	2009-06-11 00:52:58.000000000 +0200
@@ -22,13 +22,16 @@
 $IgnoreUnmatched = $ENV{'vsftpd_ignore_unmatched'};
 $TotalBytesOut = 0;
 $TotalBytesIn = 0;
+$TotalDeleted = 0;
+$TotalCreatedDirs = 0;
+$TotalRemovedDirs = 0;
 
 while (defined($ThisLine = <STDIN>)) {
    if ( ( $ThisLine =~ /CONNECT/ ) or
-        ( $ThisLine =~ /[OK|FAIL] RMDIR/ ) or
+        ( $ThisLine =~ /[OK|FAIL] RENAME/ ) or
         ( $ThisLine =~ /[OK|FAIL] CHMOD/ ) or
-        ( $ThisLine =~ /[OK|FAIL] DELETE/ ) or
-        ( $ThisLine =~ /MKDIR/ ) ) 
+        ( $ThisLine =~ /authentication failure/ ) 
+      ) 
    { # We don't care about these
    } elsif ( ($IP,$Email) = ( $ThisLine =~ /OK LOGIN: Client \"(.*)\", anon password \"(.*)\"$/ ) ) {
       $Temp = "    (" . $IP . "): " . $Email . " - ";
@@ -37,7 +40,7 @@
       $Temp = "    (" . $IP . "): " . $User . " - ";
       $UserLogins{$Temp}++;
    } elsif ( ($PID,$User,$IP) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] FAIL LOGIN: Client \"(.*)\"$/ ) ) {
-      $Temp = " (" . $IP . "): " . $User . " - ";
+      $Temp = "    (" . $IP . "): " . $User . " - ";
       $FailedLogins{$Temp}++;
    } elsif ( ($PID,$User,$IP,$FileName,$FileSize) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] OK UPLOAD: Client \"(.*)\", \"(.*)\", (?:(\d+) bytes)?/ ) ) {
       $Temp = "   " . $FileName . " <- " . $IP . " (User: " . $User . ")\n";
@@ -55,6 +58,27 @@
       $Temp = "   " . $FileName . " -> " . $IP . " (User: " . $User . ")\n";
       $TotalBytesOut+= $FileSize;
       push @FailedDownloadedFiles,$Temp;
+   } elsif ( ($PID,$User,$IP,$FileName) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] OK DELETE: Client \"(.*)\", \"(.*)\"/ ) ) {
+      $Temp = "   " . $FileName . " >< " . $IP . " (User: " . $User . ")\n";
+      $TotalDeleted++;
+      push @DeletedFiles,$Temp;
+   } elsif ( ($PID,$User,$IP,$FileName) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] FAIL DELETE: Client \"(.*)\", \"(.*)\"/ ) ) {
+      $Temp = "   " . $FileName . " <> " . $IP . " (User: " . $User . ")\n";
+      push @FailedDeletedFiles,$Temp;
+   } elsif ( ($PID,$User,$IP,$FileName) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] OK MKDIR: Client \"(.*)\", \"(.*)\"/ ) ) {
+      $Temp = "   " . $FileName . " <- " . $IP . " (User: " . $User . ")\n";
+      $TotalCreatedDirs++;
+      push @CreatedDirs,$Temp;
+   } elsif ( ($PID,$User,$IP,$FileName) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] FAIL MKDIR: Client \"(.*)\", \"(.*)\"/ ) ) {
+      $Temp = "   " . $FileName . " xx " . $IP . " (User: " . $User . ")\n";
+      push @FailedCreatedDirs,$Temp;
+   } elsif ( ($PID,$User,$IP,$FileName) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] OK RMDIR: Client \"(.*)\", \"(.*)\"/ ) ) {
+      $Temp = "   " . $FileName . " >< " . $IP . " (User: " . $User . ")\n";
+      $TotalRemovedDirs++;
+      push @RemovedDirs,$Temp;
+   } elsif ( ($PID,$User,$IP,$FileName) = ( $ThisLine =~ /\[(.*)\] \[(.*)\] FAIL RMDIR: Client \"(.*)\", \"(.*)\"/ ) ) {
+      $Temp = "   " . $FileName . " <> " . $IP . " (User: " . $User . ")\n";
+      push @FailedRemovedDirs,$Temp;
    } elsif ( ($Date, $IP,$FileSize,$FileName,$Direction,$AccessMode,$User) = 
          ( $ThisLine =~ /^(... ... .. ..:..:.. ....) \d+ ([^ ]+) (\d+) (.*) . . (.) (.) (.*) ftp . .*$/ ) ) {
       # Handle xferlog format entries too...
@@ -135,9 +159,33 @@
    print "\nTOTAL KB OUT: " . $TotalKBytesOut . "KB (" . $TotalMBytesOut . "MB)\n";
 }
 
-if ( (@DeletedFiles) ) {
-   print "\nDeleted Files:\n";
-   print @DeletedFiles;
+if ( $Detail > 5 ) {
+   if ( $#DeletedFiles >= 0 ) {
+      print "\nDeleted Files: (Total: $TotalDeleted)\n";
+      print @DeletedFiles;
+   }
+   if ( $#FailedDeletedFiles >= 0) {
+      print "\n Failed Deleted\n";
+      print @FailedDeletedFiles;
+   } 
+
+   if ( $#CreatedDirs >= 0 ) {
+      print "\nCreated Directories: (Total: $TotalCreatedDirs)\n";
+      print @CreatedDirs;
+   }
+   if ( $#FailedCreatedDirs >= 0) {
+      print "\n Failed to create Directories\n";
+      print @FailedCreatedFiles;
+   }
+
+   if ( $#RemovedDirs >= 0 ) {
+      print "\nRemoved Directories: (Total: $TotalRemovedDirs)\n";
+      print @RemovedDirs;
+   }
+   if ( $#FailedRemovedDirs >= 0) {
+      print "\n Failed to remove Directories\n";
+      print @FailedRemovedFiles;
+   }
 }
 
 if (($#OtherList >= 0) and (not $IgnoreUnmatched)){
sshd.patch (text/x-patch, 2.7 KB)
--- sshd	2009-06-10 21:48:39.000000000 +0200
+++ /home/general/Projekte/sshd.new	2009-06-10 22:15:07.000000000 +0200
@@ -207,6 +207,8 @@
 my %LockedAccount = ();
 my %AllowUsers = ();
 my %AllowGroups = ();
+my %DenyUsers = ();
+my %DenyGroups = ();
 my %NoShellUsers = ();
 my %ShellNotExecutableUsers = ();
 my %DeprecatedOption = ();
@@ -353,9 +355,9 @@
       $BadLogins{$Host}{"$User/$Method"}++;
    } elsif ($ThisLine =~ s/^(log: )?Could not reverse map address ([^ ]*).*$/$2/) {
       $NoRevMap{$ThisLine}++;
-   } elsif ( my ($Address) = ($ThisLine =~ /^reverse mapping checking getaddrinfo for ([^ ]*) failed - POSSIBLE BREAK-?IN ATTEMPT!/)) {
+   } elsif ( my ($Address) = ($ThisLine =~ /^reverse mapping checking getaddrinfo for ([^ ]*(?: [^ ]*)?) failed - POSSIBLE BREAK-IN ATTEMPT!/)) {
       $NoRevMap{$Address}++;
-   } elsif ( my ($IP,$Address) = ($ThisLine =~ /^Address ([^ ]*) maps to ([^ ]*), but this does not map back to the address - POSSIBLE BREAK-?IN ATTEMPT!/)) {
+   } elsif ( my ($IP,$Address) = ($ThisLine =~ /^Address ([^ ]*) maps to ([^ ]*), but this does not map back to the address - POSSIBLE BREAK-IN ATTEMPT!/)) {
       $NoRevMap{"$Address($IP)"}++;
    } elsif ( my (undef,$Address) = ($ThisLine =~ /^warning: ([^ ]*), line \d+: can't verify hostname: getaddrinfo\(([^ ]*), AF_INET\) failed$/)) {
       $NoRevMap{$Address}++;
@@ -392,6 +394,10 @@
       $AllowUsers{$User}++;
    } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) from ([^ ]*) not allowed because none of user's groups are listed in AllowGroups/)) {
       $AllowGroups{$User}++;    
+   } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) from ([^ ]*) not allowed because listed in DenyUsers/)) {
+      $DenyUsers{$User}++;
+   } elsif ( my ($User) = ($ThisLine =~ /^User ([^ ]*) from ([^ ]*) not allowed because a group is listed in DenyGroups/)) {
+      $DenyGroups{$User}++;
    } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) does not exist/)) {
       $NoShellUsers{$User}++;
    } elsif ( ($User) = ($ThisLine =~ /^User ([^ ]*) not allowed because shell (\S+) is not executable/)) {
@@ -568,6 +574,20 @@
    }
 }
 
+if (keys %DenyUsers) {
+   print "\nLogin attempted when in DenyUsers list:\n";
+   foreach my $User (sort {$a cmp $b} keys %DenyUsers) {
+      print "   $User : $DenyUsers{$User} Time(s)\n";
+   }
+}
+
+if (keys %DenyGroups) {
+   print "\nLogin attempted when in DenyGroups list:\n";
+   foreach my $User (sort {$a cmp $b} keys %DenyGroups) {
+      print "   $User : $DenyGroups{$User} Time(s)\n";
+   }
+}
+
 if (keys %NoShellUsers) {
    print "\nLogin attempted when shell does not exist:\n";
    foreach my $User (sort {$a cmp $b} keys %NoShellUsers) {
pam_unix.patch (text/x-patch, 1.8 KB)
--- pam_unix	2008-03-25 00:31:26.000000000 +0100
+++ /home/general/Projekte/pam_unix.new	2009-06-11 01:27:20.000000000 +0200
@@ -149,10 +149,10 @@
 	}
    #lowercase the service 
    $service = lc($service); 
-	if (($service =~ /ssh(|d)/) or ($service eq 'login') or ($service eq 'ftp') or ($service eq 'rsh') or 
-	    ($service eq 'remote') or ($service eq 'rlogin') or ($service eq 'rexec')) {
-		if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
-			($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
+   if (($service =~ /ssh(|d)/) or ($service eq 'login') or ($service eq 'ftp') or ($service eq 'vsftpd') or 
+	($service eq 'rsh') or($service eq 'remote') or ($service eq 'rlogin') or ($service eq 'rexec')) {
+      if ($line =~ s/^session opened for user (.+) by \(uid=\d+\)/$1/) {
+	 ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
       } elsif ($line =~ s/^session opened for user ([^ ]*) by ([^ ]*)\(uid=\d+\)/$1 by $2/) {
          ($Detail >= 5) && $data{$service}{'Sessions Opened'}{$line}++;
 		} elsif ($line =~ s/^session opened for user (.+) by LOGIN\(uid=\d+\)/$1/) {
@@ -165,6 +165,8 @@
          $data{$service}{'Authentication Failures'}{$line}++;
       } elsif ($line =~ s/^authentication failure; logname=(\S*) uid=(\d+) .*user=(\S*)$/$1($2) -> $3/) {
          $data{$service}{'Authentication Failures'}{$line}++;
+      } elsif ($line =~ s/^authentication failure; logname=(\S*) .*rhost=(\S*)\s+user=(\S*)$/($3 or $1)($2): /) {
+         $data{$service}{'Authentication Failures'}{$line}++;
       } elsif ($line =~ s/^(\d+) more authentication failure; .*rhost=(\S*)\s+user=(\S*)$/$3 ($2)/) {
          $data{$service}{'Authentication Failures'}{$line} += $1;
       } elsif ($line =~ s/^(\d+) more authentication failure; .*rhost=(\S*)$/unknown ($2)/) {
dhcpd.patch (text/x-patch, 591 B)
--- logwatch/scripts/services/dhcpd	2008-04-30 19:15:14.000000000 +0200
+++ dhcpd.new	2008-12-12 20:27:11.000000000 +0100
@@ -57,7 +57,8 @@
       ($line =~ /^Abandoning IP address/) or
       ($line =~ /^Unable to add (forward|reverse) map/) or
       ($line =~ /^Can\'t update (forward|reverse) map/) or
-      ($line =~ /^pool [0-9a-f]+ /)
+      ($line =~ /^pool [0-9a-f]+ /) or
+      ($line =~ /^Not searching LDAP since ldap-server, ldap-port and ldap-base-dn were not specified in the config file/)
       ) {
       # Ignore these lines
    } elsif ($line =~ s/Listening on\s+//) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.