Index: src/java/org/apache/james/transport/mailets/NotifyPostmaster.java
===================================================================
RCS file: /home/cvspublic/jakarta-james/src/java/org/apache/james/transport/mailets/NotifyPostmaster.java,v
retrieving revision 1.9
diff -u -r1.9 NotifyPostmaster.java
--- src/java/org/apache/james/transport/mailets/NotifyPostmaster.java	29 Sep 2002 00:09:46 -0000	1.9
+++ src/java/org/apache/james/transport/mailets/NotifyPostmaster.java	4 Oct 2002 17:30:11 -0000
@@ -33,13 +33,20 @@
 /**
  * Sends an error message to the sender of a message (that's typically landed in
  * the error mail repository).  You can optionally specify a sender of the error
- * message.  If you do not specify one, it will use the postmaster's address
+ * message.  If you do not specify one, it will use the postmaster's address.
+ * To detect notifaction loops, which occur when a notification is created in
+ * response to a notification, you can use a special header given as the
+ * raiseHeader parameter. The header will receive an successivly increased 
+ * integer value beginning with 1. If no raiseHeader init parameter is specified
+ * this feature is disabled. Use this feature in conjuction with the
+ * HeaderSmallerThan matcher.
  *
  * Sample configuration:
  * <mailet match="All" class="NotifyPostmaster">
  *   <sendingAddress>nobounce@localhost</sendingAddress>
  *   <attachStackTrace>true</attachStackTrace>
  *   <notice>Notice attached to the message (optional)</notice>
+ *   <raiseHeader>X-Notify-Depth</raiseHeader>
  * </mailet>
  *
  * @author  Serge Knystautas <sergek@lokitech.com>
@@ -65,6 +72,17 @@
     String noticeText = null;
 
     /**
+     * This is the name of a header containing an integer number.
+     * The value will be raised by one on the notification mail.
+     * A value of 0 is assumed if the header was not set (or not a
+     * positive integer) on the original mail. The header needs to 
+     * start with "X-". This parameter in conjuction with the
+     * HeaderSmallerThan matcher can be used to gain some control
+     * over notification loops.
+     */
+    String raiseHeader = null;
+
+    /**
      * The date format object used to generate RFC 822 compliant date headers
      */
     private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
@@ -90,6 +108,11 @@
         } catch (Exception e) {
             // Ignore exception, default to false
         }
+        raiseHeader = getInitParameter("raiseHeader");
+        if (raiseHeader != null && !raiseHeader.startsWith("X-")) {
+            log("header to set must begin with 'X-'. Will not raise '"+raiseHeader+"'!");
+            raiseHeader = null;
+        }
     }
 
     /**
@@ -219,6 +242,10 @@
         }
         reply.setHeader(RFC2822Headers.IN_REPLY_TO, message.getMessageID());
 
+        if (raiseHeader!=null) {
+            reply.setHeader(raiseHeader,raiseHeader(message.getHeader(raiseHeader,null)));
+        }       
+
         //Send it off...
         getMailetContext().sendMail(notifier, recipients, reply);
     }
@@ -231,5 +258,27 @@
     public String getMailetInfo() {
         return "NotifyPostmaster Mailet";
     }
+
+    /**
+     * Raises the integer header (passed as String) by one and returns it as String.
+     * null, any negative or not integer value is treated as 0. This Function is used
+     * to raise the value of the header passed as raiseHeader init parameter.
+     *
+     * @param header integer to increase by one
+     * @return header argument increased by one
+     */
+    private static final String raiseHeader(String header) {
+        if (header==null) {
+            return "1";
+        }
+        int value = 0;
+        try {
+            value = Math.max(0,Integer.parseInt(header));
+        } catch (NumberFormatException nfe) {
+            value = 0;
+        }
+        return String.valueOf(value++);
+    }
+
 }
 
Index: src/java/org/apache/james/transport/mailets/NotifySender.java
===================================================================
RCS file: /home/cvspublic/jakarta-james/src/java/org/apache/james/transport/mailets/NotifySender.java,v
retrieving revision 1.10
diff -u -r1.10 NotifySender.java
--- src/java/org/apache/james/transport/mailets/NotifySender.java	29 Sep 2002 00:09:46 -0000	1.10
+++ src/java/org/apache/james/transport/mailets/NotifySender.java	4 Oct 2002 17:30:11 -0000
@@ -32,13 +32,20 @@
 /**
  * Sends an error message to the sender of a message (that's typically landed in
  * the error mail repository).  You can optionally specify a sender of the error
- * message.  If you do not specify one, it will use the postmaster's address
+ * message.  If you do not specify one, it will use the postmaster's address.
+ * To detect notifaction loops, which occur when a notification is created in
+ * response to a notification, you can use a special header given as the
+ * raiseHeader parameter. The header will receive an successivly increased 
+ * integer value beginning with 1. If no raiseHeader init parameter is specified
+ * this feature is disabled. Use this feature in conjuction with the
+ * HeaderSmallerThan matcher.
  *
  * Sample configuration:
  * <mailet match="All" class="NotifySender">
  *   <sendingAddress>nobounce@localhost</sendingAddress>
  *   <attachStackTrace>true</attachStackTrace>
  *   <notice>Notice attached to the message (optional)</notice>
+ *   <raiseHeader>X-Notify-Depth</raiseHeader>
  * </mailet>
  *
  * @author  Serge Knystautas <sergek@lokitech.com>
@@ -64,6 +71,17 @@
     String noticeText = null;
 
     /**
+     * This is the name of a header containing an integer number.
+     * The value will be raised by one on the notification mail.
+     * A value of 0 is assumed if the header was not set (or not a
+     * positive integer) on the original mail. The header needs to 
+     * start with "X-". This parameter in conjuction with the
+     * HeaderSmallerThan matcher can be used to gain some control
+     * over notification loops.
+     */
+    String raiseHeader = null;
+
+    /**
      * The date format object used to generate RFC 822 compliant date headers
      */
     private RFC822DateFormat rfc822DateFormat = new RFC822DateFormat();
@@ -89,6 +107,11 @@
         } catch (Exception e) {
             // Ignore exception, default to false
         }
+        raiseHeader = getInitParameter("raiseHeader");
+        if (raiseHeader != null && !raiseHeader.startsWith("X-")) {
+            log("header to set must begin with 'X-'. Will not raise '"+raiseHeader+"'!");
+            raiseHeader = null;
+        }
     }
 
     /**
@@ -204,6 +227,10 @@
         }
         reply.setHeader(RFC2822Headers.IN_REPLY_TO, message.getMessageID());
 
+        if (raiseHeader!=null) {
+            reply.setHeader(raiseHeader,raiseHeader(message.getHeader(raiseHeader,null)));
+        }       
+
         //Send it off...
         getMailetContext().sendMail(notifier, recipients, reply);
     }
@@ -215,6 +242,27 @@
      */
     public String getMailetInfo() {
         return "NotifySender Mailet";
+    }
+
+    /**
+     * Raises the integer header (passed as String) by one and returns it as String.
+     * null, any negative or not integer value is treated as 0. This Function is used
+     * to raise the value of the header passed as raiseHeader init parameter.
+     *
+     * @param header integer to increase by one
+     * @return header argument increased by one
+     */
+    private static final String raiseHeader(String header) {
+        if (header==null) {
+            return "1";
+        }
+        int value = 0;
+        try {
+            value = Math.max(0,Integer.parseInt(header));
+        } catch (NumberFormatException nfe) {
+            value = 0;
+        }
+        return String.valueOf(value++);
     }
 }
 

