Index: ChangeLog
===================================================================
--- ChangeLog	(revision 79a0e82293e700c67a73648b97bcdf9639136be8)
+++ ChangeLog	(revision ce7db4dc829cba2b5bb3b63633bda1e948c957dc)
@@ -18,4 +18,6 @@
 	Fixed personal aim messages logging to class directory
 	Log "LOGIN" or "LOGOUT" for AIM buddy messages message
+	zwrite -m now logs and displays an outgoing message
+	zwrite -s now works
 
 2.0.4-pre-1
Index: commands.c
===================================================================
--- commands.c	(revision ef56a6724cbce9cfe55d35d4b300df48c8c464c6)
+++ commands.c	(revision ce7db4dc829cba2b5bb3b63633bda1e948c957dc)
@@ -1526,17 +1526,12 @@
 
 char *owl_command_zwrite(int argc, char **argv, char *buff) {
-  char *tmpbuff, *pos, *cmd, *msg;
+  owl_zwrite z;
 
   /* check for a zwrite -m */
-  for (pos = buff; *pos; pos = skiptokens(pos, 1)) {
-    if (!strncmp(pos, "-m ", 3)) {
-      cmd = owl_strdup(buff);
-      msg = cmd+(pos-buff);
-      *msg = '\0';
-      msg += 3;
-      owl_zwrite_create_and_send_from_line(cmd, msg);
-      owl_free(cmd);
-      return NULL;
-    }
+  owl_zwrite_create_from_line(&z, buff);
+  if (owl_zwrite_is_message_set(&z)) {
+    owl_function_zwrite(buff, NULL);
+    owl_zwrite_free(&z);
+    return (NULL);
   }
 
@@ -1544,15 +1539,11 @@
     owl_function_makemsg("Not enough arguments to the zwrite command.");
   } else {
-    tmpbuff = owl_strdup(buff);
-    owl_function_zwrite_setup(tmpbuff);
-    owl_global_set_buffercommand(&g, tmpbuff);
-    owl_free(tmpbuff);
-  }
-  return NULL;
+    owl_function_zwrite_setup(buff);
+    owl_global_set_buffercommand(&g, buff);
+  }
+  return(NULL);
 }
 
 char *owl_command_aimwrite(int argc, char **argv, char *buff) {
-  char *tmpbuff;
-
   if (!owl_global_is_aimloggedin(&g)) {
     owl_function_makemsg("You are not logged in to AIM.");
@@ -1565,25 +1556,19 @@
   }
 
-  tmpbuff=owl_strdup(buff);
-  owl_function_aimwrite_setup(tmpbuff);
-  owl_global_set_buffercommand(&g, tmpbuff);
-  owl_free(tmpbuff);
+  owl_function_aimwrite_setup(buff);
+  owl_global_set_buffercommand(&g, buff);
   return(NULL);
 }
 
 char *owl_command_zcrypt(int argc, char **argv, char *buff) {
-  char *tmpbuff, *pos, *cmd, *msg;
-  
+  owl_zwrite z;
+
   /* check for a zwrite -m */
-  for (pos = buff; *pos; pos = skiptokens(pos, 1)) {
-    if (!strncmp(pos, "-m ", 3)) {
-      cmd = owl_strdup(buff);
-      msg = cmd+(pos-buff);
-      *msg = '\0';
-      msg += 3;
-      owl_zwrite_create_and_send_from_line(cmd, msg);
-      owl_free(cmd);
-      return NULL;
-    }
+  owl_zwrite_create_from_line(&z, buff);
+  if (owl_zwrite_is_message_set(&z)) {
+    owl_zwrite_send_message(&z);
+    owl_function_make_outgoing_zephyr(owl_zwrite_get_message(&z), buff, owl_zwrite_get_zsig(&z));
+    owl_zwrite_free(&z);
+    return (NULL);
   }
 
@@ -1591,8 +1576,6 @@
     owl_function_makemsg("Not enough arguments to the zcrypt command.");
   } else {
-    tmpbuff = owl_strdup(buff);
-    owl_function_zwrite_setup(tmpbuff);
-    owl_global_set_buffercommand(&g, tmpbuff);
-    owl_free(tmpbuff);
+    owl_function_zwrite_setup(buff);
+    owl_global_set_buffercommand(&g, buff);
   }
   return(NULL);
Index: functions.c
===================================================================
--- functions.c	(revision f1cbb7ad459be40f4c5e37309892324bba047818)
+++ functions.c	(revision ce7db4dc829cba2b5bb3b63633bda1e948c957dc)
@@ -302,17 +302,27 @@
 }
 
