1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    GNU Mailutils 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 3, or (at your option)
7    any later version.
8 
9    GNU Mailutils 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.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
20 #include <sys/types.h>
21 #include <sys/time.h>
22 #include <sys/wait.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <mh_getopt.h>
26 #include <mailutils/io.h>
27 
28 #include <string.h>
29 
30 #include <mailutils/alloc.h>
31 #include <mailutils/cctype.h>
32 #include <mailutils/cstr.h>
33 #include <mailutils/parse822.h>
34 #include <mailutils/mailbox.h>
35 #include <mailutils/message.h>
36 #include <mailutils/header.h>
37 #include <mailutils/body.h>
38 #include <mailutils/registrar.h>
39 #include <mailutils/list.h>
40 #include <mailutils/iterator.h>
41 #include <mailutils/address.h>
42 #include <mailutils/util.h>
43 #include <mailutils/stream.h>
44 #include <mailutils/filter.h>
45 #include <mailutils/url.h>
46 #include <mailutils/attribute.h>
47 #include <mailutils/error.h>
48 #include <mailutils/errno.h>
49 #include <mailutils/nls.h>
50 #include <mailutils/argcv.h>
51 #include <mailutils/wordsplit.h>
52 #include <mailutils/debug.h>
53 #include <mailutils/mailer.h>
54 #include <mailutils/envelope.h>
55 #include <mailutils/mime.h>
56 #include <mailutils/io.h>
57 #include <mailutils/property.h>
58 #include <mailutils/prog.h>
59 #include <mailutils/opool.h>
60 #include <mailutils/mh.h>
61 #include <mailutils/stdstream.h>
62 #include <mailutils/datetime.h>
63 #include <mailutils/msgset.h>
64 
65 #include <mu_umaxtostr.h>
66 
67 #define MH_SEQUENCES_FILE ".mh_sequences"
68 #define MH_USER_PROFILE ".mh_profile"
69 #define MH_GLOBAL_PROFILE "mh-profile"
70 #define MH_CONTEXT_FILE "context"
71 #define DEFAULT_ALIAS_FILE MHLIBDIR "/MailAliases"
72 
73 #define is_true(arg) ((arg) == NULL||mu_true_answer_p (arg) == 1)
74 
75 typedef struct
76 {
77   const char *name;
78   mu_header_t header;
79 } mh_context_t;
80 
81 /* Recipient masks */
82 #define RCPT_NONE 0
83 #define RCPT_TO   0x0001
84 #define RCPT_CC   0x0002
85 #define RCPT_ME   0x0004
86 #define RCPT_ALL  (RCPT_TO|RCPT_CC|RCPT_ME)
87 
88 #define RCPT_DEFAULT RCPT_NONE
89 
90 struct mh_whatnow_env     /* whatnow shell environment */
91 {
92   char *file;             /* The file being processed */
93   char *msg;              /* File name of the original message (if any) */
94   char *draftfile;        /* File to preserve the draft into */
95   const char *editor;     /* Default editor */
96   char *prompt;
97   char *anno_field;       /* Annotate field to be used */
98   mu_list_t anno_list;    /* List of messages (mu_message_t) to annotate */
99   mu_mailbox_t mbox;
100   int nowhatnowproc;
101   int reedit:1;           /* Set if the editor was already invoked */
102   char *last_ed;          /* Last used editor */
103 };
104 
105 #define DISP_QUIT 0
106 #define DISP_USE 1
107 #define DISP_REPLACE 2
108 
109 #define SEQ_PRIVATE 1
110 #define SEQ_ZERO    2
111 
112 extern int rcpt_mask;
113 extern int mh_mailbox_cur_default;
114 
115 void mh_init (void);
116 void mh_init2 (void);
117 void mh_read_profile (void);
118 int mh_read_formfile (char const *name, char **pformat);
119 mu_message_t mh_file_to_message (const char *folder, const char *file_name);
120 mu_message_t mh_stream_to_message (mu_stream_t stream);
121 void mh_install (char *name, int automode);
122 
123 mu_property_t mh_read_property_file (char *name, int ro);
124 void mh_property_merge (mu_property_t dst, mu_property_t src);
125 
126 int mh_width (void);
127 
128 #define mh_global_profile_get(name, defval) \
129   mu_mhprop_get_value (mu_mh_profile, name, defval)
130 #define mh_global_profile_set(name, value) \
131   mu_property_set_value (mu_mh_profile, name, value, 1))
132 #define mh_global_profile_iterate(fp, data) \
133   mu_mhprop_iterate (mu_mh_profile, fp, data)
134 
135 #define mh_global_context_get(name, defval) \
136   mu_mhprop_get_value (mu_mh_context, name, defval)
137 #define mh_global_context_set(name, value) \
138   mu_property_set_value (mu_mh_context, name, value, 1)
139 #define mh_global_context_iterate(fp, data) \
140   mu_mhprop_iterate (mu_mh_context, fp, data)
141 
142 const char *mh_set_current_folder (const char *val);
143 const char *mh_current_folder (void);
144 
145 mu_property_t mh_mailbox_get_property (mu_mailbox_t mbox);
146 const char *mh_global_sequences_get (mu_mailbox_t mbox,
147 				     const char *name, const char *defval);
148 void mh_global_sequences_set (mu_mailbox_t mbox,
149 			      const char *name, const char *value);
150 void mh_global_sequences_iterate (mu_mailbox_t mbox,
151 				  mu_mhprop_iterator_t fp, void *data);
152 void mh_global_sequences_drop (mu_mailbox_t mbox);
153 
154 void mh_global_save_state (void);
155 
156 int mh_private_sequences_iterate (mu_mailbox_t mbox, mu_mhprop_iterator_t fp,
157 				  void *data);
158 
159 int mh_interactive_mode_p (void);
160 int mh_getyn (const char *fmt, ...) MU_PRINTFLIKE(1,2);
161 int mh_getyn_interactive (const char *fmt, ...) MU_PRINTFLIKE(1,2);
162 int mu_vgetans (const char *variants, const char *fmt, va_list ap);
163 int mu_getans (const char *variants, const char *fmt, ...)
164   MU_PRINTFLIKE(2,3);
165 int mh_check_folder (const char *pathname, int confirm);
166 int mh_makedir (const char *p);
167 
168 typedef struct mh_format *mh_format_t;
169 typedef struct mh_fvm *mh_fvm_t;
170 
171 #define MH_FMT_FORCENL 1
172 void mh_fvm_create (mh_fvm_t *fvm, int flags);
173 void mh_fvm_destroy (mh_fvm_t *fvm);
174 
175 void mh_fvm_set_output (mh_fvm_t fvm, mu_stream_t str);
176 void mh_fvm_set_width (mh_fvm_t fvm, size_t width);
177 void mh_fvm_set_format (mh_fvm_t fvm, mh_format_t fmt);
178 
179 void mh_fvm_run (mh_fvm_t fvm, mu_message_t msg);
180 
181 int mh_format_str (mh_format_t fmt, char *str, size_t width, char **pret);
182 
183 void mh_format_dump_code (mh_format_t fmt);
184 void mh_format_dump_disass (mh_format_t fmt, int addr);
185 
186 #define MH_FMT_PARSE_DEFAULT 0
187 #define MH_FMT_PARSE_TREE 0x01
188 #define MH_FMT_PARSE_DEBUG 0x02
189 int mh_format_string_parse (mh_format_t *retfmt, char const *format_str,
190 			    struct mu_locus_point const *locus,
191 			    int flags);
192 int mh_format_file_parse (mh_format_t *retfmt, char const *formfile,
193 			  int flags);
194 mh_format_t mh_scan_format (void);
195 
196 
197 void mh_format_free (mh_format_t fmt);
198 void mh_format_destroy (mh_format_t *fmt);
199 
200 void mh_error (const char *fmt, ...) MU_PRINTFLIKE(1,2);
201 void mh_err_memory (int fatal);
202 
203 mu_stream_t mh_audit_open (char *name, mu_mailbox_t mbox);
204 void mh_audit_close (mu_stream_t);
205 
206 int mh_message_number (mu_message_t msg, size_t *pnum);
207 
208 mu_mailbox_t mh_open_folder (const char *folder, int flags);
209 
210 void mh_msgset_parse (mu_msgset_t *msgset, mu_mailbox_t mbox,
211 		      int argc, char **argv, const char *def);
212 void mh_msgset_parse_string (mu_msgset_t *msgset, mu_mailbox_t mbox,
213 			     const char *string, const char *def);
214 #define RET_MSGNO 0
215 #define RET_UID   1
216 size_t mh_msgset_first (mu_msgset_t msgset, int uid);
217 size_t mh_msgset_last  (mu_msgset_t msgset, int uid);
218 int mh_msgset_single_message (mu_msgset_t msgset);
219 
220 #define NAME_ANY    0
221 #define NAME_FOLDER 1
222 #define NAME_FILE   2
223 char *mh_expand_name (const char *base, const char *name, int what);
224 
225 char *mh_get_dir (void);
226 int mh_find_file (const char *name, char **resolved_name);
227 void mh_quote (const char *in, char **out);
228 void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to,
229 			mu_address_t *addr_cc,
230 			mu_address_t *addr_bcc);
231 
232 int mh_is_my_name (const char *name);
233 char const *mh_get_my_real_name (void);
234 char const *mh_get_my_user_name (void);
235 char const *mh_my_email (void);
236 char const *mh_my_host (void);
237 
238 
239 size_t mh_get_message (mu_mailbox_t mbox, size_t seqno, mu_message_t *mesg);
240 
241 int mh_decode_rcpt_flag (const char *arg);
242 
243 int mh_draft_message (const char *name, const char *msgspec, char **pname);
244 
245 int mh_spawnp (const char *prog, const char *file);
246 int mh_whatnow (struct mh_whatnow_env *wh, int initial_edit);
247 int mh_whatnowproc (struct mh_whatnow_env *wh, int initial_edit,
248 		    const char *prog);
249 
250 int mh_disposition (const char *filename);
251 int mh_usedraft (const char *filename);
252 int mh_file_copy (const char *from, const char *to);
253 char *mh_draft_name (void);
254 char *mh_create_message_id (int);
255 
256 int mh_whom_header (mu_header_t hdr);
257 int mh_whom_file (const char *filename, int check);
258 int mh_whom_message (mu_message_t msg, int check);
259 
260 void mh_set_reply_regex (const char *str);
261 int mh_decode_2047 (char const *text, char **decoded_text);
262 const char *mh_charset (const char *);
263 
264 int mh_alias_read (char const *name, int fail);
265 int mh_alias_get (const char *name, mu_list_t *return_list);
266 int mh_alias_get_address (const char *name, mu_address_t *addr, int *incl);
267 int mh_alias_get_alias (const char *uname, mu_list_t *return_list);
268 int mh_read_aliases (void);
269 int mh_alias_expand (const char *str, mu_address_t *paddr, int *incl);
270 
271 typedef int (*mh_alias_enumerator_t) (char *alias, mu_list_t names, void *data);
272 void mh_alias_enumerate (mh_alias_enumerator_t fun, void *data);
273 
274 
275 void mh_annotate (mu_message_t msg, const char *field, const char *text,
276 		  int date);
277 
278 #define MHL_DECODE       1
279 #define MHL_CLEARSCREEN  2
280 #define MHL_BELL         4
281 #define MHL_DISABLE_BODY 8
282 
283 mu_list_t mhl_format_compile (char *name);
284 
285 int mhl_format_run (mu_list_t fmt, int width, int length, int flags,
286 		    mu_message_t msg, mu_stream_t output);
287 void mhl_format_destroy (mu_list_t *fmt);
288 
289 void mh_seq_add (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
290 		 int flags);
291 int mh_seq_delete (mu_mailbox_t mbox, const char *name, mu_msgset_t mset,
292 		   int flags);
293 const char *mh_seq_read (mu_mailbox_t mbox, const char *name, int flags);
294 
295 void mh_sequences_elim (mu_msgset_t msgset);
296 
297 void mh_comp_draft (const char *formfile, const char *draftfile);
298 int check_draft_disposition (struct mh_whatnow_env *wh, int use_draft);
299 
300 void ali_verbatim (int enable);
301 
302 char *mh_safe_make_file_name (const char *dir, const char *file);
303 
304 void mh_mailbox_get_cur (mu_mailbox_t mbox, size_t *pcur);
305 void mh_mailbox_set_cur (mu_mailbox_t mbox, size_t cur);
306 
307 void mh_whatnow_env_from_environ_early (struct mh_whatnow_env *wh);
308 void mh_whatnow_env_from_environ_late (struct mh_whatnow_env *wh);
309 void mh_whatnow_env_to_environ (struct mh_whatnow_env *wh);
310