Andreas Krennmair:
authorak1 <ak1@e385b8ad-14ed-0310-8656-cc95a2468c6d>
Fri, 14 Jan 2005 22:39:14 +0000 (22:39 +0000)
committerak1 <ak1@e385b8ad-14ed-0310-8656-cc95a2468c6d>
Fri, 14 Jan 2005 22:39:14 +0000 (22:39 +0000)
* added dw.xface patch for X-Face header support via slrnface

git-svn-id: svn://svn.berlios.de/mutt-ng/trunk@16 e385b8ad-14ed-0310-8656-cc95a2468c6d

ChangeLog.mutt-ng
PATCHES
globals.h
init.c
init.h
main.c
mutt.h
muttlib.c
pager.c
parse.c
sendlib.c

index 4d29835..73ceee2 100644 (file)
@@ -2,6 +2,7 @@ Changes specific to mutt-ng:
 2004-01-14:
   * Integrated the following patches:
     * rr.compressed for compressed folders
 2004-01-14:
   * Integrated the following patches:
     * rr.compressed for compressed folders
+    * dw.xface for X-Face support via slrnface
   * Changed User-Agent string
   * Added operating_system to set fake operating system for User-Agent string
 
   * Changed User-Agent string
   * Added operating_system to set fake operating system for User-Agent string
 
diff --git a/PATCHES b/PATCHES
index 6f0bdfe..34de6be 100644 (file)
--- a/PATCHES
+++ b/PATCHES
@@ -7,3 +7,4 @@ patch-1.5.5.1.cd.purge_message.3.4
 patch-1.5.5.1.cd.trash_folder.3.4
 vvv.quote
 vvv.nntp
 patch-1.5.5.1.cd.trash_folder.3.4
 vvv.quote
 vvv.nntp
+dw.xface
index f7b2058..002c509 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -242,6 +242,8 @@ WHERE char *SmimeGetCertEmailCommand;
 
 
 
 
 
 
+WHERE int slrnface_fd INITVAL (-1);
+
 #ifdef DEBUG
 WHERE FILE *debugfile INITVAL (0);
 WHERE int debuglevel INITVAL (0);
 #ifdef DEBUG
 WHERE FILE *debugfile INITVAL (0);
 WHERE int debuglevel INITVAL (0);
diff --git a/init.c b/init.c
index cbc9645..d566add 100644 (file)
--- a/init.c
+++ b/init.c
@@ -43,6 +43,8 @@
 #include <string.h>
 #include <sys/utsname.h>
 #include <errno.h>
 #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)
 #include <sys/wait.h>
 
 void toggle_quadoption (int opt)
@@ -2175,3 +2177,131 @@ int mutt_get_hook_type (const char *name)
       return c->data;
   return 0;
 }
       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 --git a/init.h b/init.h
index 111ad72..970bcd6 100644 (file)
--- a/init.h
+++ b/init.h
@@ -2948,6 +2948,12 @@ struct option_t MuttVars[] = {
   ** xterm_set_titles has been set. This string is identical in formatting
   ** to the one used by ``$$status_format''.
   */
   ** xterm_set_titles has been set. This string is identical in formatting
   ** to the one used by ``$$status_format''.
   */
+  { "xface",           DT_BOOL, R_NONE, OPTXFACE, 0 },
+  /*
+  ** .pp
+  ** Controls whether mutt uses slrnface to display X-Faces when run
+  ** in an X11 terminal emulator.
+  */
 #ifdef USE_NNTP
   { "x_comment_to",   DT_BOOL, R_NONE, OPTXCOMMENTTO, 0 },
   /*
 #ifdef USE_NNTP
   { "x_comment_to",   DT_BOOL, R_NONE, OPTXCOMMENTTO, 0 },
   /*
diff --git a/main.c b/main.c
index 89fa6d3..03fd326 100644 (file)
--- a/main.c
+++ b/main.c
@@ -967,6 +967,8 @@ int main (int argc, char **argv)
 
     mutt_folder_hook (folder);
 
 
     mutt_folder_hook (folder);
 
+    mutt_start_slrnface();
+
     if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
        || !explicit_folder)
     {
     if((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL))
        || !explicit_folder)
     {
@@ -975,6 +977,8 @@ int main (int argc, char **argv)
        FREE (&Context);
     }
     mutt_endwin (Errorbuf);
        FREE (&Context);
     }
     mutt_endwin (Errorbuf);
+
+    mutt_stop_slrnface();
   }
 
   exit (0);
   }
 
   exit (0);
diff --git a/mutt.h b/mutt.h
index c99861c..dda0aaa 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -451,6 +451,7 @@ enum
   OPTWRAP,
   OPTWRAPSEARCH,
   OPTWRITEBCC,         /* write out a bcc header? */
   OPTWRAP,
   OPTWRAPSEARCH,
   OPTWRITEBCC,         /* write out a bcc header? */
+  OPTXFACE,
   OPTXMAILER,
   OPTXTERMSETTITLES,
 
   OPTXMAILER,
   OPTXTERMSETTITLES,
 
@@ -603,6 +604,7 @@ typedef struct envelope
 #endif
   LIST *references;            /* message references (in reverse order) */
   LIST *in_reply_to;           /* in-reply-to header content */
 #endif
   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;
 
   LIST *userhdrs;              /* user defined headers */
 } ENVELOPE;
 