-void owl_function_zwrite(char *line)
+/* send, log and display an outgoing zephyr.  If 'msg' is NULL
+ * the message is expected to be set from the zwrite line itself
+ */
+void owl_function_zwrite(char *line, char *msg)
 {
   owl_zwrite z;
   int i, j;
+  char *mymsg;
 
   /* create the zwrite and send the message */
   owl_zwrite_create_from_line(&z, line);
-  owl_zwrite_send_message(&z, owl_editwin_get_text(owl_global_get_typwin(&g)));
+  if (msg) {
+    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(owl_editwin_get_text(owl_global_get_typwin(&g)), line, owl_zwrite_get_zsig(&z));
+    owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
   }
 
@@ -321,6 +331,5 @@
     j=owl_zwrite_get_numrecips(&z);
     for (i=0; i<j; i++) {
-      owl_log_outgoing_zephyr(owl_zwrite_get_recip_n(&z, i),
-		       owl_editwin_get_text(owl_global_get_typwin(&g)));
+      owl_log_outgoing_zephyr(owl_zwrite_get_recip_n(&z, i), mymsg);
     }
   }
@@ -1073,5 +1082,5 @@
   buff=owl_global_get_buffercommand(&g);
   if (!strncmp(buff, "zwrite ", 7)) {
-    owl_function_zwrite(buff);
+    owl_function_zwrite(buff, owl_editwin_get_text(owl_global_get_typwin(&g)));
   } else if (!strncmp(buff, "aimwrite ", 9)) {
     owl_function_aimwrite(buff+9);
Index: owl.c
===================================================================
--- owl.c	(revision ef56a6724cbce9cfe55d35d4b300df48c8c464c6)
+++ owl.c	(revision ce7db4dc829cba2b5bb3b63633bda1e948c957dc)
@@ -283,5 +283,5 @@
   strcat(startupmsg, buff);
   strcat(startupmsg, "                                                                         \n");
-  strcat(startupmsg, "If you would like to receive release announcments about owl you can join \n");
+  strcat(startupmsg, "If you would like to receive release announcements about owl you can join \n");
   strcat(startupmsg, "the owl-users@mit.edu mailing list.  MIT users can add themselves,       \n");
   strcat(startupmsg, "otherwise send a request to owner-owl-users@mit.edu.               ^ ^   \n");
Index: owl.h
===================================================================
--- owl.h	(revision 0c502e9628cc58f86762f4588401e8c19a55a5e4)
+++ owl.h	(revision ce7db4dc829cba2b5bb3b63633bda1e948c957dc)
@@ -231,9 +231,10 @@
 
 typedef struct _owl_zwrite {
-  char class[LINE];
-  char inst[LINE];
-  char realm[LINE];
-  char opcode[LINE];
+  char *class;
+  char *inst;
+  char *realm;
+  char *opcode;
   char *zsig;
+  char *message;
   owl_list recips;
   int cc;
Index: zwrite.c
===================================================================
--- zwrite.c	(revision 8262340da7afa4c7f9e0d5bdcfee0e8006bf087d)
+++ zwrite.c	(revision ce7db4dc829cba2b5bb3b63633bda1e948c957dc)
@@ -7,15 +7,6 @@
 static const char fileIdent[] = "$Id$";
 
-int owl_zwrite_create_and_send_from_line(char *cmd, char *msg) {
-  owl_zwrite z;
-  int rv;
-  rv = owl_zwrite_create_from_line(&z, cmd);
-  if (rv) return(rv);
-  owl_zwrite_send_message(&z, msg);
-  owl_zwrite_free(&z);
-  return(0);
-}
-
-int owl_zwrite_create_from_line(owl_zwrite *z, char *line) {
+int owl_zwrite_create_from_line(owl_zwrite *z, char *line)
+{
   int argc, badargs, myargc;
   char **argv, **myargv;
@@ -25,10 +16,11 @@
   badargs=0;
   
-  /* set the defaults */
-  strcpy(z->realm, "");
-  strcpy(z->class, "message");
-  strcpy(z->inst, "personal");
-  strcpy(z->opcode, "");
-  z->zsig=owl_strdup("");
+  /* start with null entires */
+  z->realm=NULL;
+  z->class=NULL;
+  z->inst=NULL;
+  z->opcode=NULL;
+  z->zsig=NULL;
+  z->message=NULL;
   z->cc=0;
   z->noping=0;
@@ -52,5 +44,5 @@
 	break;
       }
-      strcpy(z->class, myargv[1]);
+      z->class=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -60,5 +52,5 @@
 	break;
       }
-      strcpy(z->inst, myargv[1]);
+      z->inst=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -68,5 +60,13 @@
 	break;
       }
-      strcpy(z->realm, myargv[1]);
+      z->realm=owl_strdup(myargv[1]);
+      myargv+=2;
+      myargc-=2;
+    } else if (!strcmp(myargv[0], "-s")) {
+      if (myargc<2) {
+	badargs=1;
+	break;
+      }
+      z->zsig=owl_strdup(myargv[1]);
       myargv+=2;
       myargc-=2;
@@ -76,7 +76,30 @@
 	break;
       }
