--- /dev/null
+diff -ruN mutt-1.4./README.xface mutt-1.4/README.xface
+--- mutt-1.4./README.xface Thu Jan 1 01:00:00 1970
++++ mutt-1.4/README.xface Sat Aug 24 02:29:23 2002
+@@ -0,0 +1,80 @@
++This is slrnface, a small helper utility which displays X-Faces on behalf
++of programs like slrn and mutt when they are run in the X11 terminal
++emulator.
++
++Requirements:
++
++a) X11.
++b) Terminal emulator which sets WINDOWID environment variable. Most of the
++ ones in common use will set it. If you're using some terminal emulator
++ which doesn't have this capability, you'll have to set it yourself.
++
++How to build:
++
++a) Install libcompface. I recommend getting the source from the nearest
++ Debian GNU/Linux mirror because there's a patch which adds the
++ ability to output XBM image, as well as the historic brain dead
++ format. Slrnface doesn't use that feature, but it might be handy for
++ something else.
++
++b) Edit Makefile.
++
++c) Invoke make.
++
++d) Install with "make install".
++
++Upgrading from version 1.x:
++
++ If you have used one of the older versions of slrnface, you probably
++ have .slrnface file in your home directory. You can delete it, because
++ the new version doesn't use it any more. Instead, the pipes will be
++ created in $HOME/.slrnfaces directory. There are no other user visible
++ changes.
++
++Using slrnface with slrn:
++
++ This version requires S-Lang 1.4 or later and slrn 0.9.7.4. It might
++ work with slrn 0.9.7.3, but I haven't tested that configuration. It
++ will not work properly with older versions.
++
++ In case you can't or won't upgrade, take a look at the slrnface home
++ page. You'll find older versions which might work with what you have.
++
++ Take a look at slrnface.sl, edit if you want and then include it in
++ your .slrnrc, like this:
++
++ interpret slrnface.sl
++
++ Run slrn.
++
++Using slrnface with mutt:
++
++ Mutt doesn't have a way to use some kind of embeded interpreter, like
++ S-Lang. Since Mutt's current capabilities are not good enough for our
++ purposes, a patch for the source is provided. It has been tested with
++ mutt 1.4, but it should work with the 1.3.x series, if x is high
++ enough.
++
++ Uncompress mutt 1.4 source and apply mutt.patch from the slrnface
++ distribution.
++
++ Compile mutt as usual.
++
++ Edit your ~/.muttrc and add:
++
++ set xface=yes
++
++ Run mutt.
++
++If you think X-Faces are not placed at the appropriate location on your
++terminal emulator window or you don't like the colors, set some X resources.
++Read the man page for more information. Additional documentation is in the
++doc directory.
++
++Licence: GPL. See file called COPYING.
++
++Special thanks to Mark R. Bowyer for proofreading the man page.
++
++Home page: http://dave.willfork.com/slrnface/
++
++dave@willfork.com
+diff -ruN mutt-1.4./globals.h mutt-1.4/globals.h
+--- mutt-1.4./globals.h Mon Jan 20 00:17:02 2003
++++ mutt-1.4/globals.h Mon Jan 20 00:28:31 2003
+@@ -177,6 +177,8 @@
+ WHERE ALIAS *Aliases INITVAL (0);
+ WHERE LIST *UserHeader INITVAL (0);
+
++WHERE int slrnface_fd INITVAL (-1);
++
+ #ifdef DEBUG
+ WHERE FILE *debugfile INITVAL (0);
+ WHERE int debuglevel INITVAL (0);
+diff -ruN mutt-1.4./init.c mutt-1.4/init.c
+--- mutt-1.4./init.c Mon Jan 20 00:17:02 2003
++++ mutt-1.4/init.c Mon Jan 20 00:28:31 2003
+@@ -47,6 +47,8 @@
+ #include <string.h>
+ #include <sys/utsname.h>
+ #include <errno.h>
++#include <sys/types.h>
++#include <fcntl.h>
+ #include <sys/wait.h>
+
+ void toggle_quadoption (int opt)
+@@ -1971,3 +1973,131 @@
+ return c->data;
+ return 0;
+ }
++
++void mutt_start_slrnface(void)
++{
++ char *fifo;
++ int pathlen, status;
++ pid_t pid, pidst;
++ struct utsname u;
++
++ if (!option(OPTXFACE))
++ return;
++
++ /*
++ * If we don't have display, there's no point. The user probably knows,
++ * so fail silently.
++ */
++ if (!getenv("DISPLAY"))
++ return;
++ /* If there is no WINDOWID, complain. */
++ if (!getenv ("WINDOWID"))
++ {
++ mutt_error (_("Cannot run slrnface: WINDOWID not found in environment."));
++ return;
++ }
++
++ uname (&u);
++ pathlen = strlen (Homedir) + sizeof("/.slrnfaces/")
++ + strlen (u.nodename) + 30;
++ fifo = safe_malloc (pathlen);
++ sprintf (fifo, "%s/.slrnfaces", Homedir);
++ if (mkdir (fifo, 0700))
++ {
++ if (errno != EEXIST)
++ {
++ mutt_error (_("Cannot run slrnface: failed to create %s: %s."),
++ fifo, strerror(errno));
++ return;
++ }
++ }
++ else
++ {
++ FILE *fp;
++
++ /* We'll abuse fifo filename memory here. It's long enough. */
++ sprintf (fifo, "%s/.slrnfaces/README", Homedir);
++ if ((fp = fopen (fifo, "w")) != NULL)
++ {
++ fputs (_(
++"This directory is used to create named pipes for communication between\n"
++"slrnface and its parent process. It should normally be empty because\n"
++"the pipe is deleted right after it has been opened by both processes.\n\n"
++"File names generated by slrnface have the form \"hostname.pid\". It is\n"
++"probably an error if they linger here longer than a fraction of a second.\n\n"
++"However, if the directory is mounted from an NFS server, you might see\n"
++"special files created by your NFS server while slrnface is running.\n"
++"Do not try to remove them.\n"), fp);
++ fclose (fp);
++ }
++ }
++
++ status = snprintf (fifo, pathlen, "%s/.slrnfaces/%s.%ld", Homedir,
++ u.nodename, (long)getpid());
++ if (status < 0)
++ goto clean_face;
++
++ unlink (fifo);
++ if (mkfifo (fifo, 0600) < 0)
++ {
++ mutt_error (_("Cannot run slrnface, failed to create %s: %s."), fifo,
++ strerror(errno));
++ goto clean_face;
++ }
++
++ pid = fork();
++ switch (pid)
++ {
++ case -1: break;
++ case 0: execlp ("slrnface", "slrnface", fifo, (char *)0);
++ /* This is child, exit on error. */
++ _exit (10);
++ default: do {
++ pidst = waitpid (pid, &status, 0);
++ } while (pidst == -1 && errno == EINTR);
++
++ if (!WIFEXITED (status))
++ mutt_error (_("Slrnface abnormaly exited, code %d."), status);
++ else
++ {
++ char *message;
++
++ switch (WEXITSTATUS (status))
++ {
++ case 0: /* All fine, open the pipe */
++ slrnface_fd = open (fifo, O_WRONLY, 0600);
++ write (slrnface_fd, "start\n", sizeof "start");
++ goto clean_face;
++ case 1: message = "couldn't connect to display";
++ break;
++ case 2: message = "WINDOWID not found in environment";
++ break;
++ case 3: message = "couldn't find controlling terminal";
++ break;
++ case 4: message = "terminal doesn't export width and height";
++ break;
++ case 5: message = "cannot open FIFO";
++ break;
++ case 6: message = "fork() failed";
++ break;
++ case 10: message = "executable not found";
++ break;
++ default: message = "unknown error";
++ }
++ mutt_error (_("Slrnface failed: %s."), message);
++ }
++ }
++
++clean_face:
++ unlink (fifo);
++ free (fifo);
++}
++
++void mutt_stop_slrnface(void)
++{
++ if (slrnface_fd >= 0)
++ close(slrnface_fd);
++ slrnface_fd = -1;
++
++ /* FIFO has been unlinked in the startup function. */
++}
+diff -ruN mutt-1.4./init.h mutt-1.4/init.h
+--- mutt-1.4./init.h Mon Jan 20 00:17:02 2003
++++ mutt-1.4/init.h Mon Jan 20 00:28:31 2003
+@@ -2437,6 +2437,12 @@
+ ** Controls whether mutt writes out the Bcc header when preparing
+ ** messages to be sent. Exim users may wish to use this.
+ */
++ { "xface", DT_BOOL, R_NONE, OPTXFACE, 0 },
++ /*
++ ** .pp
++ ** Controls whether mutt uses slrnface to display X-Faces when run
++ ** in an X11 terminal emulator.
++ */
+ /*--*/
+ { NULL }
+ };
+diff -ruN mutt-1.4./main.c mutt-1.4/main.c
+--- mutt-1.4./main.c Mon Jan 20 00:17:02 2003
++++ mutt-1.4/main.c Mon Jan 20 00:28:31 2003
+@@ -841,6 +841,8 @@
+
+ mutt_folder_hook (folder);
+
++ mutt_start_slrnface();
++
+ if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
+ || !explicit_folder)
+ {
+@@ -849,6 +851,8 @@
+ safe_free ((void **)&Context);
+ }
+ mutt_endwin (Errorbuf);
++
++ mutt_stop_slrnface();
+ }
+
+ exit (0);
+diff -ruN mutt-1.4./mutt.h mutt-1.4/mutt.h
+--- mutt-1.4./mutt.h Mon Jan 20 00:17:02 2003
++++ mutt-1.4/mutt.h Mon Jan 20 00:28:31 2003
+@@ -422,6 +422,7 @@
+ OPTWRAP,
+ OPTWRAPSEARCH,
+ OPTWRITEBCC, /* write out a bcc header? */
++ OPTXFACE,
+ OPTXMAILER,
+
+ /* PGP options */
+@@ -540,6 +541,7 @@
+ char *x_label;
+ LIST *references; /* message references (in reverse order) */
+ LIST *in_reply_to; /* in-reply-to header content */
++ LIST *x_face; /* X-Face header content */
+ LIST *userhdrs; /* user defined headers */
+ } ENVELOPE;
+
+diff -ruN mutt-1.4./muttlib.c mutt-1.4/muttlib.c
+--- mutt-1.4./muttlib.c Mon Jan 20 00:17:02 2003
++++ mutt-1.4/muttlib.c Mon Jan 20 00:28:31 2003
+@@ -650,6 +650,7 @@
+ safe_free ((void **) &(*p)->date);
+ mutt_free_list (&(*p)->references);
+ mutt_free_list (&(*p)->in_reply_to);
++ mutt_free_list (&(*p)->x_face);
+ mutt_free_list (&(*p)->userhdrs);
+ safe_free ((void **) p);
+ }
+diff -ruN mutt-1.4./pager.c mutt-1.4/pager.c
+--- mutt-1.4./pager.c Mon Jan 20 00:17:02 2003
++++ mutt-1.4/pager.c Mon Jan 20 00:28:31 2003
+@@ -1431,6 +1431,66 @@
+ return cur;
+ }
+
++static void
++mutt_display_xface (HEADER *hdr)
++{
++ LIST *face;
++ char buf[2000];
++
++ if (slrnface_fd < 0)
++ return;
++
++ if (!hdr)
++ return;
++
++ face = hdr->env->x_face;
++
++ if (face == NULL || face->data == NULL)
++ write(slrnface_fd, "clear\n", sizeof "clear");
++ else
++ do {
++ int len;
++
++ len = snprintf (buf, sizeof (buf), "xface %s\n", face->data);
++ if (len <= sizeof (buf))
++ {
++ write (slrnface_fd, buf, len);
++ break;
++ }
++ /*
++ * slrnface will ignore X-Faces larger than approx. 2000 chars, so
++ * try the next one, if it exists.
++ */
++ } while (face = face->next);
++}
++
++static void
++mutt_clear_xface (void)
++{
++ if (slrnface_fd < 0)
++ return;
++
++ write(slrnface_fd, "clear\n", sizeof "clear");
++}
++
++static void
++mutt_suppress_xface (void)
++{
++ if (slrnface_fd < 0)
++ return;
++
++ write(slrnface_fd, "suppress\n", sizeof "suppress");
++}
++
++static void
++mutt_show_xface (void)
++{
++ if (slrnface_fd < 0)
++ return;
++
++ write(slrnface_fd, "show\n", sizeof "show");
++}
++
+ static struct mapping_t PagerHelp[] = {
+ { N_("Exit"), OP_EXIT },
+ { N_("PrevPg"), OP_PREV_PAGE },
+@@ -1535,6 +1595,9 @@
+ snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer);
+ }
+
++ if (IsHeader (extra))
++ mutt_display_xface(extra->hdr);
++
+ while (ch != -1)
+ {
+ mutt_curs_set (0);
+@@ -2035,7 +2098,9 @@
+ if (! InHelp)
+ {
+ InHelp = 1;
++ mutt_suppress_xface ();
+ mutt_help (MENU_PAGER);
++ mutt_show_xface ();
+ redraw = REDRAW_FULL;
+ InHelp = 0;
+ }
+@@ -2329,59 +2394,71 @@
+ case OP_MAIL:
+ CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
+ CHECK_ATTACH;
++ mutt_suppress_xface ();
+ ci_send_message (0, NULL, NULL, NULL, NULL);
++ mutt_show_xface ();
+ redraw = REDRAW_FULL;
+ break;
+
+ case OP_REPLY:
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ CHECK_ATTACH;
++ mutt_suppress_xface();
+ if (IsMsgAttach (extra))
+ mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy,
+ SENDREPLY);
+ else
+ ci_send_message (SENDREPLY, NULL, NULL, extra->ctx, extra->hdr);
++ mutt_show_xface ();
+ redraw = REDRAW_FULL;
+ break;
+
+ case OP_RECALL_MESSAGE:
+ CHECK_MODE(IsHeader (extra));
+ CHECK_ATTACH;
++ mutt_suppress_xface();
+ ci_send_message (SENDPOSTPONED, NULL, NULL, extra->ctx, extra->hdr);
++ mutt_show_xface ();
+ redraw = REDRAW_FULL;
+ break;
+
+ case OP_GROUP_REPLY:
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ CHECK_ATTACH;
++ mutt_suppress_xface();
+ if (IsMsgAttach (extra))
+ mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy, SENDREPLY|SENDGROUPREPLY);
+ else
+ ci_send_message (SENDREPLY | SENDGROUPREPLY, NULL, NULL, extra->ctx, extra->hdr);
++ mutt_suppress_xface ();
+ redraw = REDRAW_FULL;
+ break;
+
+ case OP_LIST_REPLY:
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ CHECK_ATTACH;
++ mutt_suppress_xface();
+ if (IsMsgAttach (extra))
+ mutt_attach_reply (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy, SENDREPLY|SENDLISTREPLY);
+ else
+ ci_send_message (SENDREPLY | SENDLISTREPLY, NULL, NULL, extra->ctx, extra->hdr);
++ mutt_show_xface ();
+ redraw = REDRAW_FULL;
+ break;
+
+ case OP_FORWARD_MESSAGE:
+ CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
+ CHECK_ATTACH;
++ mutt_suppress_xface();
+ if (IsMsgAttach (extra))
+ mutt_attach_forward (extra->fp, extra->hdr, extra->idx,
+ extra->idxlen, extra->bdy);
+ else
+ ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
++ mutt_show_xface ();
+ redraw = REDRAW_FULL;
+ break;
+
+@@ -2430,7 +2507,9 @@
+ break;
+
+ case OP_SHELL_ESCAPE:
++ mutt_suppress_xface ();
+ mutt_shell_escape ();
++ mutt_show_xface ();
+ MAYBE_REDRAW (redraw);
+ break;
+
+@@ -2573,5 +2652,6 @@
+ safe_free ((void **) &lineInfo);
+ if (index)
+ mutt_menuDestroy(&index);
++ mutt_clear_xface ();
+ return (rc != -1 ? rc : 0);
+ }
+diff -ruN mutt-1.4./parse.c mutt-1.4/parse.c
+--- mutt-1.4./parse.c Tue Jan 29 11:05:20 2002
++++ mutt-1.4/parse.c Mon Jan 20 00:28:32 2003
+@@ -90,6 +90,27 @@
+ /* not reached */
+ }
+
++static LIST *mutt_add_x_face (LIST *lst, char *face)
++{
++ LIST *n;
++
++ n = safe_malloc(sizeof(LIST));
++ n->data = safe_strdup(face);
++ n->next = NULL;
++
++ if (lst)
++ {
++ LIST *l;
++
++ for(l = lst; l->next; l = l->next);
++ l->next = n;
++ }
++ else
++ lst = n;
++
++ return lst;
++}
++
+ static LIST *mutt_parse_references (char *s, int in_reply_to)
+ {
+ LIST *t, *lst = NULL;
+@@ -1207,6 +1228,11 @@
+ e->x_label = safe_strdup(p);
+ matched = 1;
+ }
++ else if (ascii_strcasecmp (line+1, "-face") == 0)
++ {
++ e->x_face = mutt_add_x_face (e->x_face, p);
++ matched = 1;
++ }
+
+ default:
+ break;
+diff -ruN mutt-1.4./sendlib.c mutt-1.4/sendlib.c
+--- mutt-1.4./sendlib.c Sat Apr 20 09:25:49 2002
++++ mutt-1.4/sendlib.c Mon Jan 20 00:28:32 2003
+@@ -1663,6 +1663,15 @@
+ fputc ('\n', fp);
+ }
+
++ /* Add X-Face headers */
++ if (env->x_face)
++ {
++ LIST *face;
++
++ for (face = env->x_face; face; face = face->next)
++ fprintf (fp, "X-Face: %s\n", face->data);
++ }
++
+ if (mode == 0 && !privacy && option (OPTXMAILER))
+ {
+ /* Add a vanity header */