Index: ChangeLog
===================================================================
--- ChangeLog	(revision 95474d77b95d322778b31415b2c82ac723b35fa8)
+++ ChangeLog	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -11,4 +11,13 @@
 	  readable.  Still prints an error either way if zephyr reports a
 	  failure. [BZ 19]
+	Fixed some small memory leaks in logging if files unwriteable
+	If the variable logfilter is set it names a filter.  Any messages
+	  matching this filter are logged.  This is an independent
+	  mechanism from the other logging variables.  If you want to
+	  control all logging with logfilter the other variables must be
+	  set to their default (off) settings. [BZ 37]
+	Relatively substantial changes made under the hood to support
+	  filter logging.  Now have more consistent interfaces to
+	  creating messages etc.  Still needs more work though.
 
 2.1.10
Index: filter.c
===================================================================
--- filter.c	(revision 32eed9803319874c26a2ba1bbc83e1fb38e8d50d)
+++ filter.c	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -160,4 +160,7 @@
 }
 
+/* return 1 if the message matches the given filter, otherwise
+ * return 0.
+ */
 int owl_filter_message_match(owl_filter *f, owl_message *m)
 {
Index: functions.c
===================================================================
--- functions.c	(revision 95474d77b95d322778b31415b2c82ac723b35fa8)
+++ functions.c	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -164,34 +164,69 @@
 }
 
