--- orig-mod_log_mysql.c	Fri Nov 21 14:22:06 1997
+++ mod_log_mysql.c	Mon Jul 19 14:39:39 2004
@@ -61,10 +61,11 @@
 
 
 #include "httpd.h"
 #include "http_config.h"
 #include "http_core.h"
+#include <ctype.h>
 #include <time.h>
 #include <mysql/mysql.h>
 
 module mysql_log_module;
 MYSQL log_sql_server, *mysql_log=NULL;
@@ -77,10 +78,11 @@
 
 typedef char *(*item_key_func)(request_rec *, char *);
 typedef struct {
     char *referer_table_name,*agent_table_name,*transfer_table_name;
     array_header *referer_ignore_list;
+    array_header *referer_ignore_status_list;
     array_header *transfer_ignore_list;
     char *transfer_log_format;
 } log_mysql_state;
 
 
@@ -395,10 +397,11 @@
     log_mysql_state *cls =
       (log_mysql_state *)palloc (p, sizeof (log_mysql_state));
 
     cls->referer_table_name = cls->agent_table_name = cls->transfer_table_name = "";
     cls->referer_ignore_list = make_array(p, 1, sizeof(char *));
+    cls->referer_ignore_status_list = make_array(p, 1, sizeof(int));
     cls->transfer_ignore_list = make_array(p, 1, sizeof(char *));
     cls->transfer_log_format = "";
     return (void *)cls;
 }
 
@@ -472,10 +475,28 @@
   addme = push_array(cls->referer_ignore_list);
   *addme = pstrdup(cls->referer_ignore_list->pool, arg);
   return NULL;
 }
 
+const char *add_referer_mysql_ignore_status (cmd_parms *parms, void *dummy, char *arg)
+{
+  int *addme;
+  log_mysql_state *cls = get_module_config (parms->server->module_config,
+					      &mysql_log_module);
+
+  while(isdigit(*arg)) {
+    addme = push_array(cls->referer_ignore_status_list);
+    *addme = strtol(arg,&arg,10);
+    if(','==*arg)
+      arg++;
+  }
+  if(*arg) {
+    return "Invalid RefererIgnoreStatus argument";
+  }
+  return NULL;
+}
+
 const char *add_transfer_mysql_ignore (cmd_parms *parms, void *dummy, char *arg)
 {
   char **addme;
   log_mysql_state *cls = get_module_config (parms->server->module_config,
 					      &mysql_log_module);
@@ -494,10 +515,12 @@
     "the table of the transfer log" },
 { "TransferLogMySQLFormat", set_transfer_log_format, NULL, RSRC_CONF, TAKE1,
     "specific format for the MySQL transfer log"},
 { "RefererIgnore", add_referer_mysql_ignore, NULL, RSRC_CONF, ITERATE,
     "referer hostnames to ignore" },
+{ "RefererIgnoreStatus", add_referer_mysql_ignore_status, NULL, RSRC_CONF, ITERATE,
+    "statuses to ignore for referer log" },
 { "TransferIgnore", add_transfer_mysql_ignore, NULL, RSRC_CONF, ITERATE,
     "transfer log hostnames to ignore" },
 { "LogMySQLDB", set_log_mysql_db, NULL, RSRC_CONF, TAKE1,
 	"the database of the referer log" },
 { "LogMySQLInfo", set_log_mysql_info, NULL, RSRC_CONF, TAKE3,
@@ -563,10 +586,11 @@
 
 
 int log_mysql_transaction(request_rec *orig)
 {
     char **ptrptr, **ptrptr2;
+    int *intptr, *intptr2;
     log_mysql_state *cls = get_module_config (orig->server->module_config,
 					       &mysql_log_module);
     char *str;
     char *referer;
     request_rec *r;
@@ -597,10 +621,22 @@
       if(referer != NULL) {
         /* The following is an upsetting mess of pointers, I'm sorry
            Anyone with the motiviation and/or the time should feel free
            to make this cleaner... */
 
+        intptr2 = (int *) (cls->referer_ignore_status_list->elts + 
+                          (cls->referer_ignore_status_list->nelts *
+                          cls->referer_ignore_status_list->elt_size));
+
+        for(intptr = (int *) cls->referer_ignore_status_list->elts;
+          intptr < intptr2;
+          intptr = (int *)((char *)intptr + cls->referer_ignore_status_list->elt_size)) {
+ 	  if(r->status==*intptr) {
+            goto afterreflog;
+          }
+        }
+
          ptrptr2 = (char **) (cls->referer_ignore_list->elts + 
                              (cls->referer_ignore_list->nelts *
                              cls->referer_ignore_list->elt_size));
 	  
         /* Go through each element of the ignore list and compare it to the
@@ -608,19 +644,22 @@
 
         for(ptrptr = (char **) cls->referer_ignore_list->elts;
           ptrptr < ptrptr2;
           ptrptr = (char **)((char *)ptrptr + cls->referer_ignore_list->elt_size)) {
  	  if(strstr(referer, *ptrptr)) {
-            return OK;
+            goto afterreflog;
           }
         }
-        str = pstrcat(orig->pool, "insert into ", cls->referer_table_name, " (referer,url,time_stamp) values ('",
-                      mysql_escape_log(referer,orig->pool), "','", mysql_escape_log(r->uri,orig->pool),
+        str = pstrcat(orig->pool, "replace into ", cls->referer_table_name,
+                      " (referer,url,time_stamp) values ('",
+                      mysql_escape_log(referer,orig->pool), "','",
+                      mysql_escape_log(orig->uri,orig->pool),
                       "',unix_timestamp(now()) )", NULL);
         safe_mysql_query(orig,str);
       }
     }
+afterreflog:
     if (agent_needed) {	/* log agent */
       char *agent,*str;
       retvalue=OK;
       agent = table_get(orig->headers_in, "User-Agent");
       if(agent != NULL) {
