Index: ChangeLog
===================================================================
--- ChangeLog	(revision b68f9cd141f90b856b00c2df676d8baec2b8140b)
+++ ChangeLog	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -12,4 +12,13 @@
 	Added "reply zaway" which sends a zaway response to the current msg.
 	Added "edit:delete-prev-word" command and bound M-BACKSPACE to it.
+	Added owl_sprintf which returns the formatted string, or NULL.
+	        The caller must free this string.
+		This will allocate enough memory and thus 
+		avoid potential some buffer overrun situations.
+	Started fixing some potential buffer overrun situations.
+	Simple implementation of 'zwrite -m' (doesn't yet log an outgoing
+	        message as having been sent.)
+	The "Not logged in or subscribing to messages" error 
+	        now includes the name of the recipient.
 		
 1.2.1-pre-1
Index: commands.c
===================================================================
--- commands.c	(revision b68f9cd141f90b856b00c2df676d8baec2b8140b)
+++ commands.c	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -81,7 +81,10 @@
   OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
 	      "send a zephyr",
-	      "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] ",
+	      "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
 	      "Zwrite send a zephyr to the one or more users specified.\n\n"
 	      "The following options are available:\n\n"
+	      "-m    Specifies a message to send without prompting.\n"
+	      "      Note that this does not yet log an outgoing message.\n"
+	      "      This must be the last argument.\n\n"
 	      "-n    Do not send a ping message.\n\n"
 	      "-C    If the message is sent to more than one user include a\n"
@@ -1111,5 +1114,19 @@
 
 char *owl_command_zwrite(int argc, char **argv, char *buff) {
-  char *tmpbuff;
+  char *tmpbuff, *pos, *cmd, *msg;
+
+  /* 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;
+    }
+  }
+
   if (argc < 2) {
     owl_function_makemsg("Not enough arguments to the zwrite command.");
Index: functions.c
===================================================================
--- functions.c	(revision d36f2cbef9f608ed68766f9c026d4376906953d6)
+++ functions.c	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -155,7 +155,6 @@
   /* display the message as an admin message in the receive window */
   if (owl_global_is_displayoutgoing(&g) && owl_zwrite_is_personal(&z)) {
-    tmpbuff=owl_malloc(strlen(owl_editwin_get_text(owl_global_get_typwin(&g)))+1024);
     owl_zwrite_get_recipstr(&z, buff);
-    sprintf(tmpbuff, "Message sent to %s", buff);
+    tmpbuff = owl_sprintf("Message sent to %s", buff);
     owl_function_adminmsg_outgoing(tmpbuff, owl_editwin_get_text(owl_global_get_typwin(&g)), line);
     owl_free(tmpbuff);
@@ -1162,5 +1161,5 @@
   }
 
-  buff=malloc(num*200);
+  buff=owl_malloc(num*200);
   strcpy(buff, "");
   for (i=0; i<num; i++) {
@@ -1173,5 +1172,5 @@
 
   owl_function_popless_text(buff);
-  free(buff);
+  owl_free(buff);
   ZFlushSubscriptions();
 }
@@ -1266,5 +1265,4 @@
   owl_view *v;
   owl_filter *f;
-  char buff[LINE];
 
   /* get the trash filter */
@@ -1287,6 +1285,5 @@
   }
   owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  sprintf(buff, "%i messages marked for deletion", count);
-  owl_function_makemsg(buff);
+  owl_function_makemsg("%i messages marked for deletion", count);
   owl_global_set_needrefresh(&g);
 }
Index: owl.c
===================================================================
--- owl.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ owl.c	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -273,8 +273,9 @@
       /* this is an unsupported feature */
       if (owl_global_is_burningears(&g) && owl_message_is_burningears(m)) {
-	char buff[LINE];
-	sprintf(buff, "@i(Burning ears message on class %s)", owl_message_get_class(m));
+	char *buff;
+	buff = owl_sprintf("@i(Burning ears message on class %s)", owl_message_get_class(m));
 	/* owl_function_makemsg(buff); */
 	owl_function_adminmsg(buff, "");
+	owl_free(buff);
 	owl_function_beep();
       }
Index: util.c
===================================================================
--- util.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ util.c	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -28,5 +28,5 @@
     strcpy(buff, " (-/-) ");
   } else {
-    sprintf(buff, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
+    snprintf(buff, 1024, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
 	    owl_view_get_size(v),
 	    owl_messagelist_get_size(ml));
@@ -62,5 +62,5 @@
     getyx(sepwin, y, x);
     wmove(sepwin, y, x+2);
-    sprintf(buff, " right: %i ", owl_global_get_rightshift(&g));
+    snprintf(buff, 1024, " right: %i ", owl_global_get_rightshift(&g));
     waddstr(sepwin, buff);
   }
@@ -316,4 +316,32 @@
 }
 