-void owl_function_adminmsg(char *header, char *body)
-{
-  owl_message *m;
-  int followlast;
-
-  followlast=owl_global_should_followlast(&g);
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_admin(m, header, body);
+
+/* Add the given message to Owl's internal queue.  If displayoutgoing
+ * is disabled, the message is NOT added to any internal queue, -1 is
+ * returned and THE CALLER IS EXPECTED TO FREE THE GIVEN MESSAGE.
+ * Otherwise 0 is returned and the caller need do nothing more
+ */
+int owl_function_add_message(owl_message *m)
+{
+  /* if displayoutgoing is disabled, nuke the message and move on */
+  if (! owl_global_is_displayoutgoing(&g)) {
+    return(-1);
+  }
+
+  /* add it to the global list and current view */
   owl_messagelist_append_element(owl_global_get_msglist(&g), m);
   owl_view_consider_message(owl_global_get_current_view(&g), m);
 
-  if (followlast) owl_function_lastmsg_noredisplay();
-
+  /* do followlast if necessary */
+  if (owl_global_should_followlast(&g)) owl_function_lastmsg_noredisplay();
+
+  /* redisplay etc. */
   owl_mainwin_redisplay(owl_global_get_mainwin(&g));
   if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
     owl_popwin_refresh(owl_global_get_popwin(&g));
   }
-  
   wnoutrefresh(owl_global_get_curs_recwin(&g));
   owl_global_set_needrefresh(&g);
-}
-
-void owl_function_make_outgoing_zephyr(char *body, char *zwriteline, char *zsig)
+  return(0);
+}
+
+/* Create an admin message, append it to the global list of messages
+ * and redisplay if necessary.
+ */
+void owl_function_adminmsg(char *header, char *body)
 {
   owl_message *m;
-  int followlast;
+
+  m=owl_malloc(sizeof(owl_message));
+  owl_message_create_admin(m, header, body);
+  
+  /* add it to the global list and current view */
+  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
+  owl_view_consider_message(owl_global_get_current_view(&g), m);
+
+  /* do followlast if necessary */
+  if (owl_global_should_followlast(&g)) owl_function_lastmsg_noredisplay();
+
+  /* redisplay etc. */
+  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
+  if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
+    owl_popwin_refresh(owl_global_get_popwin(&g));
+  }
+  wnoutrefresh(owl_global_get_curs_recwin(&g));
+  owl_global_set_needrefresh(&g);
+}
+
+/* Create an outgoing zephyr message and return a pointer to it.  Does
+ * not put it on the global queue, use owl_function_add_message() for
+ * that.
+ */
+owl_message *owl_function_make_outgoing_zephyr(char *body, char *zwriteline, char *zsig)
+{
+  owl_message *m;
   owl_zwrite z;
   
-  followlast=owl_global_should_followlast(&g);
-
   /* create a zwrite for the purpose of filling in other message fields */
   owl_zwrite_create_from_line(&z, zwriteline);
@@ -200,34 +235,21 @@
   m=owl_malloc(sizeof(owl_message));
   owl_message_create_from_zwriteline(m, zwriteline, body, zsig);
-
-  /* add it to the global list and current view */
-  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
-  owl_view_consider_message(owl_global_get_current_view(&g), m);
-
-  if (followlast) owl_function_lastmsg_noredisplay();
-
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-    owl_popwin_refresh(owl_global_get_popwin(&g));
-  }
+  owl_zwrite_free(&z);
+
+  return(m);
+}
+
+/* Create an outgoing AIM message, returns a pointer to the created
+ * message or NULL if we're not logged into AIM (and thus unable to
+ * create the message).  Does not put it on the global queue.  Use
+ * owl_function_add_message() for that .
+ */
+owl_message *owl_function_make_outgoing_aim(char *body, char *to)
+{
+  owl_message *m;
+
+  /* error if we're not logged into aim */
+  if (!owl_global_is_aimloggedin(&g)) return(NULL);
   
-  wnoutrefresh(owl_global_get_curs_recwin(&g));
-  owl_global_set_needrefresh(&g);
-  owl_zwrite_free(&z);
-}
-
-int owl_function_make_outgoing_aim(char *body, char *to)
-{
-  owl_message *m;
-  int followlast;
-
-
-  if (!owl_global_is_aimloggedin(&g)) {
-    return(-1);
-  }
-  
-  followlast=owl_global_should_followlast(&g);
-
-  /* create the message */
   m=owl_malloc(sizeof(owl_message));
   owl_message_create_aim(m,
@@ -237,27 +259,14 @@
 			 OWL_MESSAGE_DIRECTION_OUT,
 			 0);
-
-  /* add it to the global list and current view */
-  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
-  owl_view_consider_message(owl_global_get_current_view(&g), m);
-
-  if (followlast) owl_function_lastmsg_noredisplay();
-
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-    owl_popwin_refresh(owl_global_get_popwin(&g));
-  }
-  
-  wnoutrefresh(owl_global_get_curs_recwin(&g));
-  owl_global_set_needrefresh(&g);
-  return(0);
-}
-
-int owl_function_make_outgoing_loopback(char *body)
+  return(m);
+}
+
+/* Create an outgoing loopback message and return a pointer to it.
+ * Does not append it to the global queue, use
+ * owl_function_add_message() for that.
+ */
+owl_message *owl_function_make_outgoing_loopback(char *body)
 {
   owl_message *m;
-  int followlast;
-
-  followlast=owl_global_should_followlast(&g);
 
   /* create the message */
@@ -266,18 +275,5 @@
   owl_message_set_direction_out(m);
 
-  /* add it to the global list and current view */
-  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
-  owl_view_consider_message(owl_global_get_current_view(&g), m);
-
-  if (followlast) owl_function_lastmsg_noredisplay();
-
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-    owl_popwin_refresh(owl_global_get_popwin(&g));
-  }
-  
-  wnoutrefresh(owl_global_get_curs_recwin(&g));
-  owl_global_set_needrefresh(&g);
-  return(0);
+  return(m);
 }
 
@@ -386,6 +382,6 @@
 {
   owl_zwrite z;
-  int i, j;
   char *mymsg;
+  owl_message *m;
 
   /* create the zwrite and send the message */
@@ -394,20 +390,21 @@
     owl_zwrite_set_message(&z, msg);
   }
-
   owl_zwrite_send_message(&z);
   owl_function_makemsg("Waiting for ack...");
 
-  mymsg=owl_zwrite_get_message(&z);
-
-  /* display the message as an outgoing message in the receive window */
-  if (owl_global_is_displayoutgoing(&g) && owl_zwrite_is_personal(&z)) {
-    owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
-  }
-
-  /* log it if we have logging turned on */
-  if (owl_global_is_logging(&g) && owl_zwrite_is_personal(&z)) {
-    j=owl_zwrite_get_numrecips(&z);
-    for (i=0; i<j; i++) {
-      owl_log_outgoing_zephyr(owl_zwrite_get_recip_n(&z, i), mymsg);
+  /* If it's personal */
+  if (owl_zwrite_is_personal(&z)) {
+    /* create the outgoing message */
+    mymsg=owl_zwrite_get_message(&z);
+    m=owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
+
+    /* log it */
+    owl_log_message(m);
+
+    /* add it or nuke it */
+    if (owl_global_is_displayoutgoing(&g)) {
+      owl_function_add_message(m);
+    } else {
+      owl_message_free(m);
     }
   }
@@ -423,7 +420,7 @@
 {
   owl_zwrite z;
-  int i, j;
   char *mymsg;
   char *cryptmsg;
+  owl_message *m;
 #ifdef OWL_ENABLE_ZCRYPT
   int ret;
@@ -457,14 +454,18 @@
   owl_function_makemsg("Waiting for ack...");
 
-  /* display the message as an outgoing message in the receive window */
-  if (owl_global_is_displayoutgoing(&g) && owl_zwrite_is_personal(&z)) {
-    owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
-  }
-
-  /* log it if we have logging turned on */
-  if (owl_global_is_logging(&g) && owl_zwrite_is_personal(&z)) {
-    j=owl_zwrite_get_numrecips(&z);
-    for (i=0; i<j; i++) {
-      owl_log_outgoing_zephyr(owl_zwrite_get_recip_n(&z, i), mymsg);
+  /* If it's personal */
+  if (owl_zwrite_is_personal(&z)) {
+    /* create the outgoing message */
+    mymsg=owl_zwrite_get_message(&z);
+    m=owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
+    
+    /* log it */
+    owl_log_message(m);
+    
+    /* add it or nuke it */
+    if (owl_global_is_displayoutgoing(&g)) {
+      owl_function_add_message(m);
+    } else {
+      owl_message_free(m);
     }
   }
@@ -479,4 +480,5 @@
   int ret;
   char *msg, *format_msg;
+  owl_message *m;
 
   /* make a formatted copy of the message */
@@ -493,12 +495,15 @@
   }
 
-  /* display the message as an outgoing message in the receive window */
+  /* create the outgoing message */
+  m=owl_function_make_outgoing_aim(msg, to);
+
+  /* log it */
+  owl_log_message(m);
+
+  /* display it or nuke it */
   if (owl_global_is_displayoutgoing(&g)) {
-    owl_function_make_outgoing_aim(msg, to);
-  }
-
-  /* log it if we have logging turned on */
-  if (owl_global_is_logging(&g)) {
-    owl_log_outgoing_aim(to, msg);
+    owl_function_add_message(m);
+  } else {
+    owl_message_free(m);
   }
 
@@ -510,4 +515,5 @@
   int ret;
   char *format_msg;
+  owl_message *m;
 
   /* make a formatted copy of the message */
@@ -523,14 +529,19 @@
   }
 
-  /* display the message as an outgoing message in the receive window */
-  if (owl_global_is_displayoutgoing(&g)) {
-    owl_function_make_outgoing_aim(msg, to);
-  }
-
-  /* log it if we have logging turned on */
-  if (owl_global_is_logging(&g)) {
-    owl_log_outgoing_aim(to, msg);
-  }
-
+  /* create the message */
+  m=owl_function_make_outgoing_aim(msg, to);
+  if (m) {
+    /* log it */
+    owl_log_message(m);
+
+    /* display it or nuke it */
+    if (owl_global_is_displayoutgoing(&g)) {
+      owl_function_add_message(m);
+    } else {
+      owl_message_free(m);
+    }
+  } else {
+    owl_function_error("Could not create AIM message");
+  }
   owl_free(format_msg);
 }
@@ -538,25 +549,23 @@
 void owl_function_loopwrite()
 {
-  owl_message *m;
+  owl_message *min, *mout;
 
   /* create a message and put it on the message queue.  This simulates
    * an incoming message */
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_loopback(m, owl_editwin_get_text(owl_global_get_typwin(&g)));
-  owl_message_set_direction_in(m);
-  owl_global_messagequeue_addmsg(&g, m);
-
-  /* display the message as an outgoing message in the receive window */
+  min=owl_malloc(sizeof(owl_message));
+  owl_message_create_loopback(min, owl_editwin_get_text(owl_global_get_typwin(&g)));
+  owl_message_set_direction_in(min);
+  owl_global_messagequeue_addmsg(&g, min);
+
+  mout=owl_function_make_outgoing_loopback(owl_editwin_get_text(owl_global_get_typwin(&g)));
+  owl_log_message(mout);
   if (owl_global_is_displayoutgoing(&g)) {
-    owl_function_make_outgoing_loopback(owl_editwin_get_text(owl_global_get_typwin(&g)));
+    owl_function_add_message(mout);
+  } else {
+    owl_message_free(mout);
   }
 
   /* fake a makemsg */
   owl_function_makemsg("loopback message sent");
-
-  /* log it if we have logging turned on */
-  if (owl_global_is_logging(&g)) {
-    owl_log_outgoing_loopback(owl_editwin_get_text(owl_global_get_typwin(&g)));
-  }
 }
 
Index: logging.c
===================================================================
--- logging.c	(revision debb15d0815787026eb479f6e2b011f9b8bd0f8c)
+++ logging.c	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -7,33 +7,97 @@
 static const char fileIdent[] = "$Id$";
 
-void owl_log_outgoing_zephyr(char *to, char *text)
+/* This is now the one function that should be called to log a
+ * message.  It will do all the work necessary by calling the other
+ * functions in this file as necessary.
+ */
+void owl_log_message(owl_message *m) {
+  owl_function_debugmsg("owl_log_message: entering");
+
+  /* should we be logging this message? */
+  if (!owl_log_shouldlog_message(m)) {
+    owl_function_debugmsg("owl_log_message: not logging message");
+    return;
+  }
+
+  /* handle incmoing messages */
+  if (owl_message_is_direction_in(m)) {
+    owl_log_incoming(m);
+    owl_function_debugmsg("owl_log_message: leaving");
+    return;
+  }
+
+  /* handle outgoing messages */
+  if (owl_message_is_type_aim(m)) {
+    owl_log_outgoing_aim(m);
+  } else if (owl_message_is_type_zephyr(m)) {
+    owl_log_outgoing_zephyr(m);
+  } else if (owl_message_is_type_loopback(m)) {
+    owl_log_outgoing_loopback(m);
+  } else {
+    owl_function_error("Unknown message type for logging");
+  }
+  owl_function_debugmsg("owl_log_message: leaving");
+}
+
+/* Return 1 if we should log the given message, otherwise return 0 */
+int owl_log_shouldlog_message(owl_message *m) {
+  owl_filter *f;
+
+  /* If there's a logfilter and this message matches it, log */
+  f=owl_global_get_filter(&g, owl_global_get_logfilter(&g));
+  if (f && owl_filter_message_match(f, m)) return(1);
+
+  /* otherwise we do things based on the logging variables */
+
+  /* skip login/logout messages if appropriate */
+  if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
+      
+  /* check for nolog */
+  if (!strcasecmp(owl_message_get_opcode(m), "nolog") || !strcasecmp(owl_message_get_instance(m), "nolog")) return(0);
+
+  /* check direction */
+  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
+    return(0);
+  }
+  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) && owl_message_is_direction_in(m)) {
+    return(0);
+  }
+
+  if (owl_message_is_type_zephyr(m)) {
+    if (owl_message_is_personal(m) && !owl_global_is_logging(&g)) return(0);
+    if (!owl_message_is_personal(m) && !owl_global_is_classlogging(&g)) return(0);
+  } else {
+    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
+      if (!owl_global_is_logging(&g)) return(0);
+    } else {
+      if (!owl_global_is_classlogging(&g)) return(0);
+    }
+  }
+  return(1);
+}
+
+void owl_log_outgoing_zephyr(owl_message *m)
 {
   FILE *file;
   char filename[MAXPATHLEN], *logpath;
-  char *tobuff, *ptr="";
-
-  if (owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) return;
-
-  tobuff=owl_malloc(strlen(to)+20);
-  strcpy(tobuff, to);
-
-  /* chop off a local realm */
-  ptr=strchr(tobuff, '@');
-  if (ptr && !strncmp(ptr+1, owl_zephyr_get_realm(), strlen(owl_zephyr_get_realm()))) {
-    *ptr='\0';
-  }
+  char *to, *text;
+
+  /* strip local realm */
+  to=short_zuser(owl_message_get_recipient(m));
 
   /* expand ~ in path names */
-  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", 
-				owl_global_get_homedir(&g));
-
-  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
+  logpath=owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
+
+  text=owl_message_get_body(m);
+
+  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, to);
   file=fopen(filename, "a");
   if (!file) {
     owl_function_error("Unable to open file for outgoing logging");
     owl_free(logpath);
-    return;
-  }
-  fprintf(file, "OUTGOING (owl): %s\n%s\n", tobuff, text);
+    owl_free(to);
+    return;
+  }
+  fprintf(file, "OUTGOING (owl): %s\n%s\n", to, text);
   if (text[strlen(text)-1]!='\n') {
     fprintf(file, "\n");
@@ -46,13 +110,14 @@
   if (!file) {
     owl_function_error("Unable to open file for outgoing logging");
-    return;
-  }
-  fprintf(file, "OUTGOING (owl): %s\n%s\n", tobuff, text);
-  if (text[strlen(text)-1]!='\n') {
-    fprintf(file, "\n");
-  }
-  fclose(file);
-
-  owl_free(tobuff);
+    owl_free(to);
+    return;
+  }
+  fprintf(file, "OUTGOING (owl): %s\n%s\n", to, text);
+  if (text[strlen(text)-1]!='\n') {
+    fprintf(file, "\n");
+  }
+  fclose(file);
+
+  owl_free(to);
 }
 
