From owner-freebsd-ports-bugs@FreeBSD.ORG Thu Mar 16 15:10:39 2006 Return-Path: X-Original-To: freebsd-ports-bugs@hub.freebsd.org Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C287616A6C6 for ; Thu, 16 Mar 2006 15:10:39 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9E52543DA6 for ; Thu, 16 Mar 2006 15:09:33 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id k2GF9SxP082198 for ; Thu, 16 Mar 2006 15:09:28 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id k2GF9S06082197; Thu, 16 Mar 2006 15:09:28 GMT (envelope-from gnats) Resent-Date: Thu, 16 Mar 2006 15:09:28 GMT Resent-Message-Id: <200603161509.k2GF9S06082197@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Udo Schweigert Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7DF7E16A42B for ; Thu, 16 Mar 2006 08:15:14 +0000 (UTC) (envelope-from udo.schweigert@siemens.com) Received: from david.siemens.de (david.siemens.de [192.35.17.14]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2061243DA1 for ; Thu, 16 Mar 2006 08:14:17 +0000 (GMT) (envelope-from udo.schweigert@siemens.com) Received: from mail2.siemens.de (localhost [127.0.0.1]) by david.siemens.de (8.12.6/8.12.6) with ESMTP id k2G8EFlw003109 for ; Thu, 16 Mar 2006 09:14:15 +0100 Received: from mars.cert.siemens.com (mars.cert.siemens.com [139.25.19.9]) by mail2.siemens.de (8.12.6/8.12.6) with ESMTP id k2G8EFTa015536 for ; Thu, 16 Mar 2006 09:14:15 +0100 Received: from alaska.cert.siemens.com (alaska.cert.siemens.com [139.25.19.64]) by mars.cert.siemens.com (8.13.5/8.13.5/$SiemensCERT: mail/cert.mc.pre, v 1.67 2005/05/09 15:42:50 mailadm Exp $) with ESMTP id k2G8EFc4098302 for ; Thu, 16 Mar 2006 09:14:15 +0100 (CET) Received: from alaska.cert.siemens.com (alaska.cert.siemens.com [139.25.19.64]) by alaska.cert.siemens.com (8.13.5/8.13.5/$Ust: hosts/alaska/mail/config.mc, v 1.19 2004/08/29 16:18:57 ust Exp $) with ESMTP id k2G8EFDU049269 for ; Thu, 16 Mar 2006 09:14:15 +0100 (CET) (envelope-from ust@alaska.cert.siemens.com) Received: (from ust@localhost) by alaska.cert.siemens.com (8.13.5/8.13.5/$Ust: hosts/alaska/mail/submit.mc,v 1.6 2004/08/29 16:18:57 ust Exp $) id k2G8EFZ5036221; Thu, 16 Mar 2006 09:14:15 +0100 (CET) (envelope-from ust) Message-Id: <200603160814.k2G8EFZ5036221@alaska.cert.siemens.com> Date: Thu, 16 Mar 2006 09:14:15 +0100 (CET) From: Udo Schweigert To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: ports/94542: maintainer-update of mail/mutt-devel X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Udo Schweigert List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Mar 2006 15:10:39 -0000 >Number: 94542 >Category: ports >Synopsis: maintainer-update of mail/mutt-devel >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: maintainer-update >Submitter-Id: current-users >Arrival-Date: Thu Mar 16 15:09:28 GMT 2006 >Closed-Date: >Last-Modified: >Originator: Udo Schweigert >Release: FreeBSD 6.0-RELEASE i386 >Organization: >Environment: >Description: Maintainer update of mail/mutt-devel: - Fix the WITH_MUTT_SIGNATURE_MENU patch. - Bump PORTREVISION. Committer: new file (cvs add) files/extra-patch-signature-menu >How-To-Repeat: >Fix: diff -ru /usr/ports/mail/mutt-devel/Makefile ./Makefile --- /usr/ports/mail/mutt-devel/Makefile Thu Mar 16 06:13:09 2006 +++ ./Makefile Thu Mar 16 09:13:09 2006 @@ -101,7 +101,7 @@ PORTNAME= mutt-devel PORTVERSION= 1.5.11 -PORTREVISION?= 2 +PORTREVISION?= 3 CATEGORIES+= mail ipv6 .if defined(WITH_MUTT_NNTP) CATEGORIES+= news @@ -187,16 +187,10 @@ .if defined(WITH_MUTT_MAILDIR_HEADER_CACHE) WITH_MUTT_IMAP_HEADER_CACHE= yes .endif -.if defined(WITH_MUTT_SIGNATURE_MENU) -IGNORE= cannot install: the WITH_MUTT_SIGNATURE_MENU does not work at the moment -.endif .if defined(WITH_MUTT_SIDEBAR_PATCH) .if defined(WITH_MUTT_NNTP) IGNORE= cannot install: the WITH_MUTT_SIDEBAR_PATCH and WITH_MUTT_NNTP are not compatible .endif -.if defined(WITH_MUTT_SIGNATURE_MENU) -IGNORE= cannot install: the WITH_MUTT_SIDEBAR_PATCH and WITH_MUTT_SIGNATURE_MENU are not compatible -.endif .endif .if defined(WITH_MUTT_ASSUMED_CHARSET_PATCH) .if defined(WITH_MUTT_NNTP) @@ -311,6 +305,11 @@ post-patch:: @${PATCH} ${PATCH_ARGS} -p1 < ${PATCHDIR}/extra-patch-maildir-header-cache .endif +.if defined(WITH_MUTT_SIGNATURE_MENU) +XML_NEEDED= yes +post-patch:: + @${PATCH} ${PATCH_ARGS} -p1 < ${PATCHDIR}/extra-patch-signature-menu +.endif .if defined(WITH_MUTT_MAILDIR_MTIME_PATCH) post-patch:: .if defined(WITH_MUTT_NNTP) @@ -390,10 +389,6 @@ .if ! defined(WITHOUT_MUTT_QUOTE_PATCH) PATCHFILES+= patch-${VVV_PATCH_VERSION}.vvv.initials.gz:vvv \ patch-${VVV_PATCH_VERSION}.vvv.quote.gz:vvv -XML_NEEDED= yes -.endif -.if defined(WITH_MUTT_SIGNATURE_MENU) -PATCHFILES+= patch-${CD_PATCH_VERSION}.cd.signatures_menu.2.1:cd XML_NEEDED= yes .endif .if defined(WITH_MUTT_IFDEF_PATCH) diff -ru /usr/ports/mail/mutt-devel/files/extra-patch-signature-menu ./files/extra-patch-signature-menu --- /usr/ports/mail/mutt-devel/files/extra-patch-signature-menu Thu Jan 1 01:00:00 1970 +++ ./files/extra-patch-signature-menu Thu Mar 16 08:17:28 2006 @@ -0,0 +1,729 @@ +--- mutt-1.5.11/PATCHES Dec 2002 17:44:54 -0000 3.6 ++++ mutt-1.5.11/PATCHES Feb 2004 13:19:42 -0000 +@@ -0,0 +1 @@ ++patch-1.5.11.cd.signatures_menu.2.1 +--- mutt-1.5.11/Makefile.am.orig Thu Aug 11 23:27:28 2005 ++++ mutt-1.5.11/Makefile.am Sat Mar 11 21:47:55 2006 +@@ -25,7 +25,7 @@ + main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \ + postpone.c query.c recvattach.c recvcmd.c \ + rfc822.c rfc1524.c rfc2047.c rfc2231.c \ +- score.c send.c sendlib.c signal.c sort.c \ ++ score.c send.c sendlib.c signal.c signature.c sort.c \ + status.c system.c thread.c charset.c history.c lib.c \ + muttlib.c editmsg.c utf8.c mbyte.c wcwidth.c \ + url.c ascii.c mutt_idna.c crypt-mod.c crypt-mod.h +--- mutt-1.5.11/Makefile.in.orig Thu Sep 15 16:22:50 2005 ++++ mutt-1.5.11/Makefile.in Sat Mar 11 21:50:27 2006 +@@ -89,7 +89,7 @@ + recvattach.$(OBJEXT) recvcmd.$(OBJEXT) rfc822.$(OBJEXT) \ + rfc1524.$(OBJEXT) rfc2047.$(OBJEXT) rfc2231.$(OBJEXT) \ + score.$(OBJEXT) send.$(OBJEXT) sendlib.$(OBJEXT) \ +- signal.$(OBJEXT) sort.$(OBJEXT) status.$(OBJEXT) \ ++ signal.$(OBJEXT) signature.${OBJEXT} sort.$(OBJEXT) status.$(OBJEXT) \ + system.$(OBJEXT) thread.$(OBJEXT) charset.$(OBJEXT) \ + history.$(OBJEXT) lib.$(OBJEXT) muttlib.$(OBJEXT) \ + editmsg.$(OBJEXT) utf8.$(OBJEXT) mbyte.$(OBJEXT) \ +@@ -307,7 +307,7 @@ + main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \ + postpone.c query.c recvattach.c recvcmd.c \ + rfc822.c rfc1524.c rfc2047.c rfc2231.c \ +- score.c send.c sendlib.c signal.c sort.c \ ++ score.c send.c sendlib.c signal.c signature.c sort.c \ + status.c system.c thread.c charset.c history.c lib.c \ + muttlib.c editmsg.c utf8.c mbyte.c wcwidth.c \ + url.c ascii.c mutt_idna.c crypt-mod.c crypt-mod.h +--- mutt-1.5.11/OPS.orig Sun Jul 24 18:56:42 2005 ++++ mutt-1.5.11/OPS Sat Mar 11 21:47:55 2006 +@@ -38,6 +38,7 @@ + OP_COMPOSE_POSTPONE_MESSAGE "save this message to send later" + OP_COMPOSE_RENAME_FILE "rename/move an attached file" + OP_COMPOSE_SEND_MESSAGE "send the message" ++OP_COMPOSE_SIG "choose a signature" + OP_COMPOSE_TOGGLE_DISPOSITION "toggle disposition between inline/attachment" + OP_COMPOSE_TOGGLE_UNLINK "toggle whether to delete file after sending it" + OP_COMPOSE_UPDATE_ENCODING "update an attachment's encoding info" +@@ -131,6 +132,7 @@ + OP_NEXT_ENTRY "move to the next entry" + OP_NEXT_LINE "scroll down one line" + OP_NEXT_PAGE "move to the next page" ++OP_NEXT_SIG "move to the next signature" + OP_PAGER_BOTTOM "jump to the bottom of the message" + OP_PAGER_HIDE_QUOTED "toggle display of quoted text" + OP_PAGER_SKIP_QUOTED "skip beyond quoted text" +@@ -139,10 +141,12 @@ + OP_PREV_ENTRY "move to the previous entry" + OP_PREV_LINE "scroll up one line" + OP_PREV_PAGE "move to the previous page" ++OP_PREV_SIG "move to the previous signature" + OP_PRINT "print the current entry" + OP_QUERY "query external program for addresses" + OP_QUERY_APPEND "append new query results to current results" + OP_QUIT "save changes to mailbox and quit" ++OP_RANDOM_SIG "pick a signature at random" + OP_RECALL_MESSAGE "recall a postponed message" + OP_REDRAW "clear and redraw the screen" + OP_REFORMAT_WINCH "{internal}" +@@ -156,6 +160,7 @@ + OP_SEARCH_OPPOSITE "search for next match in opposite direction" + OP_SEARCH_TOGGLE "toggle search pattern coloring" + OP_SHELL_ESCAPE "invoke a command in a subshell" ++OP_SIG_SEARCH "search signatures matching a pattern" + OP_SORT "sort messages" + OP_SORT_REVERSE "sort messages in reverse order" + OP_TAG "tag the current entry" +--- mutt-1.5.11/compose.c.orig Thu Aug 11 21:37:23 2005 ++++ mutt-1.5.11/compose.c Sat Mar 11 21:47:55 2006 +@@ -1128,6 +1128,12 @@ + /* no send2hook, since this doesn't modify the message */ + break; + ++ case OP_COMPOSE_SIG: ++ mutt_signature(msg->content->filename); ++ MAYBE_REDRAW (menu->redraw); ++ mutt_update_encoding (msg->content); ++ break; ++ + case OP_PIPE: + case OP_FILTER: + CHECK_COUNT; +--- mutt-1.5.11/doc/manual.xml.head.orig Tue Sep 6 18:46:44 2005 ++++ mutt-1.5.11/doc/manual.xml.head Sat Mar 11 21:48:05 2006 +@@ -908,6 +908,7 @@ + c edit-cc edit the Cc field + b edit-bcc edit the Bcc field + y send-message send the message ++ESC s signature-menu select a signature and append it to your mail + s edit-subject edit the Subject + S smime-menu select S/MIME options + f edit-fcc specify an ``Fcc'' mailbox +--- mutt-1.5.11/functions.h.orig Sun Jul 24 18:56:42 2005 ++++ mutt-1.5.11/functions.h Sat Mar 11 21:48:05 2006 +@@ -311,6 +311,7 @@ + { "view-attach", OP_VIEW_ATTACH, M_ENTER_S }, + { "send-message", OP_COMPOSE_SEND_MESSAGE, "y" }, + { "pipe-entry", OP_PIPE, "|" }, ++ { "signature-menu", OP_COMPOSE_SIG, "\033s" }, + + { "attach-key", OP_COMPOSE_ATTACH_KEY, "\033k" }, + { "pgp-menu", OP_COMPOSE_PGP_MENU, "p" }, +@@ -368,6 +369,19 @@ + { "mail", OP_MAIL, "m" }, + { "query", OP_QUERY, "Q" }, + { "query-append", OP_QUERY_APPEND, "A" }, ++ { NULL, 0, NULL } ++}; ++ ++/* Signature Menu */ ++struct binding_t OpSig[] = { ++ { "next-sig", OP_NEXT_SIG, "j" }, ++ { "previous-sig", OP_PREV_SIG, "k" }, ++ { "random-sig", OP_RANDOM_SIG, "r" }, ++ { NULL, 0, NULL } ++}; ++ ++struct binding_t OpSigDir[] = { ++ { "search-sig", OP_SIG_SEARCH, "/" }, + { NULL, 0, NULL } + }; + +--- mutt-1.5.11/globals.h.orig Thu Sep 15 16:19:54 2005 ++++ mutt-1.5.11/globals.h Sat Mar 11 21:48:05 2006 +@@ -109,6 +109,7 @@ + WHERE char *Sendmail; + WHERE char *Shell; + WHERE char *Signature; ++WHERE char *SigDirectory; + WHERE char *SimpleSearch; + WHERE char *Spoolfile; + WHERE char *SpamSep; +--- mutt-1.5.11/init.h.orig Thu Sep 15 16:19:54 2005 ++++ mutt-1.5.11/init.h Sat Mar 11 21:48:05 2006 +@@ -2457,6 +2457,14 @@ + ** assumed that filename is a shell command and input should be read from + ** its stdout. + */ ++ { "signatures_directory", DT_PATH, R_NONE, UL &SigDirectory, UL "" }, ++ /* ++ ** .pp ++ ** Specifies the path where your signatures are located. In the files of ++ ** this directory, the signatures are separated by blank lines and/or ++ ** sig_dashes (``-- ''). ++ ** You can choose between these signatures from the compose menu. ++ */ + { "simple_search", DT_STR, R_NONE, UL &SimpleSearch, UL "~f %s | ~s %s" }, + /* + ** .pp +--- mutt-1.5.11/keymap.c.orig Wed Sep 7 10:19:43 2005 ++++ mutt-1.5.11/keymap.c Sat Mar 11 21:48:05 2006 +@@ -55,6 +55,8 @@ + + + { "query", MENU_QUERY }, ++ { "signature", MENU_SIG }, ++ { "sig_directory", MENU_SIG_DIR }, + { "generic", MENU_GENERIC }, + { NULL, 0 } + }; +@@ -560,6 +562,8 @@ + create_bindings (OpPost, MENU_POST); + create_bindings (OpQuery, MENU_QUERY); + create_bindings (OpAlias, MENU_ALIAS); ++ create_bindings (OpSig, MENU_SIG); ++ create_bindings (OpSigDir, MENU_SIG_DIR); + + + if ((WithCrypto & APPLICATION_PGP)) +@@ -658,6 +662,9 @@ + km_bindkey ("", MENU_ATTACH, OP_VIEW_ATTACH); + km_bindkey ("", MENU_COMPOSE, OP_VIEW_ATTACH); + ++ km_bindkey ("", MENU_SIG, OP_PREV_SIG); ++ km_bindkey ("", MENU_SIG, OP_NEXT_SIG); ++ + /* edit-to (default "t") hides generic tag-entry in Compose menu + This will bind tag-entry to "T" in the Compose menu */ + km_bindkey ("T", MENU_COMPOSE, OP_TAG); +@@ -793,6 +800,10 @@ + return OpEditor; + case MENU_QUERY: + return OpQuery; ++ case MENU_SIG: ++ return OpSig; ++ case MENU_SIG_DIR: ++ return OpSigDir; + + case MENU_PGP: + return (WithCrypto & APPLICATION_PGP)? OpPgp:NULL; +--- mutt-1.5.11/keymap.h.orig Thu Jun 17 22:33:04 2004 ++++ mutt-1.5.11/keymap.h Sat Mar 11 21:48:05 2006 +@@ -62,6 +62,8 @@ + MENU_PAGER, + MENU_POST, + MENU_QUERY, ++ MENU_SIG, ++ MENU_SIG_DIR, + + + MENU_PGP, +@@ -108,6 +110,8 @@ + extern struct binding_t OpEditor[]; + extern struct binding_t OpQuery[]; + extern struct binding_t OpAlias[]; ++extern struct binding_t OpSig[]; ++extern struct binding_t OpSigDir[]; + + extern struct binding_t OpPgp[]; + +--- mutt-1.5.11/protos.h.orig Wed Sep 7 10:19:43 2005 ++++ mutt-1.5.11/protos.h Sat Mar 11 21:48:05 2006 +@@ -242,6 +242,7 @@ + void mutt_shell_escape (void); + void mutt_show_error (void); + void mutt_signal_init (void); ++void mutt_signature (char *); + void mutt_stamp_attachment (BODY *a); + void mutt_tabs_to_spaces (char *); + void mutt_tag_set_flag (int, int); +--- mutt-1.5.11/signature.c.orig Sat Mar 11 21:58:38 2006 ++++ mutt-1.5.11/signature.c Sat Mar 11 22:07:31 2006 +@@ -0,0 +1,499 @@ ++/* ++ * Copyright (C) 2001 Cedric Duval ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. ++ */ ++ ++#if HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include "mutt.h" ++#include "mutt_menu.h" ++#include "mapping.h" ++#include "mutt_curses.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define SIG_DISPLAY_LINES 4 ++#define SEPARATOR(x) ((*x == '\n') || (mutt_strcmp (x, "-- \n") == 0)) ++#define SIG_ADD_LINE(x,y) mutt_add_list (x, strtok (y, "\n")) ++ ++typedef struct sig_list ++{ ++ struct sig_list *next; ++ LIST *sig; ++} SIG_LIST; ++ ++typedef struct sig_dir ++{ ++ struct sig_dir *next; ++ char *name; ++} SIG_DIR; ++ ++typedef LIST * ENTRY; ++ ++typedef struct entry_dir ++{ ++ int tagged; ++ SIG_DIR *data; ++} ENTRY_DIR; ++ ++static struct mapping_t SigHelp[] = { ++ { N_("Exit"), OP_EXIT }, ++ { N_("Search"), OP_SEARCH }, ++ { N_("Random"), OP_RANDOM_SIG }, ++ { N_("Help"), OP_HELP }, ++ { NULL } ++}; ++ ++static struct mapping_t SigDirHelp[] = { ++ { N_("Exit"), OP_EXIT }, ++ { N_("Search signature"), OP_SIG_SEARCH }, ++ { N_("Help"), OP_HELP }, ++ { NULL } ++}; ++ ++void menu_next_entry (MUTTMENU *menu); ++void menu_prev_entry (MUTTMENU *menu); ++ ++ ++static int sig_match (LIST *s, regex_t *re) ++{ ++ while (s) ++ { ++ if (regexec (re, s->data, (size_t)0, NULL, (int)0) == 0) ++ return 1; ++ s = s->next; ++ } ++ return 0; ++} ++ ++static void read_sig_file (char *name, SIG_LIST **begin, regex_t *re) ++{ ++ FILE *fp; ++ char buf[STRING]; ++ LIST *sig = NULL; ++ SIG_LIST *first, *cur; ++ int append = 0; ++ ++ if (!(fp = safe_fopen (name, "r"))) ++ { ++ mutt_error (_("Can't open signature file %s"), name); ++ return; ++ } ++ ++ for (first = *begin; first && first->next; first = first->next, append++) ++ ; /* append results to an existing list */ ++ cur = first; ++ ++ while (fgets (buf, sizeof (buf), fp)) ++ { ++ if (buf[0] && !SEPARATOR (buf)) ++ { ++ sig = SIG_ADD_LINE (NULL, buf); ++ ++ while (fgets (buf, sizeof (buf), fp) && buf[0] && !SEPARATOR (buf)) ++ SIG_ADD_LINE (sig, buf); ++ ++ if (re && !sig_match (sig, re)) ++ mutt_free_list (&sig); /* previous sig didn't match the regexp */ ++ else ++ { ++ /* add signature */ ++ if (first == NULL) ++ first = cur = (SIG_LIST *) safe_calloc (1, sizeof (SIG_LIST)); ++ else ++ { ++ cur->next = (SIG_LIST *) safe_calloc (1, sizeof (SIG_LIST)); ++ cur = cur->next; ++ } ++ ++ cur->sig = sig; ++ cur->next = NULL; ++ } ++ } ++ } ++ ++ if (!append) ++ *begin = first; ++ ++ safe_fclose (&fp); ++} ++ ++static void sig_make_entry (char *s, size_t slen, MUTTMENU *menu, int num) ++{ ++ ENTRY *table = (ENTRY *) menu->data; ++ ++ snprintf (s, slen, "%3d %s", ++ num + 1, ++ table[num]->data); ++} ++ ++static int sig_menu_search (MUTTMENU *menu, regex_t *re, int num) ++{ ++ return (sig_match (((ENTRY *)menu->data)[num], re) ? 0 : REG_NOMATCH); ++} ++ ++static void draw_sig_frame (LIST *s) ++{ ++ int i; ++ ++ for (i = 1; i <= SIG_DISPLAY_LINES; i++) ++ { ++ if (s) ++ { ++ mvaddstr (i, 0, s->data); ++ s = s->next; ++ } ++ else ++ move (i, 0); ++ ++ clrtoeol (); ++ } ++ ++ SETCOLOR (MT_COLOR_STATUS); ++ mvaddstr (SIG_DISPLAY_LINES + 1, 0, _("-- Signature")); ++ BKGDSET (MT_COLOR_STATUS); ++ clrtoeol (); ++ ++ BKGDSET (MT_COLOR_NORMAL); ++ SETCOLOR (MT_COLOR_NORMAL); ++} ++ ++static void free_sig_list (SIG_LIST **sigs) ++{ ++ SIG_LIST *cur; ++ ++ while (*sigs) ++ { ++ cur = *sigs; ++ *sigs = (*sigs)->next; ++ mutt_free_list (&cur->sig); ++ safe_free ((void **)&cur); ++ } ++} ++ ++static void append_signature (char *msg_file, LIST *s) ++{ ++ FILE *fp; ++ ++ if ((fp = safe_fopen (msg_file, "a")) == 0) ++ mutt_perror (msg_file); ++ else ++ { ++ if (option (OPTSIGDASHES)) ++ fputs ("\n-- \n", fp); ++ ++ for (; s; s = s->next) ++ fprintf (fp, "%s\n", s->data); ++ ++ mutt_message (_("Signature appended to your mail")); ++ safe_fclose (&fp); ++ } ++} ++ ++static LIST *sig_list_menu (char *file, SIG_LIST *list) ++{ ++ LIST *result = NULL; ++ SIG_LIST *sigl; ++ MUTTMENU *menu; ++ ENTRY *SigTable; ++ char helpstr[SHORT_STRING], title[SHORT_STRING]; ++ int i, done = 0; ++ ++ snprintf (title, sizeof (title), _("Signature : %s"), file); ++ ++ menu = mutt_new_menu (); ++ menu->make_entry = sig_make_entry; ++ menu->tag = NULL; ++ menu->search = sig_menu_search; ++ menu->menu = MENU_SIG; ++ menu->title = title; ++ menu->help = mutt_compile_help (helpstr, sizeof (helpstr), ++ MENU_SIG, SigHelp); ++ menu->offset = SIG_DISPLAY_LINES + 2; ++ menu->pagelen = LINES - SIG_DISPLAY_LINES - 4; ++ ++ for (sigl = list; sigl; sigl = sigl->next) ++ menu->max++; ++ ++ menu->data = SigTable = (ENTRY *) safe_calloc (menu->max, sizeof (ENTRY)); ++ ++ for (i = 0, sigl = list; sigl; i++, sigl = sigl->next) ++ SigTable[i] = sigl->sig; ++ ++ while (!done) ++ { ++ switch (mutt_menuLoop (menu)) ++ { ++ case OP_GENERIC_SELECT_ENTRY: ++ result = SigTable[menu->current]; ++ done = 1; ++ break; ++ ++ case OP_PREV_SIG: ++ menu_prev_entry (menu); ++ draw_sig_frame (SigTable[menu->current]); ++ break; ++ ++ case OP_NEXT_SIG: ++ menu_next_entry (menu); ++ draw_sig_frame (SigTable[menu->current]); ++ break; ++ ++ case OP_REDRAW: ++ menu->offset = SIG_DISPLAY_LINES + 2; ++ menu->pagelen = LINES - SIG_DISPLAY_LINES - 4; ++ draw_sig_frame (SigTable[menu->current]); ++ break; ++ ++ case OP_RANDOM_SIG: ++ menu->current = LRAND () % menu->max; ++ draw_sig_frame (SigTable[menu->current]); ++ menu->redraw |= REDRAW_MOTION; ++ break; ++ ++ case OP_EXIT: ++ set_option (OPTNEEDREDRAW); ++ done = 1; ++ break; ++ } ++ } ++ ++ mutt_menuDestroy (&menu); ++ safe_free ((void **)&SigTable); ++ return result; ++} ++ ++static SIG_LIST *sig_search_filter (MUTTMENU *menu, char *path) ++{ ++ regex_t re; ++ char buf[STRING]; ++ SIG_LIST *result = NULL; ++ int i; ++ ++ snprintf (buf, sizeof(buf), menu->searchBuf ? menu->searchBuf : ""); ++ if (mutt_get_field (_("Search for: "), buf, ++ sizeof (buf), M_CLEAR) != 0 || !buf[0]) ++ return (NULL); ++ mutt_str_replace (&menu->searchBuf, buf); ++ ++ if ((i = regcomp (&re, menu->searchBuf, REG_NOSUB | REG_EXTENDED | REG_WORDS ++ | mutt_which_case (menu->searchBuf))) != 0) ++ { ++ regerror (i, &re, buf, sizeof (buf)); ++ regfree (&re); ++ mutt_error ("%s", buf); ++ return (NULL); ++ } ++ ++ /* building list of sigs matching the regexp */ ++ for (i = 0; i < menu->max; i++) ++ { ++ /* search in every file if none is tagged */ ++ if (((ENTRY_DIR *) menu->data)[i].tagged || (menu->tagged == 0)) ++ { ++ snprintf (buf, sizeof (buf), "%s/%s", path, ++ ((ENTRY_DIR *) menu->data)[i].data->name); ++ read_sig_file (buf, &result, &re); ++ } ++ } ++ ++ regfree (&re); ++ if (!result) ++ mutt_error (_("Not found.")); ++ ++ return (result); ++} ++ ++/* returns the list of files in this directory */ ++static SIG_DIR *sig_directory (char *path) ++{ ++ DIR *dp; ++ struct dirent *de; ++ struct stat s; ++ SIG_DIR *first = NULL, *cur = NULL; ++ char file[_POSIX_PATH_MAX + SHORT_STRING]; ++ ++ if ((dp = opendir (path)) == NULL) ++ { ++ mutt_perror (path); ++ return (NULL); ++ } ++ ++ while ((de = readdir (dp))) ++ { ++ if ((de->d_name)[0] == '.') /* no hidden files */ ++ continue; ++ ++ snprintf (file, sizeof (file), "%s/%s", path, de->d_name); ++ if (lstat (file, &s) == -1) ++ continue; ++ ++ if ((!S_ISREG (s.st_mode)) && (!S_ISLNK (s.st_mode))) ++ continue; ++ ++ if (first == NULL) ++ cur = first = safe_calloc (1, sizeof (SIG_DIR)); ++ else ++ { ++ cur->next = safe_calloc (1, sizeof (SIG_DIR)); ++ cur = cur->next; ++ } ++ cur->name = safe_strdup (de->d_name); ++ cur->next = NULL; ++ } ++ closedir (dp); ++ return first; ++} ++ ++static void sig_dir_make_entry (char *s, size_t slen, MUTTMENU *menu, int num) ++{ ++ ENTRY_DIR *table = (ENTRY_DIR *) menu->data; ++ ++ snprintf (s, slen, "%c %3d - %s", ++ table[num].tagged ? '*' : ' ', ++ num + 1, ++ table[num].data->name); ++} ++ ++static int sig_dir_tag (MUTTMENU *menu, int n, int m) ++{ ++ ENTRY_DIR *cur = &((ENTRY_DIR *) menu->data)[n]; ++ int ot = cur->tagged; ++ ++ cur->tagged = m >= 0 ? m : !cur->tagged; ++ return cur->tagged - ot; ++ ++} ++ ++static int sig_dir_sort (const void *a, const void *b) ++{ ++ ENTRY_DIR *pa = (ENTRY_DIR *) a; ++ ENTRY_DIR *pb = (ENTRY_DIR *) b; ++ ++ return (mutt_strcmp (pa->data->name, pb->data->name)); ++} ++ ++static int sig_dir_menu (char *path, char *msg_file) ++{ ++ MUTTMENU *menu; ++ SIG_LIST *sigl; ++ LIST *result = NULL; ++ ENTRY_DIR *FileTable; ++ SIG_DIR *list, *files; ++ char buf[STRING], helpstr[SHORT_STRING], title[SHORT_STRING]; ++ int i, done = 0; ++ ++ if ((list = sig_directory (path)) == NULL) ++ return -1; ++ ++ snprintf (title, sizeof (title), "Signature directory : %s", path); ++ ++ menu = mutt_new_menu (); ++ menu->make_entry = sig_dir_make_entry; ++ menu->search = NULL; /* search within files with sig_search_filter() */ ++ menu->tag = sig_dir_tag; ++ menu->menu = MENU_SIG_DIR; ++ menu->title = title; ++ menu->help = mutt_compile_help (helpstr, sizeof (helpstr), ++ MENU_SIG_DIR, SigDirHelp); ++ ++ for (files = list; files; files = files->next) ++ menu->max++; ++ ++ menu->data = FileTable = (ENTRY_DIR *) safe_calloc (menu->max, ++ sizeof (ENTRY_DIR)); ++ ++ for (i = 0, files = list; files; i++, files = files->next) ++ FileTable[i].data = files; ++ ++ qsort (FileTable, menu->max, sizeof (ENTRY_DIR), sig_dir_sort); ++ ++ while (!done) ++ { ++ switch (mutt_menuLoop (menu)) ++ { ++ case OP_SIG_SEARCH: ++ sigl = sig_search_filter (menu, path); ++ ++ if (sigl) ++ { ++ if ((result = sig_list_menu (_("query results"), sigl)) != NULL) ++ { ++ append_signature (msg_file, result); ++ done = 1; ++ } ++ ++ MAYBE_REDRAW (menu->redraw); ++ free_sig_list (&sigl); ++ } ++ break; ++ ++ case OP_GENERIC_SELECT_ENTRY: ++ snprintf (buf, sizeof (buf), "%s/%s", path, ++ FileTable[menu->current].data->name); ++ sigl = NULL; ++ read_sig_file (buf, &sigl, NULL); ++ ++ if (sigl) ++ { ++ if ((result = sig_list_menu (buf, sigl)) != NULL) ++ { ++ append_signature (msg_file, result); ++ done = 1; ++ } ++ ++ MAYBE_REDRAW (menu->redraw); ++ free_sig_list (&sigl); ++ } ++ break; ++ ++ case OP_EXIT: ++ done = 1; ++ break; ++ } ++ } ++ ++ while (list) ++ { ++ safe_free ((void **)&list->name); ++ files = list; ++ list = list->next; ++ safe_free ((void **)&files); ++ } ++ safe_free ((void **)&FileTable); ++ mutt_menuDestroy (&menu); ++ return 0; ++} ++ ++void mutt_signature (char *msg_file) ++{ ++ if (!SigDirectory) ++ { ++ mutt_error (_("variable 'signatures_directory' is unset")); ++ return; ++ } ++ ++ if (sig_dir_menu (SigDirectory, msg_file) == -1) ++ mutt_error (_("%s: no files in this directory"), SigDirectory); ++ else ++ set_option (OPTNEEDREDRAW); ++} diff -ru /usr/ports/mail/mutt-devel/patch-1.5.11.cd.signatures_menu.2.1 ./patch-1.5.11.cd.signatures_menu.2.1 --- /usr/ports/mail/mutt-devel/patch-1.5.11.cd.signatures_menu.2.1 Thu Jan 1 01:00:00 1970 +++ ./patch-1.5.11.cd.signatures_menu.2.1 Thu Mar 16 08:16:43 2006 @@ -0,0 +1,726 @@ +--- mutt-1.5.11/Makefile.am.orig Thu Aug 11 23:27:28 2005 ++++ mutt-1.5.11/Makefile.am Sat Mar 11 21:47:55 2006 +@@ -25,7 +25,7 @@ + main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \ + postpone.c query.c recvattach.c recvcmd.c \ + rfc822.c rfc1524.c rfc2047.c rfc2231.c \ +- score.c send.c sendlib.c signal.c sort.c \ ++ score.c send.c sendlib.c signal.c signature.c sort.c \ + status.c system.c thread.c charset.c history.c lib.c \ + muttlib.c editmsg.c utf8.c mbyte.c wcwidth.c \ + url.c ascii.c mutt_idna.c crypt-mod.c crypt-mod.h +--- mutt-1.5.11/Makefile.in.orig Thu Sep 15 16:22:50 2005 ++++ mutt-1.5.11/Makefile.in Sat Mar 11 21:50:27 2006 +@@ -89,7 +89,7 @@ + recvattach.$(OBJEXT) recvcmd.$(OBJEXT) rfc822.$(OBJEXT) \ + rfc1524.$(OBJEXT) rfc2047.$(OBJEXT) rfc2231.$(OBJEXT) \ + score.$(OBJEXT) send.$(OBJEXT) sendlib.$(OBJEXT) \ +- signal.$(OBJEXT) sort.$(OBJEXT) status.$(OBJEXT) \ ++ signal.$(OBJEXT) signature.${OBJEXT} sort.$(OBJEXT) status.$(OBJEXT) \ + system.$(OBJEXT) thread.$(OBJEXT) charset.$(OBJEXT) \ + history.$(OBJEXT) lib.$(OBJEXT) muttlib.$(OBJEXT) \ + editmsg.$(OBJEXT) utf8.$(OBJEXT) mbyte.$(OBJEXT) \ +@@ -307,7 +307,7 @@ + main.c mbox.c menu.c mh.c mx.c pager.c parse.c pattern.c \ + postpone.c query.c recvattach.c recvcmd.c \ + rfc822.c rfc1524.c rfc2047.c rfc2231.c \ +- score.c send.c sendlib.c signal.c sort.c \ ++ score.c send.c sendlib.c signal.c signature.c sort.c \ + status.c system.c thread.c charset.c history.c lib.c \ + muttlib.c editmsg.c utf8.c mbyte.c wcwidth.c \ + url.c ascii.c mutt_idna.c crypt-mod.c crypt-mod.h +--- mutt-1.5.11/OPS.orig Sun Jul 24 18:56:42 2005 ++++ mutt-1.5.11/OPS Sat Mar 11 21:47:55 2006 +@@ -38,6 +38,7 @@ + OP_COMPOSE_POSTPONE_MESSAGE "save this message to send later" + OP_COMPOSE_RENAME_FILE "rename/move an attached file" + OP_COMPOSE_SEND_MESSAGE "send the message" ++OP_COMPOSE_SIG "choose a signature" + OP_COMPOSE_TOGGLE_DISPOSITION "toggle disposition between inline/attachment" + OP_COMPOSE_TOGGLE_UNLINK "toggle whether to delete file after sending it" + OP_COMPOSE_UPDATE_ENCODING "update an attachment's encoding info" +@@ -131,6 +132,7 @@ + OP_NEXT_ENTRY "move to the next entry" + OP_NEXT_LINE "scroll down one line" + OP_NEXT_PAGE "move to the next page" ++OP_NEXT_SIG "move to the next signature" + OP_PAGER_BOTTOM "jump to the bottom of the message" + OP_PAGER_HIDE_QUOTED "toggle display of quoted text" + OP_PAGER_SKIP_QUOTED "skip beyond quoted text" +@@ -139,10 +141,12 @@ + OP_PREV_ENTRY "move to the previous entry" + OP_PREV_LINE "scroll up one line" + OP_PREV_PAGE "move to the previous page" ++OP_PREV_SIG "move to the previous signature" + OP_PRINT "print the current entry" + OP_QUERY "query external program for addresses" + OP_QUERY_APPEND "append new query results to current results" + OP_QUIT "save changes to mailbox and quit" ++OP_RANDOM_SIG "pick a signature at random" + OP_RECALL_MESSAGE "recall a postponed message" + OP_REDRAW "clear and redraw the screen" + OP_REFORMAT_WINCH "{internal}" +@@ -156,6 +160,7 @@ + OP_SEARCH_OPPOSITE "search for next match in opposite direction" + OP_SEARCH_TOGGLE "toggle search pattern coloring" + OP_SHELL_ESCAPE "invoke a command in a subshell" ++OP_SIG_SEARCH "search signatures matching a pattern" + OP_SORT "sort messages" + OP_SORT_REVERSE "sort messages in reverse order" + OP_TAG "tag the current entry" +Binary files mutt-1.5.11/PATCHES.orig and mutt-1.5.11/PATCHES differ +--- mutt-1.5.11/compose.c.orig Thu Aug 11 21:37:23 2005 ++++ mutt-1.5.11/compose.c Sat Mar 11 21:47:55 2006 +@@ -1128,6 +1128,12 @@ + /* no send2hook, since this doesn't modify the message */ + break; + ++ case OP_COMPOSE_SIG: ++ mutt_signature(msg->content->filename); ++ MAYBE_REDRAW (menu->redraw); ++ mutt_update_encoding (msg->content); ++ break; ++ + case OP_PIPE: + case OP_FILTER: + CHECK_COUNT; +--- mutt-1.5.11/doc/manual.xml.head.orig Tue Sep 6 18:46:44 2005 ++++ mutt-1.5.11/doc/manual.xml.head Sat Mar 11 21:48:05 2006 +@@ -908,6 +908,7 @@ + c edit-cc edit the Cc field + b edit-bcc edit the Bcc field + y send-message send the message ++ESC s signature-menu select a signature and append it to your mail + s edit-subject edit the Subject + S smime-menu select S/MIME options + f edit-fcc specify an ``Fcc'' mailbox +--- mutt-1.5.11/functions.h.orig Sun Jul 24 18:56:42 2005 ++++ mutt-1.5.11/functions.h Sat Mar 11 21:48:05 2006 +@@ -311,6 +311,7 @@ + { "view-attach", OP_VIEW_ATTACH, M_ENTER_S }, + { "send-message", OP_COMPOSE_SEND_MESSAGE, "y" }, + { "pipe-entry", OP_PIPE, "|" }, ++ { "signature-menu", OP_COMPOSE_SIG, "\033s" }, + + { "attach-key", OP_COMPOSE_ATTACH_KEY, "\033k" }, + { "pgp-menu", OP_COMPOSE_PGP_MENU, "p" }, +@@ -368,6 +369,19 @@ + { "mail", OP_MAIL, "m" }, + { "query", OP_QUERY, "Q" }, + { "query-append", OP_QUERY_APPEND, "A" }, ++ { NULL, 0, NULL } ++}; ++ ++/* Signature Menu */ ++struct binding_t OpSig[] = { ++ { "next-sig", OP_NEXT_SIG, "j" }, ++ { "previous-sig", OP_PREV_SIG, "k" }, ++ { "random-sig", OP_RANDOM_SIG, "r" }, ++ { NULL, 0, NULL } ++}; ++ ++struct binding_t OpSigDir[] = { ++ { "search-sig", OP_SIG_SEARCH, "/" }, + { NULL, 0, NULL } + }; + +--- mutt-1.5.11/globals.h.orig Thu Sep 15 16:19:54 2005 ++++ mutt-1.5.11/globals.h Sat Mar 11 21:48:05 2006 +@@ -109,6 +109,7 @@ + WHERE char *Sendmail; + WHERE char *Shell; + WHERE char *Signature; ++WHERE char *SigDirectory; + WHERE char *SimpleSearch; + WHERE char *Spoolfile; + WHERE char *SpamSep; +--- mutt-1.5.11/init.h.orig Thu Sep 15 16:19:54 2005 ++++ mutt-1.5.11/init.h Sat Mar 11 21:48:05 2006 +@@ -2457,6 +2457,14 @@ + ** assumed that filename is a shell command and input should be read from + ** its stdout. + */ ++ { "signatures_directory", DT_PATH, R_NONE, UL &SigDirectory, UL "" }, ++ /* ++ ** .pp ++ ** Specifies the path where your signatures are located. In the files of ++ ** this directory, the signatures are separated by blank lines and/or ++ ** sig_dashes (``-- ''). ++ ** You can choose between these signatures from the compose menu. ++ */ + { "simple_search", DT_STR, R_NONE, UL &SimpleSearch, UL "~f %s | ~s %s" }, + /* + ** .pp +--- mutt-1.5.11/keymap.c.orig Wed Sep 7 10:19:43 2005 ++++ mutt-1.5.11/keymap.c Sat Mar 11 21:48:05 2006 +@@ -55,6 +55,8 @@ + + + { "query", MENU_QUERY }, ++ { "signature", MENU_SIG }, ++ { "sig_directory", MENU_SIG_DIR }, + { "generic", MENU_GENERIC }, + { NULL, 0 } + }; +@@ -560,6 +562,8 @@ + create_bindings (OpPost, MENU_POST); + create_bindings (OpQuery, MENU_QUERY); + create_bindings (OpAlias, MENU_ALIAS); ++ create_bindings (OpSig, MENU_SIG); ++ create_bindings (OpSigDir, MENU_SIG_DIR); + + + if ((WithCrypto & APPLICATION_PGP)) +@@ -658,6 +662,9 @@ + km_bindkey ("", MENU_ATTACH, OP_VIEW_ATTACH); + km_bindkey ("", MENU_COMPOSE, OP_VIEW_ATTACH); + ++ km_bindkey ("", MENU_SIG, OP_PREV_SIG); ++ km_bindkey ("", MENU_SIG, OP_NEXT_SIG); ++ + /* edit-to (default "t") hides generic tag-entry in Compose menu + This will bind tag-entry to "T" in the Compose menu */ + km_bindkey ("T", MENU_COMPOSE, OP_TAG); +@@ -793,6 +800,10 @@ + return OpEditor; + case MENU_QUERY: + return OpQuery; ++ case MENU_SIG: ++ return OpSig; ++ case MENU_SIG_DIR: ++ return OpSigDir; + + case MENU_PGP: + return (WithCrypto & APPLICATION_PGP)? OpPgp:NULL; +--- mutt-1.5.11/keymap.h.orig Thu Jun 17 22:33:04 2004 ++++ mutt-1.5.11/keymap.h Sat Mar 11 21:48:05 2006 +@@ -62,6 +62,8 @@ + MENU_PAGER, + MENU_POST, + MENU_QUERY, ++ MENU_SIG, ++ MENU_SIG_DIR, + + + MENU_PGP, +@@ -108,6 +110,8 @@ + extern struct binding_t OpEditor[]; + extern struct binding_t OpQuery[]; + extern struct binding_t OpAlias[]; ++extern struct binding_t OpSig[]; ++extern struct binding_t OpSigDir[]; + + extern struct binding_t OpPgp[]; + +--- mutt-1.5.11/protos.h.orig Wed Sep 7 10:19:43 2005 ++++ mutt-1.5.11/protos.h Sat Mar 11 21:48:05 2006 +@@ -242,6 +242,7 @@ + void mutt_shell_escape (void); + void mutt_show_error (void); + void mutt_signal_init (void); ++void mutt_signature (char *); + void mutt_stamp_attachment (BODY *a); + void mutt_tabs_to_spaces (char *); + void mutt_tag_set_flag (int, int); +--- mutt-1.5.11/signature.c.orig Sat Mar 11 21:58:38 2006 ++++ mutt-1.5.11/signature.c Sat Mar 11 22:07:31 2006 +@@ -0,0 +1,499 @@ ++/* ++ * Copyright (C) 2001 Cedric Duval ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. ++ */ ++ ++#if HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include "mutt.h" ++#include "mutt_menu.h" ++#include "mapping.h" ++#include "mutt_curses.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define SIG_DISPLAY_LINES 4 ++#define SEPARATOR(x) ((*x == '\n') || (mutt_strcmp (x, "-- \n") == 0)) ++#define SIG_ADD_LINE(x,y) mutt_add_list (x, strtok (y, "\n")) ++ ++typedef struct sig_list ++{ ++ struct sig_list *next; ++ LIST *sig; ++} SIG_LIST; ++ ++typedef struct sig_dir ++{ ++ struct sig_dir *next; ++ char *name; ++} SIG_DIR; ++ ++typedef LIST * ENTRY; ++ ++typedef struct entry_dir ++{ ++ int tagged; ++ SIG_DIR *data; ++} ENTRY_DIR; ++ ++static struct mapping_t SigHelp[] = { ++ { N_("Exit"), OP_EXIT }, ++ { N_("Search"), OP_SEARCH }, ++ { N_("Random"), OP_RANDOM_SIG }, ++ { N_("Help"), OP_HELP }, ++ { NULL } ++}; ++ ++static struct mapping_t SigDirHelp[] = { ++ { N_("Exit"), OP_EXIT }, ++ { N_("Search signature"), OP_SIG_SEARCH }, ++ { N_("Help"), OP_HELP }, ++ { NULL } ++}; ++ ++void menu_next_entry (MUTTMENU *menu); ++void menu_prev_entry (MUTTMENU *menu); ++ ++ ++static int sig_match (LIST *s, regex_t *re) ++{ ++ while (s) ++ { ++ if (regexec (re, s->data, (size_t)0, NULL, (int)0) == 0) ++ return 1; ++ s = s->next; ++ } ++ return 0; ++} ++ ++static void read_sig_file (char *name, SIG_LIST **begin, regex_t *re) ++{ ++ FILE *fp; ++ char buf[STRING]; ++ LIST *sig = NULL; ++ SIG_LIST *first, *cur; ++ int append = 0; ++ ++ if (!(fp = safe_fopen (name, "r"))) ++ { ++ mutt_error (_("Can't open signature file %s"), name); ++ return; ++ } ++ ++ for (first = *begin; first && first->next; first = first->next, append++) ++ ; /* append results to an existing list */ ++ cur = first; ++ ++ while (fgets (buf, sizeof (buf), fp)) ++ { ++ if (buf[0] && !SEPARATOR (buf)) ++ { ++ sig = SIG_ADD_LINE (NULL, buf); ++ ++ while (fgets (buf, sizeof (buf), fp) && buf[0] && !SEPARATOR (buf)) ++ SIG_ADD_LINE (sig, buf); ++ ++ if (re && !sig_match (sig, re)) ++ mutt_free_list (&sig); /* previous sig didn't match the regexp */ ++ else ++ { ++ /* add signature */ ++ if (first == NULL) ++ first = cur = (SIG_LIST *) safe_calloc (1, sizeof (SIG_LIST)); ++ else ++ { ++ cur->next = (SIG_LIST *) safe_calloc (1, sizeof (SIG_LIST)); ++ cur = cur->next; ++ } ++ ++ cur->sig = sig; ++ cur->next = NULL; ++ } ++ } ++ } ++ ++ if (!append) ++ *begin = first; ++ ++ safe_fclose (&fp); ++} ++ ++static void sig_make_entry (char *s, size_t slen, MUTTMENU *menu, int num) ++{ ++ ENTRY *table = (ENTRY *) menu->data; ++ ++ snprintf (s, slen, "%3d %s", ++ num + 1, ++ table[num]->data); ++} ++ ++static int sig_menu_search (MUTTMENU *menu, regex_t *re, int num) ++{ ++ return (sig_match (((ENTRY *)menu->data)[num], re) ? 0 : REG_NOMATCH); ++} ++ ++static void draw_sig_frame (LIST *s) ++{ ++ int i; ++ ++ for (i = 1; i <= SIG_DISPLAY_LINES; i++) ++ { ++ if (s) ++ { ++ mvaddstr (i, 0, s->data); ++ s = s->next; ++ } ++ else ++ move (i, 0); ++ ++ clrtoeol (); ++ } ++ ++ SETCOLOR (MT_COLOR_STATUS); ++ mvaddstr (SIG_DISPLAY_LINES + 1, 0, _("-- Signature")); ++ BKGDSET (MT_COLOR_STATUS); ++ clrtoeol (); ++ ++ BKGDSET (MT_COLOR_NORMAL); ++ SETCOLOR (MT_COLOR_NORMAL); ++} ++ ++static void free_sig_list (SIG_LIST **sigs) ++{ ++ SIG_LIST *cur; ++ ++ while (*sigs) ++ { ++ cur = *sigs; ++ *sigs = (*sigs)->next; ++ mutt_free_list (&cur->sig); ++ safe_free ((void **)&cur); ++ } ++} ++ ++static void append_signature (char *msg_file, LIST *s) ++{ ++ FILE *fp; ++ ++ if ((fp = safe_fopen (msg_file, "a")) == 0) ++ mutt_perror (msg_file); ++ else ++ { ++ if (option (OPTSIGDASHES)) ++ fputs ("\n-- \n", fp); ++ ++ for (; s; s = s->next) ++ fprintf (fp, "%s\n", s->data); ++ ++ mutt_message (_("Signature appended to your mail")); ++ safe_fclose (&fp); ++ } ++} ++ ++static LIST *sig_list_menu (char *file, SIG_LIST *list) ++{ ++ LIST *result = NULL; ++ SIG_LIST *sigl; ++ MUTTMENU *menu; ++ ENTRY *SigTable; ++ char helpstr[SHORT_STRING], title[SHORT_STRING]; ++ int i, done = 0; ++ ++ snprintf (title, sizeof (title), _("Signature : %s"), file); ++ ++ menu = mutt_new_menu (); ++ menu->make_entry = sig_make_entry; ++ menu->tag = NULL; ++ menu->search = sig_menu_search; ++ menu->menu = MENU_SIG; ++ menu->title = title; ++ menu->help = mutt_compile_help (helpstr, sizeof (helpstr), ++ MENU_SIG, SigHelp); ++ menu->offset = SIG_DISPLAY_LINES + 2; ++ menu->pagelen = LINES - SIG_DISPLAY_LINES - 4; ++ ++ for (sigl = list; sigl; sigl = sigl->next) ++ menu->max++; ++ ++ menu->data = SigTable = (ENTRY *) safe_calloc (menu->max, sizeof (ENTRY)); ++ ++ for (i = 0, sigl = list; sigl; i++, sigl = sigl->next) ++ SigTable[i] = sigl->sig; ++ ++ while (!done) ++ { ++ switch (mutt_menuLoop (menu)) ++ { ++ case OP_GENERIC_SELECT_ENTRY: ++ result = SigTable[menu->current]; ++ done = 1; ++ break; ++ ++ case OP_PREV_SIG: ++ menu_prev_entry (menu); ++ draw_sig_frame (SigTable[menu->current]); ++ break; ++ ++ case OP_NEXT_SIG: ++ menu_next_entry (menu); ++ draw_sig_frame (SigTable[menu->current]); ++ break; ++ ++ case OP_REDRAW: ++ menu->offset = SIG_DISPLAY_LINES + 2; ++ menu->pagelen = LINES - SIG_DISPLAY_LINES - 4; ++ draw_sig_frame (SigTable[menu->current]); ++ break; ++ ++ case OP_RANDOM_SIG: ++ menu->current = LRAND () % menu->max; ++ draw_sig_frame (SigTable[menu->current]); ++ menu->redraw |= REDRAW_MOTION; ++ break; ++ ++ case OP_EXIT: ++ set_option (OPTNEEDREDRAW); ++ done = 1; ++ break; ++ } ++ } ++ ++ mutt_menuDestroy (&menu); ++ safe_free ((void **)&SigTable); ++ return result; ++} ++ ++static SIG_LIST *sig_search_filter (MUTTMENU *menu, char *path) ++{ ++ regex_t re; ++ char buf[STRING]; ++ SIG_LIST *result = NULL; ++ int i; ++ ++ snprintf (buf, sizeof(buf), menu->searchBuf ? menu->searchBuf : ""); ++ if (mutt_get_field (_("Search for: "), buf, ++ sizeof (buf), M_CLEAR) != 0 || !buf[0]) ++ return (NULL); ++ mutt_str_replace (&menu->searchBuf, buf); ++ ++ if ((i = regcomp (&re, menu->searchBuf, REG_NOSUB | REG_EXTENDED | REG_WORDS ++ | mutt_which_case (menu->searchBuf))) != 0) ++ { ++ regerror (i, &re, buf, sizeof (buf)); ++ regfree (&re); ++ mutt_error ("%s", buf); ++ return (NULL); ++ } ++ ++ /* building list of sigs matching the regexp */ ++ for (i = 0; i < menu->max; i++) ++ { ++ /* search in every file if none is tagged */ ++ if (((ENTRY_DIR *) menu->data)[i].tagged || (menu->tagged == 0)) ++ { ++ snprintf (buf, sizeof (buf), "%s/%s", path, ++ ((ENTRY_DIR *) menu->data)[i].data->name); ++ read_sig_file (buf, &result, &re); ++ } ++ } ++ ++ regfree (&re); ++ if (!result) ++ mutt_error (_("Not found.")); ++ ++ return (result); ++} ++ ++/* returns the list of files in this directory */ ++static SIG_DIR *sig_directory (char *path) ++{ ++ DIR *dp; ++ struct dirent *de; ++ struct stat s; ++ SIG_DIR *first = NULL, *cur = NULL; ++ char file[_POSIX_PATH_MAX + SHORT_STRING]; ++ ++ if ((dp = opendir (path)) == NULL) ++ { ++ mutt_perror (path); ++ return (NULL); ++ } ++ ++ while ((de = readdir (dp))) ++ { ++ if ((de->d_name)[0] == '.') /* no hidden files */ ++ continue; ++ ++ snprintf (file, sizeof (file), "%s/%s", path, de->d_name); ++ if (lstat (file, &s) == -1) ++ continue; ++ ++ if ((!S_ISREG (s.st_mode)) && (!S_ISLNK (s.st_mode))) ++ continue; ++ ++ if (first == NULL) ++ cur = first = safe_calloc (1, sizeof (SIG_DIR)); ++ else ++ { ++ cur->next = safe_calloc (1, sizeof (SIG_DIR)); ++ cur = cur->next; ++ } ++ cur->name = safe_strdup (de->d_name); ++ cur->next = NULL; ++ } ++ closedir (dp); ++ return first; ++} ++ ++static void sig_dir_make_entry (char *s, size_t slen, MUTTMENU *menu, int num) ++{ ++ ENTRY_DIR *table = (ENTRY_DIR *) menu->data; ++ ++ snprintf (s, slen, "%c %3d - %s", ++ table[num].tagged ? '*' : ' ', ++ num + 1, ++ table[num].data->name); ++} ++ ++static int sig_dir_tag (MUTTMENU *menu, int n, int m) ++{ ++ ENTRY_DIR *cur = &((ENTRY_DIR *) menu->data)[n]; ++ int ot = cur->tagged; ++ ++ cur->tagged = m >= 0 ? m : !cur->tagged; ++ return cur->tagged - ot; ++ ++} ++ ++static int sig_dir_sort (const void *a, const void *b) ++{ ++ ENTRY_DIR *pa = (ENTRY_DIR *) a; ++ ENTRY_DIR *pb = (ENTRY_DIR *) b; ++ ++ return (mutt_strcmp (pa->data->name, pb->data->name)); ++} ++ ++static int sig_dir_menu (char *path, char *msg_file) ++{ ++ MUTTMENU *menu; ++ SIG_LIST *sigl; ++ LIST *result = NULL; ++ ENTRY_DIR *FileTable; ++ SIG_DIR *list, *files; ++ char buf[STRING], helpstr[SHORT_STRING], title[SHORT_STRING]; ++ int i, done = 0; ++ ++ if ((list = sig_directory (path)) == NULL) ++ return -1; ++ ++ snprintf (title, sizeof (title), "Signature directory : %s", path); ++ ++ menu = mutt_new_menu (); ++ menu->make_entry = sig_dir_make_entry; ++ menu->search = NULL; /* search within files with sig_search_filter() */ ++ menu->tag = sig_dir_tag; ++ menu->menu = MENU_SIG_DIR; ++ menu->title = title; ++ menu->help = mutt_compile_help (helpstr, sizeof (helpstr), ++ MENU_SIG_DIR, SigDirHelp); ++ ++ for (files = list; files; files = files->next) ++ menu->max++; ++ ++ menu->data = FileTable = (ENTRY_DIR *) safe_calloc (menu->max, ++ sizeof (ENTRY_DIR)); ++ ++ for (i = 0, files = list; files; i++, files = files->next) ++ FileTable[i].data = files; ++ ++ qsort (FileTable, menu->max, sizeof (ENTRY_DIR), sig_dir_sort); ++ ++ while (!done) ++ { ++ switch (mutt_menuLoop (menu)) ++ { ++ case OP_SIG_SEARCH: ++ sigl = sig_search_filter (menu, path); ++ ++ if (sigl) ++ { ++ if ((result = sig_list_menu (_("query results"), sigl)) != NULL) ++ { ++ append_signature (msg_file, result); ++ done = 1; ++ } ++ ++ MAYBE_REDRAW (menu->redraw); ++ free_sig_list (&sigl); ++ } ++ break; ++ ++ case OP_GENERIC_SELECT_ENTRY: ++ snprintf (buf, sizeof (buf), "%s/%s", path, ++ FileTable[menu->current].data->name); ++ sigl = NULL; ++ read_sig_file (buf, &sigl, NULL); ++ ++ if (sigl) ++ { ++ if ((result = sig_list_menu (buf, sigl)) != NULL) ++ { ++ append_signature (msg_file, result); ++ done = 1; ++ } ++ ++ MAYBE_REDRAW (menu->redraw); ++ free_sig_list (&sigl); ++ } ++ break; ++ ++ case OP_EXIT: ++ done = 1; ++ break; ++ } ++ } ++ ++ while (list) ++ { ++ safe_free ((void **)&list->name); ++ files = list; ++ list = list->next; ++ safe_free ((void **)&files); ++ } ++ safe_free ((void **)&FileTable); ++ mutt_menuDestroy (&menu); ++ return 0; ++} ++ ++void mutt_signature (char *msg_file) ++{ ++ if (!SigDirectory) ++ { ++ mutt_error (_("variable 'signatures_directory' is unset")); ++ return; ++ } ++ ++ if (sig_dir_menu (SigDirectory, msg_file) == -1) ++ mutt_error (_("%s: no files in this directory"), SigDirectory); ++ else ++ set_option (OPTNEEDREDRAW); ++} >Release-Note: >Audit-Trail: >Unformatted: