--- BlackListPlugin.pm.orig	2005-04-05 11:44:20.358678496 +0200
+++ BlackListPlugin.pm	2005-04-05 11:54:02.215222856 +0200
@@ -47,6 +47,15 @@
     $urlHost = "initialized_later";
 }
 
+sub writeDebug {
+  &TWiki::Func::writeDebug("$pluginName - " . $_[0]) if $debug;
+}
+
+sub writeDebugTimes {
+  &TWiki::Func::writeDebugTimes("$pluginName - " . $_[0]) if $debug;
+}
+
+
 # =========================
 sub initPlugin
 {
@@ -61,6 +70,7 @@
     # get debug flag
     $debug = TWiki::Func::getPreferencesFlag( "\U$pluginName\E_DEBUG" );
 
+
     # initialize for rel="nofollow" links
     $urlHost = TWiki::Func::getUrlHost();
     $noFollowAge = TWiki::Func::getPreferencesValue( "\U$pluginName\E_NOFOLLOWAGE" ) || 0;
@@ -86,6 +96,7 @@
     my $scriptName = $ENV{'SCRIPT_NAME'}   || "";
     my $queryString = $ENV{'QUERY_STRING'} || "";
     my $banList = _handleBanList( "read", $remoteAddr );
+
     $banList = join( "|", map { quotemeta } split( /\n/, $banList ) );
 
     # black list + ban list regular expression
@@ -93,11 +104,12 @@
     $blackRE .= "|" if( $blackList && $banList );
     $blackRE .= "$banList)";
 
+
     # black sheep if in black list unless in white list
     $isBlackSheep = 0;
     $userScore = "N/A";
     if( ( $remoteAddr ) && ( $remoteAddr !~ /^$whiteList/ ) ) {
-        if( $remoteAddr =~ /^$blackRE/ ) {
+        if( $blackRE ne "()" && $remoteAddr =~ /^$blackRE/ ) {
             # already a black sheep
             $isBlackSheep = 1;
         } else {
@@ -112,7 +124,7 @@
             $cfg{ "period" }  = $c6 || 300;
 
             $userScore = _handleEventLog( $remoteAddr, $scriptName, $queryString );
-            TWiki::Func::writeDebug( "- TWiki::Plugins::${pluginName}::initPlugin() score: $userScore" ) if $debug;
+            writeDebug( "initPlugin() score: $userScore" );
             if( $userScore > $cfg{ "ptLimit" } ) {
                 $isBlackSheep = 1;
                 _handleBanList( "add", $remoteAddr );
@@ -130,13 +142,12 @@
             # view script: show message later in commonTagsHandler
         } else {
             # other scripts: force a "500 Internal Server Error" error
-            exit 1;
+            #exit 1;
         }
     }
 
     # Plugin correctly initialized
-    TWiki::Func::writeDebug( "- TWiki::Plugins::${pluginName}::initPlugin( $web.$topic ) is OK, "
-                           . "whiteList $whiteList, blackRE $blackRE" ) if $debug;
+    writeDebug("initPlugin( $web.$topic ) is OK, whiteList $whiteList, blackRE $blackRE");
     return 1;
 }
 
@@ -145,7 +156,7 @@
 {
 ### my ( $text, $topic, $web ) = @_;   # do not uncomment, use $_[0], $_[1]... instead
 
-    TWiki::Func::writeDebug( "- ${pluginName}::commonTagsHandler( $_[2].$_[1] )" ) if $debug;
+    writeDebug( "commonTagsHandler( $_[2].$_[1] )" );
 
     if( $isBlackSheep ) {
         my $message = TWiki::Func::getPreferencesValue( "\U$pluginName\E_BLACKLISTMESSAGE" ) ||
@@ -153,7 +164,7 @@
                     . "In addition, your IP address will be submitted to major blacklist databases.";
         $_[0] = $message;
     }
-    $_[0] =~ s/%BLACKLIST{(.*?)}%/_handleBlackList( $1, $_[2], $_[1] )/geo;
+    $_[0] =~ s/%BLACKLIST{([^}]*)}%/_handleBlackList( $1, $_[2], $_[1] )/geo;
 }
 
 # =========================
@@ -161,7 +172,7 @@
 {
 ### my ( $text ) = @_;   # do not uncomment, use $_[0] instead
 
-    TWiki::Func::writeDebug( "- ${pluginName}::endRenderingHandler( $web.$topic )" ) if $debug;
+    writeDebug( "endRenderingHandler( $web.$topic )" );
 
     # This handler is called by getRenderedVersion just after the line loop, that is,
     # after almost all XHTML rendering of a topic. <nop> tags are removed after this.
@@ -175,34 +186,35 @@
 {
     my( $theAttributes, $theWeb, $theTopic ) = @_;
     my $action = &TWiki::Func::extractNameValuePair( $theAttributes, "action" );
-    my $value  = &TWiki::Func::extractNameValuePair( $theAttributes, "value" );
     my $text = "";
+
     if( $action eq "ban_show" ) {
-        $text = _handleBanList( "read", "" );
-        $text =~ s/[\n\r]+$//os;
-        $text =~ s/[\n\r]+/, /gos;
+	$text = _handleBanList( "read", "" );
+	$text =~ s/[\n\r]+$//os;
+	$text =~ s/[\n\r]+/, /gos;
 
     } elsif( $action eq "user_score" ) {
-        $text = $userScore;
+	$text = $userScore;
 
     } elsif( $action =~ /^(ban_add|ban_remove)$/ ) {
-        if( "$theWeb.$theTopic" eq "$installWeb.$pluginName" ) {
-            my $wikiName = &TWiki::Func::userToWikiName( $user );
-            if(  &TWiki::Func::checkAccessPermission( "CHANGE", $wikiName, "", $pluginName, $installWeb ) ) {
-                if( $action eq "ban_add" ) {
-                    $text = _handleBanList( "add", $value );
-                    _writeLog( "BANLIST add: $value, by user" );
-                } else {
-                    $text = _handleBanList( "remove", $value );
-                    _writeLog( "BANLIST delete: $value by user" );
-                }
-            } else {
-                $text = "Error: You do not have permission to add IP addresses";
-            }
-        } else {
-             $text = "Error: For use on $installWeb.$pluginName topic only";
-        }
-        $text .= " [ [[$theWeb.$theTopic][OK]] ]";
+	if( "$theWeb.$theTopic" eq "$installWeb.$pluginName" ) {
+	    my $wikiName = &TWiki::Func::userToWikiName( $user );
+	    if(  &TWiki::Func::checkAccessPermission( "CHANGE", $wikiName, "", $pluginName, $installWeb ) ) {
+		my $value  = &TWiki::Func::extractNameValuePair( $theAttributes, "value" );
+		if( $action eq "ban_add" ) {
+		    $text .= _handleBanList( "add", $value );
+		    _writeLog( "BANLIST add: $value, by user" );
+		} else {
+		    $text .= _handleBanList( "remove", $value );
+		    _writeLog( "BANLIST delete: $value by user" );
+		}
+	    } else {
+		$text = "Error: You do not have permission to add IP addresses";
+	    }
+	} else {
+	     $text = "Error: For use on $installWeb.$pluginName topic only";
+	}
+	$text .= " [ [[$theWeb.$theTopic][OK]] ]";
     }
     return $text;
 }
@@ -210,36 +222,73 @@
 # =========================
 sub _handleBanList
 {
-    my ( $theAction, $theIP ) = @_;
+    my ( $theAction, $theIPs ) = @_;
     my $fileName = _makeFileName( "ban_list", 0 );
-    TWiki::Func::writeDebug( "- ${pluginName}::_handleBanList( Action: $theAction, IP: $theIP, file: $fileName )" ) if $debug;
+
+    writeDebug( "_handleBanList( Action: $theAction, IPs: $theIPs, file: $fileName )" );
+
     my $text = TWiki::Func::readFile( $fileName ) || "# The ban-list is a generated file, do not edit\n";
+
     if( $theAction eq "read" ) {
         $text =~ s/^\#[^\n]*\n//s;
         return $text;
 
-    } elsif( $theAction eq "add" ) {
-        unless( ( $theIP ) && ( $theIP =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ ) ) {
-            return "Error: Invalid IP address $theIP";
-        }
-        if( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) {
-            return "Error: IP address $theIP is already on the list";
-        }
-        $text .= "$theIP\n";
-        TWiki::Func::saveFile( $fileName, $text );
-        unless( -e "$fileName" ) {
-            # assuming save failed because of missing dir
-            _makeFileDir();
-            TWiki::Func::saveFile( $fileName, $text );
-        }
-        return "Note: Added IP address $theIP";
+    } 
 
-    } elsif( $theAction eq "remove" ) {
-        unless( ( $theIP ) && ( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) ) {
-            return "Error: IP address $theIP not found";
-        }
-        TWiki::Func::saveFile( $fileName, $text );
-        return "Note: Removed IP address $theIP";
+    my @errorMessages;
+    my @infoMessages;
+    foreach my $theIP (split(/,/, $theIPs)) {
+      $theIP =~ s/^\s+//;
+      $theIP =~ s/\s+$//;
+  
+      if( $theAction eq "add" ) {
+      
+	unless( ( $theIP ) && ( $theIP =~ /^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/ ) ) {
+	    push @errorMessages, "Error: Invalid IP address '$theIP'";
+	    next;
+	}
+	
+	if( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) {
+	    push @infoMessages, "Warning: IP address '$theIP' is already on the list";
+	    next;
+	}
+	
+	$text .= "$theIP\n";
+
+	push @infoMessages, "Note: Added IP address '$theIP'";
+
+      } elsif( $theAction eq "remove" ) {
+
+	unless( ( $theIP ) && ( $text =~ s/(\n)\Q$theIP\E\n/$1/s ) ) {
+	    push @errorMessages, "Error: IP address '$theIP' not found";
+	    next;
+	}
+
+	push @infoMessages, "Note: Removed IP address '$theIP'";
+      } else {
+	# never reach
+	return "Error: invalid action '$theAction'";
+      }
+    }
+
+    if (@errorMessages) {
+      writeDebug("banlist=$text");
+      return '<div class="twikiAlert">' .  join("<br/>\n", @errorMessages) . '</div>';
+	
+    } else {
+      if (@infoMessages) {
+	# SMELL: overwrites a concurrent save 
+	writeDebug("banlist=$text");
+	TWiki::Func::saveFile( $fileName, $text );
+	unless( -e "$fileName" ) {
+	    # assuming save failed because of missing dir
+	    _makeFileDir();
+	    TWiki::Func::saveFile( $fileName, $text );
+	}
+	return join("<br/>\n", @infoMessages)
+      } else {
+	return 'Error: done nothing';
+      }
     }
 }
 
@@ -250,7 +299,7 @@
 
     # read/update/save event logs
     my $fileName = _makeFileName( "event_log" );
-    TWiki::Func::writeDebug( "- ${pluginName}::_handleEventLog( IP: $theIP, type: $theType, query: $theQueryString )" ) if $debug;
+    writeDebug( "_handleEventLog( IP: $theIP, type: $theType, query: $theQueryString )" );
     my $text = TWiki::Func::readFile( $fileName ) || "# The event-list is a generated file, do not edit\n";
     my $time = time();
     $text .= "$time, $theIP, $theType";
@@ -326,7 +375,7 @@
     if( TWiki::Func::getPreferencesFlag( "\U$pluginName\E_LOGACCESS" ) ) {
         # FIXME: Call to unofficial function
         TWiki::Store::writeLog( "blacklist", "$web.$topic", $theText );
-        ##TWiki::Func::writeDebug( "BLACKLIST access by $remoteAddr, $web/$topic, $theText" );
+        writeDebug("BLACKLIST access by $remoteAddr, $web/$topic, $theText");
     }
 }
 