@@ -61,18 +126,10 @@
   FILE *file;
   char filename[MAXPATHLEN], *logpath;
-  char *tobuff, *ptr="";
-
-  tobuff=owl_malloc(strlen(to)+20);
-  strcpy(tobuff, to);
-
-  /* chop off a local realm */
-  ptr=strchr(tobuff, '@');
-  if (ptr && !strncmp(ptr+1, owl_zephyr_get_realm(), strlen(owl_zephyr_get_realm()))) {
-    *ptr='\0';
-  }
+  char *tobuff;
+
+  tobuff=short_zuser(to);
 
   /* expand ~ in path names */
-  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", 
-				owl_global_get_homedir(&g));
+  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
 
   snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
@@ -81,4 +138,5 @@
     owl_function_error("Unable to open file for outgoing logging");
     owl_free(logpath);
+    owl_free(tobuff);
     return;
   }
@@ -94,4 +152,5 @@
   if (!file) {
     owl_function_error("Unable to open file for outgoing logging");
+    owl_free(tobuff);
     return;
   }
@@ -105,13 +164,14 @@
 }
 
-void owl_log_outgoing_aim(char *to, char *text)
+void owl_log_outgoing_aim(owl_message *m)
 {
   FILE *file;
   char filename[MAXPATHLEN], *logpath;
-  char *tobuff, *normalto;
-
-  if (owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) return;
-
-  normalto=owl_aim_normalize_screenname(to);
+  char *tobuff, *normalto, *text;
+
+  owl_function_debugmsg("owl_log_outgoing_aim: entering");
+
+  /* normalize and downcase the screenname */
+  normalto=owl_aim_normalize_screenname(owl_message_get_recipient(m));
   downstr(normalto);
   tobuff=owl_sprintf("aim:%s", normalto);
@@ -119,7 +179,8 @@
 
   /* expand ~ in path names */
-  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", 
-				owl_global_get_homedir(&g));
-
+  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
+
+  text=owl_message_get_body(m);
+  
   snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
   file=fopen(filename, "a");