index 7092882..a2fa4da 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -658,6 +658,7 @@ void mutt_free_envelope (ENVELOPE **p)
 #endif
   mutt_free_list (&(*p)->references);
   mutt_free_list (&(*p)->in_reply_to);
 #endif
   mutt_free_list (&(*p)->references);
   mutt_free_list (&(*p)->in_reply_to);
+  mutt_free_list (&(*p)->x_face);
   mutt_free_list (&(*p)->userhdrs);
   FREE (p);
 }
   mutt_free_list (&(*p)->userhdrs);
   FREE (p);
 }
diff --git a/pager.c b/pager.c
index 7e9a41b..1cf451d 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -1447,6 +1447,57 @@ upNLines (int nlines, struct line_t *info, int cur, int hiding)
   return cur;
 }
 
   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_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 },
 static struct mapping_t PagerHelp[] = {
   { N_("Exit"),        OP_EXIT },
   { N_("PrevPg"), OP_PREV_PAGE },
@@ -1569,6 +1620,9 @@ mutt_pager (const char *banner, const char *fname, int flags, pager_t *extra)
     snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer);
   }
 
     snprintf (helpstr, sizeof (helpstr), "%s %s", tmphelp, buffer);
   }
 
+  if (IsHeader (extra))
+    mutt_display_xface(extra->hdr);
+
   while (ch != -1)
   {
     mutt_curs_set (0);
   while (ch != -1)
   {
     mutt_curs_set (0);
@@ -2098,7 +2152,9 @@ search_next:
        if (! InHelp)
        {
          InHelp = 1;
        if (! InHelp)
        {
          InHelp = 1;
+         mutt_clear_xface ();
          mutt_help (MENU_PAGER);
          mutt_help (MENU_PAGER);
+         mutt_show_xface ();
          redraw = REDRAW_FULL;
          InHelp = 0;
        }
          redraw = REDRAW_FULL;
          InHelp = 0;
        }
@@ -2415,7 +2471,9 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
       case OP_MAIL:
        CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
         CHECK_ATTACH;      
       case OP_MAIL:
        CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
         CHECK_ATTACH;      
+       mutt_clear_xface();
        ci_send_message (0, NULL, NULL, extra->ctx, extra->hdr);
        ci_send_message (0, NULL, NULL, extra->ctx, extra->hdr);
+       mutt_show_xface();
        redraw = REDRAW_FULL;
        break;
 
        redraw = REDRAW_FULL;
        break;
 
@@ -2423,17 +2481,20 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
       case OP_POST:
        CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
        CHECK_ATTACH;
       case OP_POST:
        CHECK_MODE(IsHeader (extra) && !IsAttach (extra));
        CHECK_ATTACH;
+       mutt_clear_xface();
        if (extra->ctx && extra->ctx->magic == M_NNTP &&
            !((NNTP_DATA *)extra->ctx->data)->allowed &&
            query_quadoption (OPT_TOMODERATED,_("Posting to this group not allowed, may be moderated. Continue?")) != M_YES)
          break;
        ci_send_message (SENDNEWS, NULL, NULL, extra->ctx, NULL);
        if (extra->ctx && extra->ctx->magic == M_NNTP &&
            !((NNTP_DATA *)extra->ctx->data)->allowed &&
            query_quadoption (OPT_TOMODERATED,_("Posting to this group not allowed, may be moderated. Continue?")) != M_YES)
          break;
        ci_send_message (SENDNEWS, NULL, NULL, extra->ctx, NULL);
+       mutt_show_xface();
        redraw = REDRAW_FULL;
        break;
 
       case OP_FORWARD_TO_GROUP:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
        CHECK_ATTACH;
        redraw = REDRAW_FULL;
        break;
 
       case OP_FORWARD_TO_GROUP:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
        CHECK_ATTACH;
+       mutt_clear_xface();
        if (extra->ctx && extra->ctx->magic == M_NNTP &&
            !((NNTP_DATA *)extra->ctx->data)->allowed &&
            query_quadoption (OPT_TOMODERATED,_("Posting to this group not allowed, may be moderated. Continue?")) != M_YES)
        if (extra->ctx && extra->ctx->magic == M_NNTP &&
            !((NNTP_DATA *)extra->ctx->data)->allowed &&
            query_quadoption (OPT_TOMODERATED,_("Posting to this group not allowed, may be moderated. Continue?")) != M_YES)
@@ -2443,12 +2504,14 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
                               extra->idxlen, extra->bdy, SENDNEWS);
        else
          ci_send_message (SENDNEWS|SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
                               extra->idxlen, extra->bdy, SENDNEWS);
        else
          ci_send_message (SENDNEWS|SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
+       mutt_show_xface();
        redraw = REDRAW_FULL;
        break;
 
       case OP_FOLLOWUP:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
        CHECK_ATTACH;
        redraw = REDRAW_FULL;
        break;
 
       case OP_FOLLOWUP:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
        CHECK_ATTACH;
+       mutt_clear_xface();
 
         if (IsMsgAttach (extra))
          followup_to = extra->bdy->hdr->env->followup_to;
 
         if (IsMsgAttach (extra))
          followup_to = extra->bdy->hdr->env->followup_to;
@@ -2468,6 +2531,7 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
          else
            ci_send_message (SENDNEWS|SENDREPLY, NULL, NULL,
                             extra->ctx, extra->hdr);
          else
            ci_send_message (SENDNEWS|SENDREPLY, NULL, NULL,
                             extra->ctx, extra->hdr);
+         mutt_show_xface();
          redraw = REDRAW_FULL;
          break;
        }
          redraw = REDRAW_FULL;
          break;
        }