-      strcpy(z->opcode, myargv[1]);
-      myargv+=2;
-      myargc-=2;
+      z->opcode=owl_strdup(myargv[1]);
+      myargv+=2;
+      myargc-=2;
+    } else if (!strcmp(myargv[0], "-m")) {
+      if (myargc<2) {
+	badargs=1;
+	break;
+      }
+      /* we must already have users */
+      if (owl_list_get_size(&(z->recips))<1) {
+	badargs=1;
+	break;
+      }
+
+      /* Once we have -m, gobble up everything else on the line */
+      myargv++;
+      myargc--;
+      z->message=owl_strdup("");
+      while (myargc) {
+	z->message=realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
+	strcat(z->message, " ");
+	strcat(z->message, myargv[0]);
+	myargc--;
+	myargv++;
+      }
+      break;
     } else if (!strcmp(myargv[0], "-C")) {
       z->cc=1;
@@ -101,63 +124,67 @@
   }
 
+  /* now deal with defaults */
+  if (z->class==NULL) z->class=owl_strdup("message");
+  if (z->inst==NULL) z->inst=owl_strdup("personal");
+  if (z->realm==NULL) z->realm=owl_strdup("");
+  if (z->opcode==NULL) z->opcode=owl_strdup("");
+  /* z->message is allowed to stay NULL */
+  
   if (!strcasecmp(z->class, "message") &&
       !strcasecmp(z->inst, "personal") &&
       owl_list_get_size(&(z->recips))==0) {
-    /* do the makemsg somewhere else */
     owl_function_makemsg("You must specify a recipient");
     return(-1);
   }
 