@@ -127,4 +188,5 @@
     owl_function_error("Unable to open file for outgoing logging");
     owl_free(logpath);
+    owl_free(tobuff);
     return;
   }
@@ -140,4 +202,5 @@
   if (!file) {
     owl_function_error("Unable to open file for outgoing logging");
+    owl_free(tobuff);
     return;
   }
@@ -151,17 +214,16 @@
 }
 
-void owl_log_outgoing_loopback(char *text)
+void owl_log_outgoing_loopback(owl_message *m)
 {
   FILE *file;
   char filename[MAXPATHLEN], *logpath;
-  char *tobuff;
-
-  if (owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) return;
+  char *tobuff, *text;
 
   tobuff=owl_sprintf("loopback");
 
   /* expand ~ in path names */
-  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", 
-				owl_global_get_homedir(&g));
+  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
+
+  text=owl_message_get_body(m);
 
   snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
@@ -170,4 +232,5 @@
     owl_function_error("Unable to open file for outgoing logging");
     owl_free(logpath);
+    owl_free(tobuff);
     return;
   }
@@ -183,4 +246,5 @@
   if (!file) {
     owl_function_error("Unable to open file for outgoing logging");
+    owl_free(tobuff);
     return;
   }
@@ -201,44 +265,25 @@
   int len, ch, i, personal;
 