+/* allocates memory and returns the string or null.
+ * caller must free the string. 
+ * from Linux sprintf man page. 
+ */
+char *owl_sprintf(const char *fmt, ...) {
+  int n, size = 100;
+  char *p;
+  va_list ap;
+  if ((p = owl_malloc (size)) == NULL)
+    return NULL;
+  while (1) {
+    /* Try to print in the allocated space. */
+    va_start(ap, fmt);
+    n = vsnprintf (p, size, fmt, ap);
+    va_end(ap);
+    /* If that worked, return the string. */
+    if (n > -1 && n < size)
+      return p;
+    /* Else try again with more space. */
+    if (n > -1)    /* glibc 2.1 */
+      size = n+1; /* precisely what is needed */
+    else           /* glibc 2.0 */
+      size *= 2;  /* twice the old size */
+    if ((p = owl_realloc (p, size)) == NULL)
+      return NULL;
+  }
+}
+
 char *pretty_sender(char *in) {
   char *out, *ptr;
@@ -331,13 +359,12 @@
 
 char *long_sender(char *in) {
-  char *out, *ptr;
+  char *ptr;
 
   /* the caller must free the return */
-  out=owl_malloc(strlen(in)+100);
-  strcpy(out, in);
-  ptr=strchr(out, '@');
-  if (ptr) return(out);
-  sprintf(out, "%s@%s", out, ZGetRealm());
-  return(out);
+  if (NULL != (ptr=strchr(in, '@'))) {
+    return owl_strdup(in);
+  } else {
+    return owl_sprintf("%s@%s", in, ZGetRealm());
+  }
 }
 		  
Index: zephyr.c
===================================================================
--- zephyr.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ zephyr.c	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -111,6 +111,5 @@
 	subs[count].zsub_classinst=owl_strdup(buffer);
       } else {
-	subs[count].zsub_classinst=owl_malloc(1024);
-	sprintf(subs[count].zsub_classinst, "%s@%s", buffer, ZGetRealm());
+	subs[count].zsub_classinst=owl_sprintf("%s@%s", buffer, ZGetRealm());
       }
 
@@ -346,5 +345,4 @@
 
 void owl_zephyr_handle_ack(ZNotice_t *retnotice) {
-  char buff[LINE];
   char *tmp;
   
@@ -362,22 +360,21 @@
 	       !strcasecmp(retnotice->z_class_inst, "personal")) {
       tmp=pretty_sender(retnotice->z_recipient);
-      sprintf(buff, "Message sent to %s.", tmp);
+      owl_function_makemsg("Message sent to %s.", tmp);
       free(tmp);
     } else {
-      sprintf(buff, "Message sent to -c %s -i %s\n", retnotice->z_class, retnotice->z_class_inst);
-    }
-    owl_function_makemsg(buff);
+      owl_function_makemsg("Message sent to -c %s -i %s\n", retnotice->z_class, retnotice->z_class_inst);
+    }
   } else if (!strcmp(retnotice->z_message, ZSRVACK_NOTSENT)) {
     if (strcasecmp(retnotice->z_class, "message")) {
-      sprintf(buff, "Not logged in or not subscribing to class %s, instance %s",
+      owl_function_makemsg("Not logged in or not subscribing to class %s, instance %s",
 	      retnotice->z_class, retnotice->z_class_inst);
-      owl_function_makemsg(buff);
     } else {
-      owl_function_makemsg("Not logged in or subscribing to messages.");
-    }
-  } else {
-    char buff[1024];
-    sprintf(buff, "Internal error on ack (%s)", retnotice->z_message);
-    owl_function_makemsg(buff);
+      tmp = pretty_sender(retnotice->z_recipient);
+      owl_function_makemsg("%s: Not logged in or subscribing to messages.", 
+			   tmp);
+      owl_free(tmp);
+    }
+  } else {
+    owl_function_makemsg("Internal error on ack (%s)", retnotice->z_message);
   }
 }
@@ -412,6 +409,5 @@
 
   /* display the message as an admin message in the receive window */
-  tmpbuff=owl_malloc(strlen(owl_global_get_zaway_msg(&g))+LINE);
-  sprintf(tmpbuff, "Message sent to %s", owl_message_get_sender(m));
+  tmpbuff = owl_sprintf("Message sent to %s", owl_message_get_sender(m));
   owl_function_adminmsg(tmpbuff, owl_global_get_zaway_msg(&g));
   owl_free(tmpbuff);
Index: zwrite.c
===================================================================
--- zwrite.c	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ zwrite.c	(revision 1c6c4d32e1e8e1d158e1586d924d0c440edc8a8b)
@@ -3,4 +3,14 @@
 
 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) {