-  /* set a zsig */
-  zsigproc = owl_global_get_zsigproc(&g);
-  zsigowlvar = owl_global_get_zsig(&g);
-  zsigzvar = ZGetVariable("zwrite-signature");
-
-  if (zsigowlvar && *zsigowlvar) {
-    owl_free(z->zsig);
-    z->zsig=strdup(zsigowlvar);
-  } else if (zsigproc && *zsigproc) {
-    FILE *file;
-    char buff[LINE], *openline;
-
-    /* simple hack for now to nuke stderr */
-    openline=owl_malloc(strlen(zsigproc)+40);
-    strcpy(openline, zsigproc);
-    strcat(openline, " 2> /dev/null");
-    file=popen(openline, "r");
-    owl_free(openline);
-    if (!file) {
-      if (zsigzvar && *zsigzvar) {
-	owl_free(z->zsig);
-	z->zsig=owl_strdup(zsigzvar);
-      }
-    } else {
-      owl_free(z->zsig);
-      z->zsig=owl_malloc(LINE);
-      strcpy(z->zsig, "");
-      while (fgets(buff, LINE, file)) { /* wrong sizing */
-	strcat(z->zsig, buff);
-      }
-      pclose(file);
-      if (z->zsig[strlen(z->zsig)-1]=='\n') {
-	z->zsig[strlen(z->zsig)-1]='\0';
-      }
-    }
-  } else if (zsigzvar) {
-    owl_free(z->zsig);
-    z->zsig=owl_strdup(zsigzvar);
-  } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
-    owl_free(z->zsig);
-    z->zsig=strdup(pw->pw_gecos);
-    ptr=strchr(z->zsig, ',');
-    if (ptr) {
-      ptr[0]='\0';
-    }
-  }
-
-  return(0);
-}
-
-void owl_zwrite_send_ping(owl_zwrite *z) {
+  /* get a zsig, if not given */
+  if (z->zsig==NULL) {
+    zsigproc = owl_global_get_zsigproc(&g);
+    zsigowlvar = owl_global_get_zsig(&g);
+    zsigzvar = ZGetVariable("zwrite-signature");
+
+    if (zsigowlvar && *zsigowlvar) {
+      z->zsig=owl_strdup(zsigowlvar);
+    } else if (zsigproc && *zsigproc) {
+      FILE *file;
+      char buff[LINE], *openline;
+      
+      /* simple hack for now to nuke stderr */
+      openline=owl_malloc(strlen(zsigproc)+40);
+      strcpy(openline, zsigproc);
+      strcat(openline, " 2> /dev/null");
+      file=popen(openline, "r");
+      owl_free(openline);
+      if (!file) {
+	if (zsigzvar && *zsigzvar) {
+	  z->zsig=owl_strdup(zsigzvar);
+	}
+      } else {
+	z->zsig=owl_malloc(LINE*5);
+	strcpy(z->zsig, "");
+	while (fgets(buff, LINE, file)) { /* wrong sizing */
+	  strcat(z->zsig, buff);
+	}
+	pclose(file);
+	if (z->zsig[strlen(z->zsig)-1]=='\n') {
+	  z->zsig[strlen(z->zsig)-1]='\0';
+	}
+      }
+    } else if (zsigzvar) {
+      z->zsig=owl_strdup(zsigzvar);
+    } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
+      z->zsig=strdup(pw->pw_gecos);
+      ptr=strchr(z->zsig, ',');
+      if (ptr) {
+	ptr[0]='\0';
+      }
+    }
+  }
+
+  return(0);
+}
+
+void owl_zwrite_send_ping(owl_zwrite *z)
+{
   int i, j;
   char to[LINE];
@@ -184,7 +211,28 @@
 }
 
-void owl_zwrite_send_message(owl_zwrite *z, char *msg) {
+void owl_zwrite_set_message(owl_zwrite *z, char *msg)
+{
+  if (z->message) owl_free(z->message);
+  z->message=owl_strdup(msg);
+}
+
+char *owl_zwrite_get_message(owl_zwrite *z)
+{
+  if (z->message) return(z->message);
+  return("");
+}
+
+int owl_zwrite_is_message_set(owl_zwrite *z)
+{
+  if (z->message) return(1);
+  return(0);
+}
+
+int owl_zwrite_send_message(owl_zwrite *z)
+{
   int i, j;
   char to[LINE];
+
+  if (z->message==NULL) return(-1);
 
   j=owl_list_get_size(&(z->recips));
@@ -202,6 +250,6 @@
 	}
       }
