Index: commands.c
===================================================================
--- commands.c	(revision 216c73421653e3ef0e957aa9a9804e208a77c80e)
+++ commands.c	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
@@ -2379,5 +2379,5 @@
   if (argc==2) {
     owl_global_set_buffercommand(&g, argv[1]);
-    owl_global_set_buffercallback(&g, owl_function_aimlogin);
+    owl_global_set_buffercallback(&g, &owl_callback_aimlogin);
     owl_function_start_password("AIM Password: ");
     return(NULL);
Index: functions.c
===================================================================
--- functions.c	(revision 4211f50b3f182f522a14169eaee7c89c03d9c447)
+++ functions.c	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
@@ -320,5 +320,5 @@
 
   owl_global_set_buffercommand(&g, line);
-  owl_global_set_buffercallback(&g, &owl_function_zwrite);
+  owl_global_set_buffercallback(&g, &owl_callback_zwrite);
 }
 
@@ -351,5 +351,5 @@
 
   owl_global_set_buffercommand(&g, line);
-  owl_global_set_buffercallback(&g, &owl_function_aimwrite);
+  owl_global_set_buffercallback(&g, &owl_callback_aimwrite);
 }
 
@@ -376,5 +376,10 @@
 
   owl_global_set_buffercommand(&g, "loopwrite");
-  owl_global_set_buffercallback(&g, &owl_function_loopwrite);
+  owl_global_set_buffercallback(&g, &owl_callback_loopwrite);
+}
+
+void owl_callback_zwrite(owl_editwin *e) {
+  owl_function_zwrite(owl_editwin_get_command(e),
+                      owl_editwin_get_text(e));
 }
 
@@ -486,4 +491,9 @@
 }
 
+void owl_callback_aimwrite(owl_editwin *e) {
+  owl_function_aimwrite(owl_editwin_get_command(e),
+                        owl_editwin_get_text(e));
+}
+
 void owl_function_aimwrite(char *line, char *msg)
 {
@@ -562,5 +572,9 @@
 }
 
-void owl_function_loopwrite(char *line, char *msg)
+void owl_callback_loopwrite(owl_editwin *e) {
+  owl_function_loopwrite(owl_editwin_get_text(e));
+}
+
+void owl_function_loopwrite(char *msg)
 {
   owl_message *min, *mout;
@@ -932,4 +946,9 @@
     owl_function_error("Error subscribing to login messages from file.");
   }
+}
+
+void owl_callback_aimlogin(owl_editwin *e) {
+  owl_function_aimlogin(owl_editwin_get_command(e),
+                        owl_global_get_response(&g));
 }
 
@@ -1324,14 +1343,5 @@
 void owl_function_run_buffercommand()
 {
-  char *buff;
-  void (*cb)(char*, char*);
-
-  buff=owl_global_get_buffercommand(&g);
-  cb=owl_global_get_buffercallback(&g);
-  if(!cb) {
-    owl_function_error("Internal error: No callback for buffercommand %s", buff);
-  } else {
-    cb(buff, owl_editwin_get_text(owl_global_get_typwin(&g)));
-  }
+  owl_editwin_do_callback(owl_global_get_typwin(&g));
 }
 
@@ -2167,8 +2177,6 @@
       }
       if (cc) owl_free(cc);
-    }
-
-    /* aim */
-    if (owl_message_is_type_aim(m)) {
+    } else if (owl_message_is_type_aim(m)) {
+      /* aim */
       if (owl_message_is_direction_out(m)) {
 	buff=owl_sprintf("aimwrite %s", owl_message_get_recipient(m));
@@ -2176,6 +2184,12 @@
 	buff=owl_sprintf("aimwrite %s", owl_message_get_sender(m));
       }
-    }
-    
+    } else {
+      char *cmd;
+      if((type==0 && (cmd=owl_message_get_attribute_value(m, "replycmd")))
+         || (type==1 && (cmd=owl_message_get_attribute_value(m, "replysendercmd")))) {
+        buff = owl_strdup(cmd);
+      }
+    }
+
     if (enter) {
       owl_history *hist = owl_global_get_cmd_history(&g);
Index: global.c
===================================================================
--- global.c	(revision 4211f50b3f182f522a14169eaee7c89c03d9c447)
+++ global.c	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
@@ -68,5 +68,4 @@
   g->searchstring=NULL;
   g->starttime=time(NULL); /* assumes we call init only a start time */
-  g->buffercommand=NULL;
   g->newmsgproc_pid=0;
   
@@ -241,19 +240,17 @@
 
 void owl_global_set_buffercommand(owl_global *g, char *command) {
-  if (g->buffercommand) owl_free(g->buffercommand);
-  g->buffercommand=owl_strdup(command);
+  owl_editwin_set_command(owl_global_get_typwin(g), command);
 }
 
 char *owl_global_get_buffercommand(owl_global *g) {
-  if (g->buffercommand) return(g->buffercommand);
-  return("");
-}
-
-void owl_global_set_buffercallback(owl_global *g, void (*cb)(char*,char*)) {
-  g->buffercallback = cb;
-}
-
-void (*owl_global_get_buffercallback(owl_global *g))(char*,char*) {
-  return g->buffercallback;
+  return owl_editwin_get_command(owl_global_get_typwin(g));
+}
+
+void owl_global_set_buffercallback(owl_global *g, void (*cb)(owl_editwin*)) {
+  owl_editwin_set_callback(owl_global_get_typwin(g), cb);
+}
+
+void (*owl_global_get_buffercallback(owl_global *g))(owl_editwin*) {
+  return owl_editwin_get_callback(owl_global_get_typwin(g));
 }
 
Index: owl.h
===================================================================
--- owl.h	(revision 39c036d463f52a8655fa9c09590bf1af5c97b4ae)
+++ owl.h	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
@@ -442,4 +442,8 @@
   int dotsend;
   int echochar;
+
+  char *command;
+  void (*callback)(struct _owl_editwin*);
+  void *cbdata;
 } owl_editwin;
 
@@ -536,6 +540,5 @@
   int haveconfig;
   int config_format;
-  char *buffercommand;
-  void (*buffercallback)(char *cmd, char *msg);
+  void *buffercbdata;
   owl_editwin tw;
   owl_viewwin vw;
Index: perlglue.xs
===================================================================
--- perlglue.xs	(revision dd16bddb5693f2d50fa1ad5379e256aac2fd48d9)
+++ perlglue.xs	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
@@ -100,5 +100,5 @@
 		owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
 
-void queue_message(msg)
+void queue_message(msg) 
 	SV *msg
 	PREINIT:
@@ -111,4 +111,5 @@
 		I32 len;
 	CODE:
+	{
 		if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
 			croak("Usage: owl::queue_message($message)");
@@ -131,4 +132,10 @@
 			}
 		}
+		owl_message_set_isprivate(m);
+		if(owl_message_is_type_admin(m)) {
+			if(!owl_message_get_attribute_value(m, "adminheader"))
+				owl_message_set_attribute(m, "adminheader", "");
+		} 
 
 		owl_global_messagequeue_addmsg(&g, m);
+	}
