diff -ruN -x '*.orig' -x '*.rej' mutt-1.5.5.1.orig/globals.h mutt-1.5.5.1/globals.h
--- mutt-1.5.5.1.orig/globals.h	2003-11-05 17:41:31.000000000 +0800
+++ mutt-1.5.5.1/globals.h	2004-01-14 10:47:53.000000000 +0800
@@ -32,2 +32,3 @@
 
+WHERE char *AttachKeyword;
 WHERE char *AliasFile;
diff -ruN -x '*.orig' -x '*.rej' mutt-1.5.5.1.orig/init.h mutt-1.5.5.1/init.h
--- mutt-1.5.5.1.orig/init.h	2003-11-05 17:41:32.000000000 +0800
+++ mutt-1.5.5.1/init.h	2004-01-14 10:47:53.000000000 +0800
@@ -101,6 +101,14 @@
 
 struct option_t MuttVars[] = {
   /*++*/
+  { "abort_noattach",	DT_QUAD, R_NONE, OPT_ATTACH, M_ASKYES },
+  /*
+  ** .pp
+  ** If set to \fIyes\fP, when composing messages containing the word
+  ** specified by $attach_keyword (default is "attach") and no attachments 
+  ** are given, composition will be aborted. If set to \fIno\fP, composing
+  ** messages as such will never be aborted.
+  */
   { "abort_nosubject",	DT_QUAD, R_NONE, OPT_SUBJECT, M_ASKYES },
   /*
   ** .pp
@@ -216,6 +224,13 @@
   ** .dt %|X .dd pad to the end of the line with character "X"
   ** .de
   */
+  { "attach_keyword",	DT_STR,	 R_NONE, UL &AttachKeyword, UL "attach" },
+  /*
+  ** .pp
+  ** If $abort_attach is not set to no, then the body of the message
+  ** will be scanned for this keyword, and if found, you will be prompted
+  ** if there are no attachments. This is case insensitive.
+  */
   { "attach_sep",	DT_STR,	 R_NONE, UL &AttachSep, UL "\n" },
   /*
   ** .pp
diff -ruN -x '*.orig' -x '*.rej' mutt-1.5.5.1.orig/mutt.h mutt-1.5.5.1/mutt.h
--- mutt-1.5.5.1.orig/mutt.h	2003-11-05 17:41:32.000000000 +0800
+++ mutt-1.5.5.1/mutt.h	2004-01-14 10:48:37.000000000 +0800
@@ -289,6 +289,7 @@
 #endif
   OPT_SUBJECT,
   OPT_VERIFYSIG,      /* verify PGP signatures */
+  OPT_ATTACH,
     
   /* THIS MUST BE THE LAST VALUE. */
   OPT_MAX
diff -ruN -x '*.orig' -x '*.rej' mutt-1.5.5.1.orig/send.c mutt-1.5.5.1/send.c
--- mutt-1.5.5.1.orig/send.c	2003-11-05 17:41:33.000000000 +0800
+++ mutt-1.5.5.1/send.c	2004-01-14 10:47:53.000000000 +0800
@@ -1028,6 +1028,34 @@
 }
 
 int
+mutt_search_attach_keyword(char* filename)
+{
+  /* searches for the magic keyword "attach" within a file */
+  int found = 0;
+  char* inputline = malloc(1024);
+  char* lowerKeyword = malloc(strlen(AttachKeyword)+1);
+  FILE *attf = fopen(filename, "r");
+  int i;
+  for (i=0; i <= strlen(AttachKeyword); i++) {
+    lowerKeyword[i] = tolower(AttachKeyword[i]);
+  }
+  while (!feof(attf)) {
+    fgets(inputline, 1024, attf);
+    for (i=0; i < strlen(inputline); i++) {
+      inputline[i] = tolower(inputline[i]);
+    }
+    if (strstr(inputline, lowerKeyword)) {
+        found = 1;
+        break;
+    }
+  }
+  free(inputline);
+  free(lowerKeyword);
+  fclose(attf);
+  return found;
+}
+
+int
 ci_send_message (int flags,		/* send mode */
 		 HEADER *msg,		/* template to use for new message */
 		 char *tempfile,	/* file specified by -i or -H */
@@ -1463,6 +1491,21 @@
     goto main_loop;
   }
 
+  if (mutt_search_attach_keyword(msg->content->filename) && 
+	  !msg->content->next && 
+	  query_quadoption(OPT_ATTACH, _("No attachments, cancel sending?")) != M_NO)
+  {
+    /* if the abort is automatic, print an error message */
+    if (quadoption (OPT_ATTACH) == M_YES) {
+	  char errorstr[512];
+	  if (snprintf(errorstr, 512, 
+			"Message contains magic keyword \"%s\", but no attachments. Not sending.", AttachKeyword)==-1)
+		errorstr[511] = 0; // terminate if need be. our string shouldnt be this long.
+      mutt_error _(errorstr);
+    }
+    goto main_loop;
+  }
+
   if (msg->content->next)
     msg->content = mutt_make_multipart (msg->content);
 

