From: ak1 Date: Fri, 14 Jan 2005 22:39:14 +0000 (+0000) Subject: Andreas Krennmair: X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=047342c2a0526885217e03d06e9b7a715f55b92f Andreas Krennmair: * 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 --- diff --git a/ChangeLog.mutt-ng b/ChangeLog.mutt-ng index 4d29835..73ceee2 100644 --- a/ChangeLog.mutt-ng +++ b/ChangeLog.mutt-ng @@ -2,6 +2,7 @@ Changes specific to mutt-ng: 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 diff --git a/PATCHES b/PATCHES index 6f0bdfe..34de6be 100644 --- 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 +dw.xface diff --git a/globals.h b/globals.h index f7b2058..002c509 100644 --- 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); diff --git a/init.c b/init.c index cbc9645..d566add 100644 --- a/init.c +++ b/init.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include void toggle_quadoption (int opt) @@ -2175,3 +2177,131 @@ int mutt_get_hook_type (const char *name) 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 --- 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''. */ + { "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 }, /* diff --git a/main.c b/main.c index 89fa6d3..03fd326 100644 --- a/main.c +++ b/main.c @@ -967,6 +967,8 @@ int main (int argc, char **argv) mutt_folder_hook (folder); + mutt_start_slrnface(); + 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); + + mutt_stop_slrnface(); } exit (0); diff --git a/mutt.h b/mutt.h index c99861c..dda0aaa 100644 --- a/mutt.h +++ b/mutt.h @@ -451,6 +451,7 @@ enum OPTWRAP, OPTWRAPSEARCH, OPTWRITEBCC, /* write out a bcc header? */ + OPTXFACE, 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 */ + LIST *x_face; /* X-Face header content */ LIST *userhdrs; /* user defined headers */ } ENVELOPE; diff --git a/muttlib.c b/muttlib.c index 7092882..a2fa4da 100644 --- 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); + mutt_free_list (&(*p)->x_face); mutt_free_list (&(*p)->userhdrs); FREE (p); } diff --git a/pager.c b/pager.c index 7e9a41b..1cf451d 100644 --- a/pager.c +++ b/pager.c @@ -1447,6 +1447,57 @@ upNLines (int nlines, struct line_t *info, int cur, int hiding) 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 }, @@ -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); } + if (IsHeader (extra)) + mutt_display_xface(extra->hdr); + while (ch != -1) { mutt_curs_set (0); @@ -2098,7 +2152,9 @@ search_next: if (! InHelp) { InHelp = 1; + mutt_clear_xface (); mutt_help (MENU_PAGER); + mutt_show_xface (); 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; + mutt_clear_xface(); ci_send_message (0, NULL, NULL, extra->ctx, extra->hdr); + mutt_show_xface(); 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; + 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); + mutt_show_xface(); 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) @@ -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); + mutt_show_xface(); 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; @@ -2468,6 +2531,7 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE); else ci_send_message (SENDNEWS|SENDREPLY, NULL, NULL, extra->ctx, extra->hdr); + mutt_show_xface(); redraw = REDRAW_FULL; break; } @@ -2475,53 +2539,63 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE); 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); + mutt_show_xface(); 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); + mutt_show_xface(); 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); + mutt_show_xface(); 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); + mutt_show_xface(); 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); + mutt_show_xface(); redraw = REDRAW_FULL; break; @@ -2571,7 +2645,9 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE); break; case OP_SHELL_ESCAPE: + mutt_clear_xface (); mutt_shell_escape (); + mutt_show_xface (); MAYBE_REDRAW (redraw); break; @@ -2739,5 +2815,6 @@ CHECK_IMAP_ACL(IMAP_ACL_DELETE); FREE (&lineInfo); if (index) mutt_menuDestroy(&index); + mutt_clear_xface (); return (rc != -1 ? rc : 0); } diff --git a/parse.c b/parse.c index 84adc1a..686d9ed 100644 --- a/parse.c +++ b/parse.c @@ -84,6 +84,27 @@ static char *read_rfc822_line (FILE *f, char *line, size_t *linelen) /* 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; @@ -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; } + 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")) { diff --git a/sendlib.c b/sendlib.c index 31596c9..7a718a2 100644 --- 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;