@@ -2475,53 +2539,63 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
 
       case OP_REPLY:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
 
       case OP_REPLY:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
-        CHECK_ATTACH;      
+        CHECK_ATTACH;
+       mutt_clear_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);
         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;
        redraw = REDRAW_FULL;
        break;
 
       case OP_RECALL_MESSAGE:
        CHECK_MODE(IsHeader (extra));
         CHECK_ATTACH;
+       mutt_clear_xface();
        ci_send_message (SENDPOSTPONED, NULL, NULL, extra->ctx, extra->hdr);
        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;
        redraw = REDRAW_FULL;
        break;
 
       case OP_GROUP_REPLY:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
         CHECK_ATTACH;
+       mutt_clear_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);
         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_show_xface();
        redraw = REDRAW_FULL;
        break;
 
       case OP_LIST_REPLY:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
         CHECK_ATTACH;        
        redraw = REDRAW_FULL;
        break;
 
       case OP_LIST_REPLY:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
         CHECK_ATTACH;        
+       mutt_clear_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);
         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;
        redraw = REDRAW_FULL;
        break;
 
       case OP_FORWARD_MESSAGE:
        CHECK_MODE(IsHeader (extra) || IsMsgAttach (extra));
         CHECK_ATTACH;
+       mutt_clear_xface();
         if (IsMsgAttach (extra))
          mutt_attach_forward (extra->fp, extra->hdr, extra->idx,
                               extra->idxlen, extra->bdy, 0);
         else
          ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
         if (IsMsgAttach (extra))
          mutt_attach_forward (extra->fp, extra->hdr, extra->idx,
                               extra->idxlen, extra->bdy, 0);
         else
          ci_send_message (SENDFORWARD, NULL, NULL, extra->ctx, extra->hdr);
+       mutt_show_xface();
        redraw = REDRAW_FULL;
        break;
 
        redraw = REDRAW_FULL;
        break;
 
@@ -2571,7 +2645,9 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
        break;
 
       case OP_SHELL_ESCAPE:
        break;
 
       case OP_SHELL_ESCAPE:
+       mutt_clear_xface ();
        mutt_shell_escape ();
        mutt_shell_escape ();
+       mutt_show_xface ();
        MAYBE_REDRAW (redraw);
        break;
 
        MAYBE_REDRAW (redraw);
        break;
 
@@ -2739,5 +2815,6 @@ CHECK_IMAP_ACL(IMAP_ACL_DELETE);
   FREE (&lineInfo);
   if (index)
     mutt_menuDestroy(&index);
   FREE (&lineInfo);
   if (index)
     mutt_menuDestroy(&index);
+  mutt_clear_xface ();
   return (rc != -1 ? rc : 0);
 }
   return (rc != -1 ? rc : 0);
 }
diff --git a/parse.c b/parse.c
index 84adc1a..686d9ed 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -84,6 +84,27 @@ static char *read_rfc822_line (FILE *f, char *line, size_t *linelen)
   /* not reached */
 }
 
   /* 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;
+}
+
 LIST *mutt_parse_references (char *s, int in_reply_to)
 {
   LIST *t, *lst = NULL;
 LIST *mutt_parse_references (char *s, int in_reply_to)
 {
   LIST *t, *lst = NULL;
@@ -1237,6 +1258,11 @@ int mutt_parse_rfc822_line (ENVELOPE *e, HEADER *hdr, char *line, char *p, short
       e->x_label = safe_strdup(p);
       matched = 1;
     }
       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;
+    }
 #ifdef USE_NNTP
     else if (!mutt_strcasecmp (line + 1, "-comment-to"))
     {
 #ifdef USE_NNTP
     else if (!mutt_strcasecmp (line + 1, "-comment-to"))
     {
index 31596c9..7a718a2 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
@@ -1737,6 +1737,15 @@ int mutt_write_rfc822_header (FILE *fp, ENVELOPE *env, BODY *attach,
     }
   }
 
     }
   }
 
+  /* 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) && !has_agent)
   {
     struct utsname un;
   if (mode == 0 && !privacy && option (OPTXMAILER) && !has_agent)
   {
     struct utsname un;