Index: commands.c
===================================================================
--- commands.c	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
+++ commands.c	(revision db8b00b09df85c08c46f12647799ccf43c314162)
@@ -2506,5 +2506,5 @@
 void owl_command_editresponse_done(owl_editwin *e)
 {
-  owl_global_set_response(&g, owl_editwin_get_text(e));
+  owl_function_run_buffercommand();
 
   owl_global_set_typwin_inactive(&g);
@@ -2512,6 +2512,4 @@
   wnoutrefresh(owl_editwin_get_curswin(e));
   owl_global_set_needrefresh(&g);
-
-  owl_function_run_buffercommand();
 }
 
Index: functions.c
===================================================================
--- functions.c	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
+++ functions.c	(revision db8b00b09df85c08c46f12647799ccf43c314162)
@@ -950,5 +950,5 @@
 void owl_callback_aimlogin(owl_editwin *e) {
   owl_function_aimlogin(owl_editwin_get_command(e),
-                        owl_global_get_response(&g));
+                        owl_editwin_get_text(e));
 }
 
Index: global.c
===================================================================
--- global.c	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
+++ global.c	(revision db8b00b09df85c08c46f12647799ccf43c314162)
@@ -99,5 +99,4 @@
   owl_buddylist_init(&(g->buddylist));
     
-  g->response=NULL;
   g->havezephyr=0;
   g->haveaim=0;
@@ -814,17 +813,4 @@
 }
 
-char *owl_global_get_response(owl_global *g)
-{
-  if (g->response==NULL) return("");
-  return(g->response);
-}
-
-void owl_global_set_response(owl_global *g, char *resp)
-{
-  if (g->response) owl_free(g->response);
-  g->response=owl_strdup(resp);
-}
-
-
 void owl_global_set_haveaim(owl_global *g)
 {
Index: perlconfig.c
===================================================================
--- perlconfig.c	(revision 6922eddf979a8bdbf46a21cad138b787a7719f46)
+++ perlconfig.c	(revision db8b00b09df85c08c46f12647799ccf43c314162)
@@ -378,2 +378,27 @@
   SvREFCNT_dec(cmd);
 }
+
+void owl_perlconfig_edit_callback(owl_editwin *e)
+{
+  SV *cb = (SV*)(e->cbdata);
+  if(cb == NULL) {
+    owl_function_error("Perl callback is NULL!");
+  }
+
+  dSP;
+
+  ENTER;
+  SAVETMPS;
+
+  PUSHMARK(SP);
+  XPUSHs(sv_2mortal(newSVpv(owl_editwin_get_text(e), 0)));
+  PUTBACK;
+  
+  call_sv(cb, G_DISCARD);
+
+  FREETMPS;
+  LEAVE;
+
+  SvREFCNT_dec(cb);
+  e->cbdata = NULL;
+}
Index: perlglue.xs
===================================================================
--- perlglue.xs	(revision 1b6b2f3723ab29b5dd1f647eb40542104bf803fd)
+++ perlglue.xs	(revision db8b00b09df85c08c46f12647799ccf43c314162)
@@ -10,4 +10,6 @@
 #include "owl.h"
 SV *owl_perlconfig_curmessage2hashref(void);
+
+#define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
 
 MODULE = owl		PACKAGE = owl		
@@ -84,4 +86,8 @@
 		owl_cmd cmd;
 	CODE:
+	{
+		if(!SV_IS_CODEREF(func)) {
+			croak("Command function must be a coderef!");
+		}
 		SvREFCNT_inc(func);
 		cmd.name = name;
@@ -99,4 +105,5 @@
 		cmd.cmd_ctxi_fn = NULL;
 		owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
+	   }
 
 void queue_message(msg) 
@@ -140,2 +147,60 @@
 		owl_global_messagequeue_addmsg(&g, m);
 	}
+
+void start_question(line, callback)
+	char *line
+	SV *callback
+	PREINIT:
+	CODE:
+	{
+		if(!SV_IS_CODEREF(callback))
+			croak("Callback must be a subref");
+
+		owl_function_start_question(line);
+
+		SvREFCNT_inc(callback);
+		owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
+		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
+	}
+
+void start_password(line, callback)
+	char *line
+	SV *callback
+	PREINIT:
+	CODE:
+	{
+		if(!SV_IS_CODEREF(callback))
+			croak("Callback must be a subref");
+
+		owl_function_start_password(line);
+
+		SvREFCNT_inc(callback);
+		owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
+		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
+	}
+
+void start_edit_win(line, callback)
+	char *line
+	SV *callback
+	PREINIT:
+		owl_editwin * e;
+		char buff[1024];
+	CODE:
+	{
+		if(!SV_IS_CODEREF(callback))
+			croak("Callback must be a subref");
+
+		e = owl_global_get_typwin(&g);
+		owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE,
+				      owl_global_get_msg_history(&g));
+		owl_editwin_clear(e);
+		owl_editwin_set_dotsend(e);
+		snprintf(buff, 1023, "----> %s\n", line);
+		owl_editwin_set_locktext(e, buff);
+
+		owl_global_set_typwin_active(&g);
+
+		SvREFCNT_inc(callback);
+		owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
+		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
+	}
