2 * Copyright (C) 1996-2002 Michael R. Elkins <me@mutt.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
27 # include <unistd.h> /* needed for SEEK_SET */
30 # include <unix.h> /* needed for snprintf on QNX. */
32 #include <sys/types.h>
41 #if defined(HAVE_WCTYPE_H) && defined(HAVE_WC_FUNCS)
45 #ifndef _POSIX_PATH_MAX
46 #include <posix1_lim.h>
60 # define MB_LEN_MAX 16
64 # define MUTT_VERSION (VERSION SUBVERSION)
66 # define MUTT_VERSION (VERSION)
69 /* nifty trick I stole from ELM 2.5alpha. */
72 #define INITVAL(x) = x
78 #include "mutt_regex.h"
80 /* flags for mutt_copy_header() */
81 #define CH_UPDATE 1 /* update the status and x-status fields? */
82 #define CH_WEED (1<<1) /* weed the headers? */
83 #define CH_DECODE (1<<2) /* do RFC1522 decoding? */
84 #define CH_XMIT (1<<3) /* transmitting this message? */
85 #define CH_FROM (1<<4) /* retain the "From " message separator? */
86 #define CH_PREFIX (1<<5) /* use Prefix string? */
87 #define CH_NOSTATUS (1<<6) /* supress the status and x-status fields */
88 #define CH_REORDER (1<<7) /* Re-order output of headers */
89 #define CH_NONEWLINE (1<<8) /* don't output terminating newline */
90 #define CH_MIME (1<<9) /* ignore MIME fields */
91 #define CH_UPDATE_LEN (1<<10) /* update Lines: and Content-Length: */
92 #define CH_TXTPLAIN (1<<11) /* generate text/plain MIME headers */
93 #define CH_NOLEN (1<<12) /* don't write Content-Length: and Lines: */
94 #define CH_WEED_DELIVERED (1<<13) /* weed eventual Delivered-To headers */
95 #define CH_FORCE_FROM (1<<14) /* give CH_FROM precedence over CH_WEED? */
96 #define CH_NOQFROM (1<<15) /* give CH_FROM precedence over CH_WEED? */
97 #define CH_UPDATE_IRT (1<<16) /* update In-Reply-To: */
98 #define CH_UPDATE_REFS (1<<17) /* update References: */
100 /* flags for mutt_enter_string() */
101 #define M_ALIAS 1 /* do alias "completion" by calling up the alias-menu */
102 #define M_FILE (1<<1) /* do file completion */
103 #define M_EFILE (1<<2) /* do file completion, plus incoming folders */
104 #define M_CMD (1<<3) /* do completion on previous word */
105 #define M_PASS (1<<4) /* password mode (no echo) */
106 #define M_CLEAR (1<<5) /* clear input if printable character is pressed */
107 #define M_COMMAND (1<<6) /* do command completion */
108 #define M_PATTERN (1<<7) /* pattern mode - only used for history classes */
110 /* flags for mutt_get_token() */
111 #define M_TOKEN_EQUAL 1 /* treat '=' as a special */
112 #define M_TOKEN_CONDENSE (1<<1) /* ^(char) to control chars (macros) */
113 #define M_TOKEN_SPACE (1<<2) /* don't treat whitespace as a term */
114 #define M_TOKEN_QUOTE (1<<3) /* don't interpret quotes */
115 #define M_TOKEN_PATTERN (1<<4) /* !)|~ are terms (for patterns) */
116 #define M_TOKEN_COMMENT (1<<5) /* don't reap comments */
117 #define M_TOKEN_SEMICOLON (1<<6) /* don't treat ; as special */
119 /* flags for km_dokey() */
120 #define M_KM_UNBUFFERED 1 /* don't read from the key buffer */
124 char *data; /* pointer to data */
125 char *dptr; /* current read/write position */
126 size_t dsize; /* length of data */
127 int destroy; /* destroy `data' when done? */
132 int ch; /* raw key pressed */
133 int op; /* function op */
136 /* flags for _mutt_system() */
137 #define M_DETACH_PROCESS 1 /* detach subprocess from group */
139 /* flags for mutt_FormatString() */
142 M_FORMAT_FORCESUBJ = (1<<0), /* print the subject even if unchanged */
143 M_FORMAT_TREE = (1<<1), /* draw the thread tree */
144 M_FORMAT_MAKEPRINT = (1<<2), /* make sure that all chars are printable */
145 M_FORMAT_OPTIONAL = (1<<3),
146 M_FORMAT_STAT_FILE = (1<<4), /* used by mutt_attach_fmt */
147 M_FORMAT_ARROWCURSOR = (1<<5), /* reserve space for arrow_cursor */
148 M_FORMAT_INDEX = (1<<6) /* this is a main index entry */
151 /* types for mutt_add_hook() */
152 #define M_FOLDERHOOK 1
153 #define M_MBOXHOOK (1<<1)
154 #define M_SENDHOOK (1<<2)
155 #define M_FCCHOOK (1<<3)
156 #define M_SAVEHOOK (1<<4)
157 #define M_CHARSETHOOK (1<<5)
158 #define M_ICONVHOOK (1<<6)
159 #define M_MESSAGEHOOK (1<<7)
160 #define M_CRYPTHOOK (1<<8)
161 #define M_ACCOUNTHOOK (1<<9)
162 #define M_REPLYHOOK (1<<10)
163 #ifdef USE_COMPRESSED
164 #define M_OPENHOOK (1<<12)
165 #define M_APPENDHOOK (1<<13)
166 #define M_CLOSEHOOK (1<<14)
169 /* tree characters for linearize_tree and print_enriched_string */
170 #define M_TREE_LLCORNER 1
171 #define M_TREE_ULCORNER 2
172 #define M_TREE_LTEE 3
173 #define M_TREE_HLINE 4
174 #define M_TREE_VLINE 5
175 #define M_TREE_SPACE 6
176 #define M_TREE_RARROW 7
177 #define M_TREE_STAR 8
178 #define M_TREE_HIDDEN 9
179 #define M_TREE_EQUALS 10
180 #define M_TREE_TTEE 11
181 #define M_TREE_BTEE 12
182 #define M_TREE_MISSING 13
183 #define M_TREE_MAX 14
185 #define M_THREAD_COLLAPSE (1<<0)
186 #define M_THREAD_UNCOLLAPSE (1<<1)
187 #define M_THREAD_GET_HIDDEN (1<<2)
188 #define M_THREAD_UNREAD (1<<3)
189 #define M_THREAD_NEXT_UNREAD (1<<4)
193 /* modes for mutt_view_attachment() */
198 /* action codes used by mutt_set_flag() and mutt_pattern_function() */
218 /* actions for mutt_pattern_comp/mutt_pattern_exec */
252 /* Options for Mailcap lookup */
258 /* options for socket code */
264 /* Options for mutt_save_attachment */
269 /* possible arguments to set_quadoption() */
278 /* quad-option vars */
294 OPT_PGPTRADITIONAL, /* create old-style PGP messages */
304 #if defined(USE_SSL) || defined(USE_GNUTLS)
308 OPT_VERIFYSIG, /* verify PGP signatures */
314 OPT_FOLLOWUPTOPOSTER,
315 #endif /* USE_NNTP */
317 /* THIS MUST BE THE LAST VALUE. */
321 /* flags to ci_send_message() */
322 #define SENDREPLY (1<<0)
323 #define SENDGROUPREPLY (1<<1)
324 #define SENDLISTREPLY (1<<2)
325 #define SENDFORWARD (1<<3)
326 #define SENDPOSTPONED (1<<4)
327 #define SENDBATCH (1<<5)
328 #define SENDMAILX (1<<6)
329 #define SENDKEY (1<<7)
330 #define SENDRESEND (1<<8)
331 #define SENDNEWS (1<<9)
333 /* flags to _mutt_select_file() */
334 #define M_SEL_BUFFY (1<<0)
335 #define M_SEL_MULTI (1<<1)
336 #define M_SEL_FOLDER (1<<2)
384 OPTIGNORELISTREPLYTO,
390 # if defined(USE_SSL) || defined(USE_GNUTLS)
394 #if defined(USE_SSL) || defined(USE_NSS) || defined(USE_GNUTLS)
411 OPTMENUSCROLL, /* scroll menu instead of implicit next-page */
412 OPTMETAKEY, /* interpret ALT-x as ESC-x */
417 OPTMIMESUBJECT, /* encode subject line with RFC2047 */
458 #ifdef HAVE_GETADDRINFO
465 OPTWRITEBCC, /* write out a bcc header? */
475 OPTCRYPTREPLYENCRYPT,
477 OPTCRYPTREPLYSIGNENCRYPTED,
481 OPTSDEFAULTDECRYPTKEY,
502 #endif /* USE_NNTP */
506 OPTAUXSORT, /* (pseudo) using auxillary sort function */
507 OPTFORCEREFRESH, /* (pseudo) refresh even during macros */
508 OPTLOCALES, /* (pseudo) set if user has valid locale definition */
509 OPTNOCURSES, /* (pseudo) when sending in batch mode */
510 OPTNEEDREDRAW, /* (pseudo) to notify caller of a submenu */
511 OPTSEARCHREVERSE, /* (pseudo) used by ci_search_command */
512 OPTMSGERR, /* (pseudo) used by mutt_error/mutt_message */
513 OPTSEARCHINVALID, /* (pseudo) used to invalidate the search pat */
514 OPTSIGNALSBLOCKED, /* (pseudo) using by mutt_block_signals () */
515 OPTSYSSIGNALSBLOCKED, /* (pseudo) using by mutt_block_signals_system () */
516 OPTNEEDRESORT, /* (pseudo) used to force a re-sort */
517 OPTRESORTINIT, /* (pseudo) used to force the next resort to be from scratch */
518 OPTVIEWATTACH, /* (pseudo) signals that we are viewing attachments */
519 OPTFORCEREDRAWINDEX, /* (pseudo) used to force a redraw in the main index */
520 OPTFORCEREDRAWPAGER, /* (pseudo) used to force a redraw in the pager */
521 OPTSORTSUBTHREADS, /* (pseudo) used when $sort_aux changes */
522 OPTNEEDRESCORE, /* (pseudo) set when the `score' command is used */
523 OPTATTACHMSG, /* (pseudo) used by attach-message */
524 OPTHIDEREAD, /* (pseudo) whether or not hide read messages */
525 OPTKEEPQUIET, /* (pseudo) shut up the message and refresh
526 * functions while we are executing an
529 OPTMENUCALLER, /* (pseudo) tell menu to give caller a take */
530 OPTREDRAWTREE, /* (pseudo) redraw the thread tree */
531 OPTPGPCHECKTRUST, /* (pseudo) used by pgp_select_key () */
532 OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
533 OPTUNBUFFEREDINPUT, /* (pseudo) don't use key buffer */
536 OPTNEWS, /* (pseudo) used to change reader mode */
537 OPTNEWSSEND, /* (pseudo) used to change behavior when posting */
538 OPTNEWSCACHE, /* (pseudo) used to indicate if news cache exist */
544 #define mutt_bit_alloc(n) calloc ((n + 7) / 8, sizeof (char))
545 #define mutt_bit_set(v,n) v[n/8] |= (1 << (n % 8))
546 #define mutt_bit_unset(v,n) v[n/8] &= ~(1 << (n % 8))
547 #define mutt_bit_toggle(v,n) v[n/8] ^= (1 << (n % 8))
548 #define mutt_bit_isset(v,n) (v[n/8] & (1 << (n % 8)))
550 #define set_option(x) mutt_bit_set(Options,x)
551 #define unset_option(x) mutt_bit_unset(Options,x)
552 #define toggle_option(x) mutt_bit_toggle(Options,x)
553 #define option(x) mutt_bit_isset(Options,x)
555 /* Exit values used in send_msg() */
559 typedef struct list_t
565 typedef struct rx_list_t
568 struct rx_list_t *next;
571 #define mutt_new_list() safe_calloc (1, sizeof (LIST))
572 #define mutt_new_rx_list() safe_calloc (1, sizeof (RX_LIST))
573 void mutt_free_list (LIST **);
574 void mutt_free_rx_list (RX_LIST **);
575 LIST *mutt_copy_list (LIST *);
576 int mutt_matches_ignore (const char *, LIST *);
577 /* add an element to a list */
578 LIST *mutt_add_list (LIST *, const char *);
580 void mutt_init (int, LIST *);
584 struct alias *self; /* XXX - ugly hack */
593 typedef struct envelope
595 ADDRESS *return_path;
602 ADDRESS *mail_followup_to;
604 char *real_subj; /* offset of the real subject */
616 LIST *references; /* message references (in reverse order) */
617 LIST *in_reply_to; /* in-reply-to header content */
618 LIST *userhdrs; /* user defined headers */
621 typedef struct parameter
625 struct parameter *next;
628 /* Information that helps in determing the Content-* of an attachment */
629 typedef struct content
631 long hibin; /* 8-bit characters */
632 long lobin; /* unprintable 7-bit chars (eg., control chars) */
633 long crlf; /* '\r' and '\n' characters */
634 long ascii; /* number of ascii chars */
635 long linemax; /* length of the longest line in the file */
636 unsigned int space : 1; /* whitespace at the end of lines? */
637 unsigned int binary : 1; /* long lines, or CR not in CRLF pair */
638 unsigned int from : 1; /* has a line beginning with "From "? */
639 unsigned int dot : 1; /* has a line consisting of a single dot? */
640 unsigned int cr : 1; /* has CR, even when in a CRLF pair */
645 char *xtype; /* content-type if x-unknown */
646 char *subtype; /* content-type subtype */
647 PARAMETER *parameter; /* parameters of the content-type */
648 char *description; /* content-description */
649 char *form_name; /* Content-Disposition form-data name param */
650 long hdr_offset; /* offset in stream where the headers begin.
651 * this info is used when invoking metamail,
652 * where we need to send the headers of the
655 long offset; /* offset where the actual data begins */
656 long length; /* length (in bytes) of attachment */
657 char *filename; /* when sending a message, this is the file
658 * to which this structure refers
660 char *d_filename; /* filename to be used for the
661 * content-disposition header.
662 * If NULL, filename is used
665 CONTENT *content; /* structure used to store detailed info about
666 * the content of the attachment. this is used
667 * to determine what content-transfer-encoding
668 * is required when sending mail.
670 struct body *next; /* next attachment in the list */
671 struct body *parts; /* parts of a multipart or message/rfc822 */
672 struct header *hdr; /* header information for message/rfc822 */
674 struct attachptr *aptr; /* Menu information, used in recvattach.c */
676 time_t stamp; /* time stamp of last
680 unsigned int type : 4; /* content-type primary type */
681 unsigned int encoding : 3; /* content-transfer-encoding */
682 unsigned int disposition : 2; /* content-disposition */
683 unsigned int use_disp : 1; /* Content-Disposition uses filename= ? */
684 unsigned int unlink : 1; /* flag to indicate the the file named by
685 * "filename" should be unlink()ed before
686 * free()ing this structure
688 unsigned int tagged : 1;
689 unsigned int deleted : 1; /* attachment marked for deletion */
691 unsigned int noconv : 1; /* don't do character set conversion */
692 unsigned int force_charset : 1;
693 /* send mode: don't adjust the character
694 * set when in send-mode.
697 unsigned int goodsig : 1; /* good cryptographic signature */
698 unsigned int badsig : 1; /* bad cryptographic signature (needed to check encrypted s/mime-signatures) */
700 unsigned int collapsed : 1; /* used by recvattach */
704 typedef struct header
706 unsigned int security : 9; /* bit 0-6: flags, bit 7,8: application.
707 see: crypt.h pgplib.h, smime.h */
709 unsigned int mime : 1; /* has a Mime-Version header? */
710 unsigned int flagged : 1; /* marked important? */
711 unsigned int tagged : 1;
712 unsigned int appended : 1; /* has been saved */
713 unsigned int purged : 1; /* bypassing the trash folder */
714 unsigned int deleted : 1;
715 unsigned int changed : 1;
716 unsigned int attach_del : 1; /* has an attachment marked for deletion */
717 unsigned int old : 1;
718 unsigned int read : 1;
719 unsigned int expired : 1; /* already expired? */
720 unsigned int superseded : 1; /* got superseded? */
721 unsigned int replied : 1;
722 unsigned int subject_changed : 1; /* used for threading */
723 unsigned int threaded : 1; /* used for threading */
724 unsigned int display_subject : 1; /* used for threading */
725 unsigned int irt_changed : 1; /* In-Reply-To changed to link/break threads */
726 unsigned int refs_changed : 1; /* References changed to break thread */
727 unsigned int recip_valid : 1; /* is_recipient is valid */
728 unsigned int active : 1; /* message is not to be removed */
729 unsigned int trash : 1; /* message is marked as trashed on disk.
730 * This flag is used by the maildir_trash
734 /* timezone of the sender of this message */
735 unsigned int zhours : 5;
736 unsigned int zminutes : 6;
737 unsigned int zoccident : 1;
739 /* bits used for caching when searching */
740 unsigned int searched : 1;
741 unsigned int matched : 1;
743 /* the following are used to support collapsing threads */
744 unsigned int collapsed : 1; /* is this message part of a collapsed thread? */
745 unsigned int limited : 1; /* is this message in a limited view? */
746 size_t num_hidden; /* number of hidden messages in this view */
748 short recipient; /* user_is_recipient()'s return value, cached */
750 int pair; /* color-pair to use when displaying in the index */
752 time_t date_sent; /* time when the message was sent (UTC) */
753 time_t received; /* time when the message was placed in the mailbox */
754 long offset; /* where in the stream does this message begin? */
755 int lines; /* how many lines in the body of this message? */
756 int index; /* the absolute (unsorted) message number */
757 int msgno; /* number displayed to the user */
758 int virtual; /* virtual message number */
760 ENVELOPE *env; /* envelope information */
761 BODY *content; /* list of MIME parts */
767 char *tree; /* character string to print thread tree */
768 struct thread *thread;
770 #ifdef IMAP_EDIT_THREADS
771 ENVELOPE *new_env; /* envelope information for rethreading */
779 int refno; /* message number on server */
782 #if defined USE_POP || defined USE_IMAP || defined USE_NNTP
783 void *data; /* driver-specific data */
786 char *maildir_flags; /* unknown maildir flags */
789 typedef struct thread
791 unsigned int fake_thread : 1;
792 unsigned int duplicate_thread : 1;
793 unsigned int sort_children : 1;
794 unsigned int check_subject : 1;
795 unsigned int visible : 1;
796 unsigned int deep : 1;
797 unsigned int subtree_visible : 2;
798 unsigned int next_subtree_visible : 1;
799 struct thread *parent;
800 struct thread *child;
808 /* flag to mutt_pattern_comp() */
809 #define M_FULL_MSG 1 /* enable body and header matching */
812 M_MATCH_FULL_ADDRESS = 1
815 typedef struct pattern_t
822 struct pattern_t *next;
823 struct pattern_t *child; /* arguments to logical op */
832 time_t mtime_cur; /* used with maildir folders */
835 char *pattern; /* limit pattern string */
836 pattern_t *limit_pattern; /* compiled limit pattern */
838 HEADER *last_tag; /* last tagged msg. used to link threads */
839 THREAD *tree; /* top of thread tree */
840 HASH *id_hash; /* hash table by msg id */
841 HASH *subj_hash; /* hash table by subject */
842 HASH *thread_hash; /* hash table for threading */
843 int *v2r; /* mapping from virtual to real msgno */
844 int hdrmax; /* number of pointers in hdrs */
845 int msgcount; /* number of messages in the mailbox */
846 int vcount; /* the number of virtual messages */
847 int tagged; /* how many messages are tagged? */
848 int new; /* how many new messages? */
849 int unread; /* how many unread messages? */
850 int deleted; /* how many deleted messages */
851 int appended; /* how many saved messages? */
852 int flagged; /* how many flagged messages */
853 int msgnotreadyet; /* which msg "new" in pager, -1 if none */
854 #if defined USE_POP || defined USE_IMAP || defined USE_NNTP
855 void *data; /* driver specific data */
856 #endif /* USE_IMAP */
858 short magic; /* mailbox type */
860 #ifdef USE_COMPRESSED
861 void *compressinfo; /* compressed mbox module private data */
862 char *realpath; /* path to compressed mailbox */
863 #endif /* USE_COMPRESSED */
865 unsigned int locked : 1; /* is the mailbox locked? */
866 unsigned int changed : 1; /* mailbox has been modified */
867 unsigned int readonly : 1; /* don't allow changes to the mailbox */
868 unsigned int dontwrite : 1; /* dont write the mailbox on close */
869 unsigned int append : 1; /* mailbox is opened in append mode */
870 unsigned int quiet : 1; /* inhibit status messages? */
871 unsigned int collapsed : 1; /* are all threads collapsed? */
872 unsigned int closing : 1; /* mailbox is being closed */
875 typedef struct attachptr
892 /* used by enter.c */
904 /* flags for the STATE struct */
905 #define M_DISPLAY (1<<0) /* output is displayed to the user */
906 #define M_VERIFY (1<<1) /* perform signature verification */
907 #define M_PENDINGPREFIX (1<<2) /* prefix to write, but character must follow */
908 #define M_WEED (1<<3) /* weed headers even when not in display mode */
909 #define M_CHARCONV (1<<4) /* Do character set conversions */
910 #define M_PRINTING (1<<5) /* are we printing? - M_DISPLAY "light" */
912 #define state_set_prefix(s) ((s)->flags |= M_PENDINGPREFIX)
913 #define state_reset_prefix(s) ((s)->flags &= ~M_PENDINGPREFIX)
914 #define state_puts(x,y) fputs(x,(y)->fpout)
915 #define state_putc(x,y) fputc(x,(y)->fpout)
917 void state_mark_attach (STATE *);
918 void state_attach_puts (const char *, STATE *);
919 void state_prefix_putc (char, STATE *);
920 int state_printf(STATE *, const char *, ...);