-      tmpmsg=owl_malloc(strlen(msg)+strlen(toline)+30);
-      sprintf(tmpmsg, "%s\n%s", toline, msg);
+      tmpmsg=owl_malloc(strlen(z->message)+strlen(toline)+30);
+      sprintf(tmpmsg, "%s\n%s", toline, z->message);
     }
 
@@ -215,5 +263,5 @@
 	send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, tmpmsg);
       } else {
-	send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, msg);
+	send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
       }
     }
@@ -223,29 +271,51 @@
   } else {
     sprintf(to, "@%s", z->realm);
-    send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, msg);
-  }
-}
-
-char *owl_zwrite_get_class(owl_zwrite *z) {
+    send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
+  }
+  return(0);
+}
+
+int owl_zwrite_create_and_send_from_line(char *cmd, char *msg)
+{
+  owl_zwrite z;
+  int rv;
+  rv=owl_zwrite_create_from_line(&z, cmd);
+  if (rv) return(rv);
+  if (!owl_zwrite_is_message_set(&z)) {
+    owl_zwrite_set_message(&z, msg);
+  }
+  owl_zwrite_send_message(&z);
+  owl_zwrite_free(&z);
+  return(0);
+}
+
+char *owl_zwrite_get_class(owl_zwrite *z)
+{
   return(z->class);
 }
 
-char *owl_zwrite_get_instance(owl_zwrite *z) {
+char *owl_zwrite_get_instance(owl_zwrite *z)
+{
   return(z->inst);
 }
 
-char *owl_zwrite_get_opcode(owl_zwrite *z) {
+char *owl_zwrite_get_opcode(owl_zwrite *z)
+{
   return(z->opcode);
 }
 
-char *owl_zwrite_get_realm(owl_zwrite *z) {
+char *owl_zwrite_get_realm(owl_zwrite *z)
+{
   return(z->realm);
 }
 
-char *owl_zwrite_get_zsig(owl_zwrite *z) {
-  return(z->zsig);
-}
-
-void owl_zwrite_get_recipstr(owl_zwrite *z, char *buff) {
+char *owl_zwrite_get_zsig(owl_zwrite *z)
+{
+  if (z->zsig) return(z->zsig);
+  return("");
+}
+
+void owl_zwrite_get_recipstr(owl_zwrite *z, char *buff)
+{
   int i, j;
 
@@ -259,13 +329,16 @@
 }
 
-int owl_zwrite_get_numrecips(owl_zwrite *z) {
+int owl_zwrite_get_numrecips(owl_zwrite *z)
+{
   return(owl_list_get_size(&(z->recips)));
 }
 
-char *owl_zwrite_get_recip_n(owl_zwrite *z, int n) {
+char *owl_zwrite_get_recip_n(owl_zwrite *z, int n)
+{
   return(owl_list_get_element(&(z->recips), n));
 }
 
-int owl_zwrite_is_personal(owl_zwrite *z) {
+int owl_zwrite_is_personal(owl_zwrite *z)
+{
   /* return true if at least one of the recipients is personal */
   int i, j;
@@ -280,6 +353,12 @@
 }
   
-void owl_zwrite_free(owl_zwrite *z) {
+void owl_zwrite_free(owl_zwrite *z)
+{
   owl_list_free_all(&(z->recips), &owl_free);
-  owl_free(z->zsig);
-}
+  if (z->class) owl_free(z->class);
+  if (z->inst) owl_free(z->inst);
+  if (z->opcode) owl_free(z->opcode);
+  if (z->realm) owl_free(z->realm);
+  if (z->message) owl_free(z->message);
+  if (z->zsig) owl_free(z->zsig);
+}