-  if (owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) return;
-
-  /* skip login/logout messages if appropriate */
-  if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return;
-      
-  /* check for nolog */
-  if (!strcasecmp(owl_message_get_opcode(m), "nolog") ||
-      !strcasecmp(owl_message_get_instance(m), "nolog")) return;
-
-  /* this is kind of a mess */
+  /* figure out if it's a "personal" message or not */
   if (owl_message_is_type_zephyr(m)) {
     if (owl_message_is_personal(m)) {
       personal=1;
-      if (!owl_global_is_logging(&g)) return;
     } else {
       personal=0;
-      if (!owl_global_is_classlogging(&g)) return;
     }
   } else {
     if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
       personal=1;
-      if (!owl_global_is_logging(&g)) return;
     } else {
       personal=0;
-      if (!owl_global_is_classlogging(&g)) return;
     }
   }
 
   if (owl_message_is_type_zephyr(m)) {
-    /* chop off a local realm for personal zephyr messages */
     if (personal) {
       if (owl_message_is_type_zephyr(m)) {
-	from=frombuff=owl_strdup(owl_message_get_sender(m));
-	ptr=strchr(frombuff, '@');
-	if (ptr && !strncmp(ptr+1, owl_zephyr_get_realm(), strlen(owl_zephyr_get_realm()))) {
-	  *ptr='\0';
-	}
+	from=frombuff=short_zuser(owl_message_get_sender(m));
       }
     } else {
-      /* we assume zephyr for now */
       from=frombuff=owl_strdup(owl_message_get_class(m));
     }
@@ -276,13 +321,10 @@
   /* create the filename (expanding ~ in path names) */
   if (personal) {
-    logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", 
-				  owl_global_get_homedir(&g));
+    logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
     snprintf(filename, MAXPATHLEN, "%s/%s", logpath, from);
     snprintf(allfilename, MAXPATHLEN, "%s/all", logpath);
 
   } else {
-    logpath = owl_text_substitute(owl_global_get_classlogpath(&g), "~", 
-				owl_global_get_homedir(&g));
-
+    logpath = owl_text_substitute(owl_global_get_classlogpath(&g), "~", owl_global_get_homedir(&g));
     snprintf(filename, MAXPATHLEN, "%s/%s", logpath, from);
   }
@@ -292,4 +334,5 @@
   if (!file) {
     owl_function_error("Unable to open file for incoming logging");
+    owl_free(frombuff);
     return;
   }
@@ -300,4 +343,5 @@
     if (!allfile) {
       owl_function_error("Unable to open file for incoming logging");
+      owl_free(frombuff);
       fclose(file);
       return;
Index: owl.c
===================================================================
--- owl.c	(revision 95474d77b95d322778b31415b2c82ac723b35fa8)
+++ owl.c	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -589,7 +589,5 @@
 
       /* log the message if we need to */
-      if (owl_global_is_logging(&g) || owl_global_is_classlogging(&g)) {
-	owl_log_incoming(m);
-      }
+      owl_log_message(m);
     }
 
Index: variable.c
===================================================================
--- variable.c	(revision 213a3eb3100f4ee3951a3133b629757508c9c8c9)
+++ variable.c	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -150,4 +150,13 @@
 	       "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
 	       "login or logout notifications.\n"),
+
+  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
+		 "name of a filter controlling which messages to log",
+
+		 "If non empty, any messages matching the given filter will be logged.\n"
+		 "This is a completely separate mechanisim from the other logging\n"
+		 "variables like logging, classlogging, loglogins, loggingdirection,\n"
+		 "etc.  If you want this variable to control all logging, make sure\n"
+		 "all other logging variables are in their default state.\n"),
 
   OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
Index: zephyr.c
===================================================================
--- zephyr.c	(revision 95474d77b95d322778b31415b2c82ac723b35fa8)
+++ zephyr.c	(revision 15b34fd530d89cbddcaa62daf32db9960bcf3754)
@@ -518,4 +518,5 @@
 #ifdef HAVE_LIBZEPHYR
   char *tmpbuff, *myuser, *to;
+  owl_message *mout;
   
   /* bail if it doesn't look like a message we should reply to.  Some
@@ -554,5 +555,6 @@
 
   /* display the message as an admin message in the receive window */
-  owl_function_make_outgoing_zephyr(owl_global_get_zaway_msg(&g), tmpbuff, "Automated reply:");
+  mout=owl_function_make_outgoing_zephyr(owl_global_get_zaway_msg(&g), tmpbuff, "Automated reply:");
+  owl_function_add_message(mout);
   owl_free(tmpbuff);
 #endif
