NeoMutt  2018-07-16 +2481-68dcde
Teaching an old dog new tricks
DOXYGEN
protos.h File Reference

Prototypes for many functions. More...

#include "config.h"
#include <stddef.h>
#include <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include "mutt.h"
#include "keymap.h"
#include "ncrypt/ncrypt.h"
+ Include dependency graph for protos.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define mutt_set_flag(m, e, flag, bf)   mutt_set_flag_update(m, e, flag, bf, true)
 

Enumerations

enum  XdgType { XDG_CONFIG_HOME, XDG_CONFIG_DIRS }
 XDG variable types. More...
 
enum  EvMessage { EVM_VIEW, EVM_EDIT }
 Edit or View a message. More...
 

Functions

int mutt_ev_message (struct Mailbox *m, struct EmailList *el, enum EvMessage action)
 Edit or view a message. More...
 
int mutt_system (const char *cmd)
 Run an external command. More...
 
int mutt_set_xdg_path (enum XdgType type, char *buf, size_t bufsize)
 Find an XDG path or its fallback. More...
 
void mutt_help (enum MenuType menu)
 Display the help menu. More...
 
void mutt_make_help (char *d, size_t dlen, const char *txt, enum MenuType menu, int op)
 Create one entry for the help bar. More...
 
void mutt_set_flag_update (struct Mailbox *m, struct Email *e, int flag, bool bf, bool upd_mbox)
 Set a flag on an email. More...
 
void mutt_signal_init (void)
 Initialise the signal handling. More...
 
void mutt_emails_set_flag (struct Mailbox *m, struct EmailList *el, int flag, bool bf)
 Set flag on messages. More...
 
int mutt_change_flag (struct Mailbox *m, struct EmailList *el, bool bf)
 Change the flag on a Message. More...
 
int mutt_complete (char *buf, size_t buflen)
 Attempt to complete a partial pathname. More...
 
int mutt_prepare_template (FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
 Prepare a message template. More...
 
int mutt_enter_string (char *buf, size_t buflen, int col, CompletionFlags flags)
 Ask the user for a string. More...
 
int mutt_enter_string_full (char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, char ***files, int *numfiles, struct EnterState *state)
 Ask the user for a string. More...
 
int mutt_get_postponed (struct Context *ctx, struct Email *hdr, struct Email **cur, char *fcc, size_t fcclen)
 Recall a postponed message. More...
 
SecurityFlags mutt_parse_crypt_hdr (const char *p, bool set_empty_signas, SecurityFlags crypt_app)
 Parse a crypto header string. More...
 
int mutt_num_postponed (struct Mailbox *m, bool force)
 Return the number of postponed messages. More...
 
int mutt_thread_set_flag (struct Email *e, int flag, bool bf, bool subthread)
 Set a flag on an entire thread. More...
 
void mutt_update_num_postponed (void)
 Force the update of the number of postponed messages. More...
 
int mutt_is_quote_line (char *buf, regmatch_t *pmatch)
 Is a line of message text a quote? More...
 
int wcscasecmp (const wchar_t *a, const wchar_t *b)
 Compare two wide-character strings, ignoring case. More...
 
int mutt_reply_observer (struct NotifyCallback *nc)
 Listen for config changes to "reply_regex" - Implements observer_t() More...
 

Detailed Description

Prototypes for many functions.

Authors
  • Michael R. Elkins
  • Karel Zak

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, see http://www.gnu.org/licenses/.

Definition in file protos.h.

Macro Definition Documentation

◆ mutt_set_flag

#define mutt_set_flag (   m,
  e,
  flag,
  bf 
)    mutt_set_flag_update(m, e, flag, bf, true)

Definition at line 69 of file protos.h.

Enumeration Type Documentation

◆ XdgType

enum XdgType

XDG variable types.

Enumerator
XDG_CONFIG_HOME 

XDG home dir: ~/.config.

XDG_CONFIG_DIRS 

XDG system dir: /etc/xdg.

Definition at line 46 of file protos.h.

47 {
50 };
XDG home dir: ~/.config.
Definition: protos.h:48
XDG system dir: /etc/xdg.
Definition: protos.h:49

◆ EvMessage

enum EvMessage

Edit or View a message.

Enumerator
EVM_VIEW 

View the message.

EVM_EDIT 

Edit the message.

Definition at line 55 of file protos.h.

56 {
57  EVM_VIEW,
58  EVM_EDIT,
59 };
View the message.
Definition: protos.h:57
Edit the message.
Definition: protos.h:58

Function Documentation

◆ mutt_ev_message()

int mutt_ev_message ( struct Mailbox m,
struct EmailList *  el,
enum EvMessage  action 
)

Edit or view a message.

Parameters
mMailbox
elList of Emails
actionAction to perform, e.g. EVM_EDIT
Return values
1Message not modified
0Message edited successfully
-1Error

Definition at line 262 of file editmsg.c.

263 {
264  struct EmailNode *en = NULL;
265  STAILQ_FOREACH(en, el, entries)
266  {
267  if (ev_message(action, m, en->email) == -1)
268  return -1;
269  }
270 
271  return 0;
272 }
static int ev_message(enum EvMessage action, struct Mailbox *m, struct Email *e)
Edit an email or view it in an external editor.
Definition: editmsg.c:59
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
struct Email * email
Email in the list.
Definition: email.h:122
List of Emails.
Definition: email.h:120
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_system()

int mutt_system ( const char *  cmd)

Run an external command.

Parameters
cmdCommand and arguments
Return values
-1Error
>=0Success (command's return code)

Fork and run an external command with arguments.

Note
This function won't return until the command finishes.

Definition at line 51 of file system.c.

52 {
53  int rc = -1;
54  struct sigaction act;
55  struct sigaction oldtstp;
56  struct sigaction oldcont;
57  pid_t pid;
58 
59  if (!cmd || !*cmd)
60  return 0;
61 
62  /* must ignore SIGINT and SIGQUIT */
63 
65 
66  act.sa_handler = SIG_DFL;
67 /* we want to restart the waitpid() below */
68 #ifdef SA_RESTART
69  act.sa_flags = SA_RESTART;
70 #endif
71  sigemptyset(&act.sa_mask);
72  sigaction(SIGTSTP, &act, &oldtstp);
73  sigaction(SIGCONT, &act, &oldcont);
74 
75  pid = fork();
76  if (pid == 0)
77  {
78  act.sa_flags = 0;
79 
80  /* reset signals for the child; not really needed, but... */
82  act.sa_handler = SIG_DFL;
83  act.sa_flags = 0;
84  sigemptyset(&act.sa_mask);
85  sigaction(SIGTERM, &act, NULL);
86  sigaction(SIGTSTP, &act, NULL);
87  sigaction(SIGCONT, &act, NULL);
88 
89  execle(EXEC_SHELL, "sh", "-c", cmd, NULL, mutt_envlist_getlist());
90  _exit(127); /* execl error */
91  }
92  else if (pid != -1)
93  {
94 #ifdef USE_IMAP
95  rc = imap_wait_keepalive(pid);
96 #endif
97  }
98 
99  sigaction(SIGCONT, &oldcont, NULL);
100  sigaction(SIGTSTP, &oldtstp, NULL);
101 
102  /* reset SIGINT, SIGQUIT and SIGCHLD */
104 
105  rc = (pid != -1) ? (WIFEXITED(rc) ? WEXITSTATUS(rc) : -1) : -1;
106 
107  return rc;
108 }
void mutt_sig_block_system(void)
Block signals before calling exec()
Definition: signal.c:183
void mutt_sig_unblock_system(bool restore)
Restore previously blocked signals.
Definition: signal.c:207
#define EXEC_SHELL
Definition: mutt.h:139
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1076
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:167
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_set_xdg_path()

int mutt_set_xdg_path ( enum XdgType  type,
char *  buf,
size_t  bufsize 
)

Find an XDG path or its fallback.

Parameters
typeType of XDG variable, e.g. XDG_CONFIG_HOME
bufBuffer to save path
bufsizeBuffer length
Return values
1if an entry was found that actually exists on disk and 0 otherwise

Process an XDG environment variable or its fallback.

Definition at line 1565 of file muttlib.c.

1566 {
1567  const char *xdg_env = mutt_str_getenv(xdg_env_vars[type]);
1568  char *xdg = xdg_env ? mutt_str_strdup(xdg_env) : mutt_str_strdup(xdg_defaults[type]);
1569  char *x = xdg; /* strsep() changes xdg, so free x instead later */
1570  char *token = NULL;
1571  int rc = 0;
1572 
1573  while ((token = strsep(&xdg, ":")))
1574  {
1575  if (snprintf(buf, bufsize, "%s/%s/neomuttrc", token, PACKAGE) < 0)
1576  continue;
1577  mutt_expand_path(buf, bufsize);
1578  if (access(buf, F_OK) == 0)
1579  {
1580  rc = 1;
1581  break;
1582  }
1583 
1584  if (snprintf(buf, bufsize, "%s/%s/Muttrc", token, PACKAGE) < 0)
1585  continue;
1586  mutt_expand_path(buf, bufsize);
1587  if (access(buf, F_OK) == 0)
1588  {
1589  rc = 1;
1590  break;
1591  }
1592  }
1593 
1594  FREE(&x);
1595  return rc;
1596 }
static const char * xdg_env_vars[]
Definition: muttlib.c:72
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:1049
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
static const char * xdg_defaults[]
Definition: muttlib.c:77
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_help()

void mutt_help ( enum MenuType  menu)

Display the help menu.

Parameters
menuCurrent Menu

Definition at line 439 of file help.c.

440 {
441  char t[PATH_MAX];
442  char buf[128];
443  FILE *fp = NULL;
444 
445  mutt_mktemp(t, sizeof(t));
446 
447  const struct Binding *funcs = km_get_table(menu);
448  const char *desc = mutt_map_get_name(menu, Menus);
449  if (!desc)
450  desc = _("<UNKNOWN>");
451 
452  do
453  {
454  fp = mutt_file_fopen(t, "w");
455  if (!fp)
456  {
457  mutt_perror(t);
458  return;
459  }
460 
461  dump_menu(fp, menu);
462  if ((menu != MENU_EDITOR) && (menu != MENU_PAGER))
463  {
464  fprintf(fp, "\n%s\n\n", _("Generic bindings:"));
465  dump_menu(fp, MENU_GENERIC);
466  }
467 
468  fprintf(fp, "\n%s\n\n", _("Unbound functions:"));
469  if (funcs)
470  dump_unbound(fp, funcs, Keymaps[menu], NULL);
471  if (menu != MENU_PAGER)
473 
474  mutt_file_fclose(&fp);
475 
476  snprintf(buf, sizeof(buf), _("Help for %s"), desc);
478  NULL) == OP_REFORMAT_WINCH);
479 }
static void dump_menu(FILE *fp, enum MenuType menu)
Write all the key bindings to a file.
Definition: help.c:374
#define mutt_perror(...)
Definition: logging.h:85
struct Keymap * Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:147
#define _(a)
Definition: message.h:28
#define MUTT_PAGER_NOWRAP
Format for term width, ignore $wrap.
Definition: pager.h:56
Pager pager (email viewer)
Definition: keymap.h:69
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
#define MUTT_PAGER_NSKIP
Preserve whitespace with smartwrap.
Definition: pager.h:52
const struct Mapping Menus[]
Menu name lookup table.
Definition: keymap.c:60
#define mutt_mktemp(buf, buflen)
Definition: muttlib.h:76
static void dump_unbound(FILE *fp, const struct Binding *funcs, struct Keymap *map, struct Keymap *aux)
Write out all the operations with no key bindings.
Definition: help.c:425
#define PATH_MAX
Definition: mutt.h:52
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.h:54
#define MUTT_PAGER_RETWINCH
Need reformatting on SIGWINCH.
Definition: pager.h:54
int mutt_do_pager(const char *banner, const char *tempfile, PagerFlags do_color, struct Pager *info)
Display some page-able text to the user.
Definition: curs_lib.c:586
const struct Binding * km_get_table(enum MenuType menu)
Lookup a menu&#39;s keybindings.
Definition: keymap.c:1219
Text entry area.
Definition: keymap.h:65
#define MUTT_PAGER_MARKER
Use markers if option is set.
Definition: pager.h:53
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:583
Mapping between a user key and a function.
Definition: keymap.h:105
Generic selection list.
Definition: keymap.h:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_help()

void mutt_make_help ( char *  buf,
size_t  buflen,
const char *  txt,
enum MenuType  menu,
int  op 
)

Create one entry for the help bar.

Parameters
bufBuffer for the result
buflenLength of buffer
txtText part, e.g. "delete"
menuCurrent Menu, e.g. MENU_PAGER
opOperation, e.g. OP_DELETE

This will return something like: "d:delete"

Definition at line 92 of file help.c.

93 {
94  char tmp[128];
95 
96  if (km_expand_key(tmp, sizeof(tmp), km_find_func(menu, op)) ||
97  km_expand_key(tmp, sizeof(tmp), km_find_func(MENU_GENERIC, op)))
98  {
99  snprintf(buf, buflen, "%s:%s", tmp, txt);
100  }
101  else
102  {
103  buf[0] = '\0';
104  }
105 }
int op
function id number
Definition: keymap.h:108
struct Keymap * km_find_func(enum MenuType menu, int func)
Find a function&#39;s mapping in a Menu.
Definition: keymap.c:808
int km_expand_key(char *s, size_t len, struct Keymap *map)
Get the key string bound to a Keymap.
Definition: keymap.c:780
Generic selection list.
Definition: keymap.h:67
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_set_flag_update()

void mutt_set_flag_update ( struct Mailbox m,
struct Email e,
int  flag,
bool  bf,
bool  upd_mbox 
)

Set a flag on an email.

Parameters
mMailbox
eEmail
flagFlag to set, e.g. MUTT_DELETE
bftrue: set the flag; false: clear the flag
upd_mboxtrue: update the Mailbox

Definition at line 55 of file flags.c.

56 {
57  if (!m || !e)
58  return;
59 
60  bool changed = e->changed;
61  int deleted = m->msg_deleted;
62  int tagged = m->msg_tagged;
63  int flagged = m->msg_flagged;
64  int update = false;
65 
66  if (m->readonly && (flag != MUTT_TAG))
67  return; /* don't modify anything if we are read-only */
68 
69  switch (flag)
70  {
71  case MUTT_DELETE:
72 
73  if (!(m->rights & MUTT_ACL_DELETE))
74  return;
75 
76  if (bf)
77  {
78  if (!e->deleted && !m->readonly && (!e->flagged || !C_FlagSafe))
79  {
80  e->deleted = true;
81  update = true;
82  if (upd_mbox)
83  m->msg_deleted++;
84 #ifdef USE_IMAP
85  /* deleted messages aren't treated as changed elsewhere so that the
86  * purge-on-sync option works correctly. This isn't applicable here */
87  if (m->magic == MUTT_IMAP)
88  {
89  e->changed = true;
90  if (upd_mbox)
91  m->changed = true;
92  }
93 #endif
94  }
95  }
96  else if (e->deleted)
97  {
98  e->deleted = false;
99  update = true;
100  if (upd_mbox)
101  m->msg_deleted--;
102 #ifdef USE_IMAP
103  /* see my comment above */
104  if (m->magic == MUTT_IMAP)
105  {
106  e->changed = true;
107  if (upd_mbox)
108  m->changed = true;
109  }
110 #endif
111  /* If the user undeletes a message which is marked as
112  * "trash" in the maildir folder on disk, the folder has
113  * been changed, and is marked accordingly. However, we do
114  * _not_ mark the message itself changed, because trashing
115  * is checked in specific code in the maildir folder
116  * driver. */
117  if ((m->magic == MUTT_MAILDIR) && upd_mbox && e->trash)
118  m->changed = true;
119  }
120  break;
121 
122  case MUTT_PURGE:
123 
124  if (!(m->rights & MUTT_ACL_DELETE))
125  return;
126 
127  if (bf)
128  {
129  if (!e->purge && !m->readonly)
130  e->purge = true;
131  }
132  else if (e->purge)
133  e->purge = false;
134  break;
135 
136  case MUTT_NEW:
137 
138  if (!(m->rights & MUTT_ACL_SEEN))
139  return;
140 
141  if (bf)
142  {
143  if (e->read || e->old)
144  {
145  update = true;
146  e->old = false;
147  if (upd_mbox)
148  m->msg_new++;
149  if (e->read)
150  {
151  e->read = false;
152  if (upd_mbox)
153  m->msg_unread++;
154  }
155  e->changed = true;
156  if (upd_mbox)
157  m->changed = true;
158  }
159  }
160  else if (!e->read)
161  {
162  update = true;
163  if (!e->old)
164  if (upd_mbox)
165  m->msg_new--;
166  e->read = true;
167  if (upd_mbox)
168  m->msg_unread--;
169  e->changed = true;
170  if (upd_mbox)
171  m->changed = true;
172  }
173  break;
174 
175  case MUTT_OLD:
176 
177  if (!(m->rights & MUTT_ACL_SEEN))
178  return;
179 
180  if (bf)
181  {
182  if (!e->old)
183  {
184  update = true;
185  e->old = true;
186  if (!e->read)
187  if (upd_mbox)
188  m->msg_new--;
189  e->changed = true;
190  if (upd_mbox)
191  m->changed = true;
192  }
193  }
194  else if (e->old)
195  {
196  update = true;
197  e->old = false;
198  if (!e->read)
199  if (upd_mbox)
200  m->msg_new++;
201  e->changed = true;
202  if (upd_mbox)
203  m->changed = true;
204  }
205  break;
206 
207  case MUTT_READ:
208 
209  if (!(m->rights & MUTT_ACL_SEEN))
210  return;
211 
212  if (bf)
213  {
214  if (!e->read)
215  {
216  update = true;
217  e->read = true;
218  if (upd_mbox)
219  m->msg_unread--;
220  if (!e->old)
221  if (upd_mbox)
222  m->msg_new--;
223  e->changed = true;
224  if (upd_mbox)
225  m->changed = true;
226  }
227  }
228  else if (e->read)
229  {
230  update = true;
231  e->read = false;
232  if (upd_mbox)
233  m->msg_unread++;
234  if (!e->old)
235  if (upd_mbox)
236  m->msg_new++;
237  e->changed = true;
238  if (upd_mbox)
239  m->changed = true;
240  }
241  break;
242 
243  case MUTT_REPLIED:
244 
245  if (!(m->rights & MUTT_ACL_WRITE))
246  return;
247 
248  if (bf)
249  {
250  if (!e->replied)
251  {
252  update = true;
253  e->replied = true;
254  if (!e->read)
255  {
256  e->read = true;
257  if (upd_mbox)
258  m->msg_unread--;
259  if (!e->old)
260  if (upd_mbox)
261  m->msg_new--;
262  }
263  e->changed = true;
264  if (upd_mbox)
265  m->changed = true;
266  }
267  }
268  else if (e->replied)
269  {
270  update = true;
271  e->replied = false;
272  e->changed = true;
273  if (upd_mbox)
274  m->changed = true;
275  }
276  break;
277 
278  case MUTT_FLAG:
279 
280  if (!(m->rights & MUTT_ACL_WRITE))
281  return;
282 
283  if (bf)
284  {
285  if (!e->flagged)
286  {
287  update = true;
288  e->flagged = bf;
289  if (upd_mbox)
290  m->msg_flagged++;
291  e->changed = true;
292  if (upd_mbox)
293  m->changed = true;
294  }
295  }
296  else if (e->flagged)
297  {
298  update = true;
299  e->flagged = false;
300  if (upd_mbox)
301  m->msg_flagged--;
302  e->changed = true;
303  if (upd_mbox)
304  m->changed = true;
305  }
306  break;
307 
308  case MUTT_TAG:
309  if (bf)
310  {
311  if (!e->tagged)
312  {
313  update = true;
314  e->tagged = true;
315  if (upd_mbox)
316  m->msg_tagged++;
317  }
318  }
319  else if (e->tagged)
320  {
321  update = true;
322  e->tagged = false;
323  if (upd_mbox)
324  m->msg_tagged--;
325  }
326  break;
327  }
328 
329  if (update)
330  {
331  mutt_set_header_color(m, e);
332 #ifdef USE_SIDEBAR
334 #endif
335  }
336 
337  /* if the message status has changed, we need to invalidate the cached
338  * search results so that any future search will match the current status
339  * of this message and not what it was at the time it was last searched. */
340  if (e->searched && ((changed != e->changed) || (deleted != m->msg_deleted) ||
341  (tagged != m->msg_tagged) || (flagged != m->msg_flagged)))
342  {
343  e->searched = false;
344  }
345 }
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:107
int msg_unread
Number of unread messages.
Definition: mailbox.h:103
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:104
Flagged messages.
Definition: mutt.h:108
bool changed
Email has been edited.
Definition: email.h:50
Messages to be purged (bypass trash)
Definition: mutt.h:106
bool searched
Email has been searched.
Definition: email.h:69
#define MUTT_ACL_DELETE
Delete a message.
Definition: mailbox.h:77
Messages that have been replied to.
Definition: mutt.h:101
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
bool tagged
Email is tagged.
Definition: email.h:46
bool read
Email is read.
Definition: email.h:53
bool old
Email is seen, but unread.
Definition: email.h:52
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
bool readonly
Don&#39;t allow changes to the mailbox.
Definition: mailbox.h:130
#define MUTT_ACL_WRITE
Write to a message (for flagging or linking threads)
Definition: mailbox.h:85
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
bool trash
Message is marked as trashed on disk (used by the maildir_trash option)
Definition: email.h:62
Old messages.
Definition: mutt.h:100
Messages to be deleted.
Definition: mutt.h:104
Tagged messages.
Definition: mutt.h:109
New messages.
Definition: mutt.h:99
Messages that have been read.
Definition: mutt.h:102
bool purge
Skip trash folder when deleting.
Definition: email.h:48
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:108
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:132
void mutt_set_header_color(struct Mailbox *m, struct Email *e)
Select a colour for a message.
Definition: index.c:3672
bool flagged
Marked important?
Definition: email.h:45
int msg_new
Number of new messages.
Definition: mailbox.h:106
bool deleted
Email is deleted.
Definition: email.h:47
bool replied
Email has been replied to.
Definition: email.h:56
#define MUTT_ACL_SEEN
Change the &#39;seen&#39; status of a message.
Definition: mailbox.h:84
WHERE bool C_FlagSafe
Config: Protect flagged messages from deletion.
Definition: globals.h:218
bool changed
Mailbox has been modified.
Definition: mailbox.h:125
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_signal_init()

void mutt_signal_init ( void  )

Initialise the signal handling.

Definition at line 127 of file mutt_signal.c.

128 {
130 
131 #ifdef USE_SLANG_CURSES
132  /* This bit of code is required because of the implementation of
133  * SLcurses_wgetch(). If a signal is received (like SIGWINCH) when we
134  * are in blocking mode, SLsys_getkey() will not return an error unless
135  * a handler function is defined and it returns -1. This is needed so
136  * that if the user resizes the screen while at a prompt, it will just
137  * abort and go back to the main-menu. */
138  SLang_getkey_intr_hook = mutt_intr_hook;
139 #endif
140 }
static void curses_signal_handler(int sig)
Catch signals and relay the info to the main program.
Definition: mutt_signal.c:44
static void curses_exit_handler(int sig)
Notify the user and shutdown gracefully.
Definition: mutt_signal.c:84
void mutt_sig_init(sig_handler_t sig_fn, sig_handler_t exit_fn, sig_handler_t segv_fn)
Initialise the signal handling.
Definition: signal.c:88
static void curses_segv_handler(int sig)
Catch a segfault and print a backtrace.
Definition: mutt_signal.c:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_emails_set_flag()

void mutt_emails_set_flag ( struct Mailbox m,
struct EmailList *  el,
int  flag,
bool  bf 
)

Set flag on messages.

Parameters
mMailbox
elList of Emails to flag
flagFlag to set, e.g. MUTT_DELETE
bftrue: set the flag; false: clear the flag

Definition at line 354 of file flags.c.

355 {
356  if (!m || !el || STAILQ_EMPTY(el))
357  return;
358 
359  struct EmailNode *en = NULL;
360  STAILQ_FOREACH(en, el, entries)
361  {
362  mutt_set_flag(m, en->email, flag, bf);
363  }
364 }
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:69
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
struct Email * email
Email in the list.
Definition: email.h:122
#define STAILQ_EMPTY(head)
Definition: queue.h:346
List of Emails.
Definition: email.h:120
+ Here is the caller graph for this function:

◆ mutt_change_flag()

int mutt_change_flag ( struct Mailbox m,
struct EmailList *  el,
bool  bf 
)

Change the flag on a Message.

Parameters
mMailbox
elList of Emails to change
bftrue: set the flag; false: clear the flag
Return values
0Success
-1Failure

Definition at line 433 of file flags.c.

434 {
435  if (!m || !el || STAILQ_EMPTY(el))
436  return -1;
437 
438  int flag;
439  struct KeyEvent event;
440 
442  "%s? (D/N/O/r/*/!): ", bf ? _("Set flag") : _("Clear flag"));
444  mutt_refresh();
445 
446  do
447  {
448  event = mutt_getch();
449  } while (event.ch == -2);
450  int i = event.ch;
451  if (i < 0)
452  {
454  return -1;
455  }
456 
458 
459  switch (i)
460  {
461  case 'd':
462  case 'D':
463  if (!bf)
464  mutt_emails_set_flag(m, el, MUTT_PURGE, bf);
465  flag = MUTT_DELETE;
466  break;
467 
468  case 'N':
469  case 'n':
470  flag = MUTT_NEW;
471  break;
472 
473  case 'o':
474  case 'O':
475  mutt_emails_set_flag(m, el, MUTT_READ, !bf);
476  flag = MUTT_OLD;
477  break;
478 
479  case 'r':
480  case 'R':
481  flag = MUTT_REPLIED;
482  break;
483 
484  case '*':
485  flag = MUTT_TAG;
486  break;
487 
488  case '!':
489  flag = MUTT_FLAG;
490  break;
491 
492  default:
493  BEEP();
494  return -1;
495  }
496 
497  mutt_emails_set_flag(m, el, flag, bf);
498  return 0;
499 }
void mutt_emails_set_flag(struct Mailbox *m, struct EmailList *el, int flag, bool bf)
Set flag on messages.
Definition: flags.c:354
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
Flagged messages.
Definition: mutt.h:108
#define _(a)
Definition: message.h:28
Messages to be purged (bypass trash)
Definition: mutt.h:106
Messages that have been replied to.
Definition: mutt.h:101
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:95
Old messages.
Definition: mutt.h:100
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:94
Messages to be deleted.
Definition: mutt.h:104
#define BEEP()
Definition: mutt_curses.h:80
Tagged messages.
Definition: mutt.h:109
New messages.
Definition: mutt.h:99
Messages that have been read.
Definition: mutt.h:102
An event such as a keypress.
Definition: mutt_curses.h:108
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:175
#define STAILQ_EMPTY(head)
Definition: queue.h:346
int mutt_window_mvprintw(struct MuttWindow *win, int row, int col, const char *fmt,...)
Move the cursor and write a formatted string to a Window.
Definition: mutt_window.c:217
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_complete()

int mutt_complete ( char *  buf,
size_t  buflen 
)

Attempt to complete a partial pathname.

Parameters
bufBuffer containing pathname
buflenLength of buffer
Return values
0if ok
-1if no matches

Given a partial pathname, fill in as much of the rest of the path as is unique.

Definition at line 57 of file complete.c.

58 {
59  char *p = NULL;
60  DIR *dirp = NULL;
61  struct dirent *de = NULL;
62  int i, init = 0;
63  size_t len;
64  char dirpart[PATH_MAX], exp_dirpart[PATH_MAX];
65  char filepart[PATH_MAX];
66 #ifdef USE_IMAP
67  char imap_path[PATH_MAX];
68 #endif
69 
70  mutt_debug(LL_DEBUG2, "completing %s\n", buf);
71 
72 #ifdef USE_NNTP
73  if (OptNews)
74  return nntp_complete(buf, buflen);
75 #endif
76 
77 #ifdef USE_IMAP
78  /* we can use '/' as a delimiter, imap_complete rewrites it */
79  if ((*buf == '=') || (*buf == '+') || (*buf == '!'))
80  {
81  if (*buf == '!')
82  p = NONULL(C_Spoolfile);
83  else
84  p = NONULL(C_Folder);
85 
86  mutt_path_concat(imap_path, p, buf + 1, sizeof(imap_path));
87  }
88  else
89  mutt_str_strfcpy(imap_path, buf, sizeof(imap_path));
90 
91  if (imap_path_probe(imap_path, NULL) == MUTT_IMAP)
92  return imap_complete(buf, buflen, imap_path);
93 #endif
94 
95  if ((*buf == '=') || (*buf == '+') || (*buf == '!'))
96  {
97  dirpart[0] = *buf;
98  dirpart[1] = '\0';
99  if (*buf == '!')
100  mutt_str_strfcpy(exp_dirpart, C_Spoolfile, sizeof(exp_dirpart));
101  else
102  mutt_str_strfcpy(exp_dirpart, C_Folder, sizeof(exp_dirpart));
103  p = strrchr(buf, '/');
104  if (p)
105  {
106  char tmp[PATH_MAX];
107  if (!mutt_path_concatn(tmp, sizeof(tmp), exp_dirpart, strlen(exp_dirpart),
108  buf + 1, (size_t)(p - buf - 1)))
109  {
110  return -1;
111  }
112  mutt_str_strfcpy(exp_dirpart, tmp, sizeof(exp_dirpart));
113  mutt_str_substr_copy(buf, p + 1, dirpart, sizeof(dirpart));
114  mutt_str_strfcpy(filepart, p + 1, sizeof(filepart));
115  }
116  else
117  mutt_str_strfcpy(filepart, buf + 1, sizeof(filepart));
118  dirp = opendir(exp_dirpart);
119  }
120  else
121  {
122  p = strrchr(buf, '/');
123  if (p)
124  {
125  if (p == buf) /* absolute path */
126  {
127  p = buf + 1;
128  mutt_str_strfcpy(dirpart, "/", sizeof(dirpart));
129  exp_dirpart[0] = '\0';
130  mutt_str_strfcpy(filepart, p, sizeof(filepart));
131  dirp = opendir(dirpart);
132  }
133  else
134  {
135  mutt_str_substr_copy(buf, p, dirpart, sizeof(dirpart));
136  mutt_str_strfcpy(filepart, p + 1, sizeof(filepart));
137  mutt_str_strfcpy(exp_dirpart, dirpart, sizeof(exp_dirpart));
138  mutt_expand_path(exp_dirpart, sizeof(exp_dirpart));
139  dirp = opendir(exp_dirpart);
140  }
141  }
142  else
143  {
144  /* no directory name, so assume current directory. */
145  dirpart[0] = '\0';
146  mutt_str_strfcpy(filepart, buf, sizeof(filepart));
147  dirp = opendir(".");
148  }
149  }
150 
151  if (!dirp)
152  {
153  mutt_debug(LL_DEBUG1, "%s: %s (errno %d)\n", exp_dirpart, strerror(errno), errno);
154  return -1;
155  }
156 
157  /* special case to handle when there is no filepart yet. find the first
158  * file/directory which is not "." or ".." */
159  len = mutt_str_strlen(filepart);
160  if (len == 0)
161  {
162  while ((de = readdir(dirp)))
163  {
164  if ((mutt_str_strcmp(".", de->d_name) != 0) &&
165  (mutt_str_strcmp("..", de->d_name) != 0))
166  {
167  mutt_str_strfcpy(filepart, de->d_name, sizeof(filepart));
168  init++;
169  break;
170  }
171  }
172  }
173 
174  while ((de = readdir(dirp)))
175  {
176  if (mutt_str_strncmp(de->d_name, filepart, len) == 0)
177  {
178  if (init)
179  {
180  for (i = 0; filepart[i] && de->d_name[i]; i++)
181  {
182  if (filepart[i] != de->d_name[i])
183  break;
184  }
185  filepart[i] = '\0';
186  }
187  else
188  {
189  char tmp[PATH_MAX];
190  struct stat st;
191 
192  mutt_str_strfcpy(filepart, de->d_name, sizeof(filepart));
193 
194  /* check to see if it is a directory */
195  if (dirpart[0] != '\0')
196  {
197  mutt_str_strfcpy(tmp, exp_dirpart, sizeof(tmp));
198  mutt_str_strfcpy(tmp + strlen(tmp), "/", sizeof(tmp) - strlen(tmp));
199  }
200  else
201  tmp[0] = '\0';
202  mutt_str_strfcpy(tmp + strlen(tmp), filepart, sizeof(tmp) - strlen(tmp));
203  if ((stat(tmp, &st) != -1) && (st.st_mode & S_IFDIR))
204  {
205  mutt_str_strfcpy(filepart + strlen(filepart), "/",
206  sizeof(filepart) - strlen(filepart));
207  }
208  init = 1;
209  }
210  }
211  }
212  closedir(dirp);
213 
214  if (dirpart[0] != '\0')
215  {
216  mutt_str_strfcpy(buf, dirpart, buflen);
217  if ((mutt_str_strcmp("/", dirpart) != 0) && (dirpart[0] != '=') && (dirpart[0] != '+'))
218  mutt_str_strfcpy(buf + strlen(buf), "/", buflen - strlen(buf));
219  mutt_str_strfcpy(buf + strlen(buf), filepart, buflen - strlen(buf));
220  }
221  else
222  mutt_str_strfcpy(buf, filepart, buflen);
223 
224  return init ? 0 : -1;
225 }
char * mutt_path_concat(char *d, const char *dir, const char *fname, size_t l)
Join a directory name and a filename.
Definition: path.c:330
#define NONULL(x)
Definition: string2.h:37
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2425
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
Log at debug level 2.
Definition: logging.h:57
char * mutt_path_concatn(char *dst, size_t dstlen, const char *dir, size_t dirlen, const char *fname, size_t fnamelen)
Concatenate directory and filename.
Definition: path.c:358
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:124
#define PATH_MAX
Definition: mutt.h:52
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
int imap_complete(char *buf, size_t buflen, char *path)
Try to complete an IMAP folder path.
Definition: imap.c:1441
int nntp_complete(char *buf, size_t buflen)
Auto-complete NNTP newsgroups.
Definition: complete.c:45
Log at debug level 1.
Definition: logging.h:56
WHERE char * C_Spoolfile
Config: Inbox.
Definition: globals.h:149
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:642
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
char * mutt_str_substr_copy(const char *begin, const char *end, char *buf, size_t buflen)
Copy a sub-string into a buffer.
Definition: string.c:556
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_prepare_template()

int mutt_prepare_template ( FILE *  fp,
struct Mailbox m,
struct Email e_new,
struct Email e,
bool  resend 
)

Prepare a message template.

Parameters
fpIf not NULL, file containing the template
mIf fp is NULL, the Mailbox containing the header with the template
e_newThe template is read into this Header
eEmail to recall/resend
resendSet if resending (as opposed to recalling a postponed msg) Resent messages enable header weeding, and also discard any existing Message-ID and Mail-Followup-To
Return values
0Success
-1Error

Definition at line 596 of file postpone.c.

598 {
599  struct Message *msg = NULL;
600  struct Body *b = NULL;
601  FILE *fp_body = NULL;
602  int rc = -1;
603  struct State s = { 0 };
604  SecurityFlags sec_type;
605  struct Envelope *protected_headers = NULL;
606 
607  if (!fp && !(msg = mx_msg_open(m, e->msgno)))
608  return -1;
609 
610  if (!fp)
611  fp = msg->fp;
612 
613  fp_body = fp;
614 
615  /* parse the message header and MIME structure */
616 
617  fseeko(fp, e->offset, SEEK_SET);
618  e_new->offset = e->offset;
619  /* enable header weeding for resent messages */
620  e_new->env = mutt_rfc822_read_header(fp, e_new, true, resend);
621  e_new->content->length = e->content->length;
622  mutt_parse_part(fp, e_new->content);
623 
624  /* If resending a message, don't keep message_id or mail_followup_to.
625  * Otherwise, we are resuming a postponed message, and want to keep those
626  * headers if they exist. */
627  if (resend)
628  {
629  FREE(&e_new->env->message_id);
630  FREE(&e_new->env->mail_followup_to);
631  }
632 
633  /* decrypt pgp/mime encoded messages */
634 
635  if (((WithCrypto & APPLICATION_PGP) != 0) &&
636  (sec_type = mutt_is_multipart_encrypted(e_new->content)))
637  {
638  e_new->security |= sec_type;
639  if (!crypt_valid_passphrase(sec_type))
640  goto bail;
641 
642  mutt_message(_("Decrypting message..."));
643  if ((crypt_pgp_decrypt_mime(fp, &fp_body, e_new->content, &b) == -1) || !b)
644  {
645  goto bail;
646  }
647 
648  mutt_body_free(&e_new->content);
649  e_new->content = b;
650 
651  if (b->mime_headers)
652  {
653  protected_headers = b->mime_headers;
654  b->mime_headers = NULL;
655  }
656 
658  }
659 
660  /* remove a potential multipart/signed layer - useful when
661  * resending messages */
662  if ((WithCrypto != 0) && mutt_is_multipart_signed(e_new->content))
663  {
664  e_new->security |= SEC_SIGN;
665  if (((WithCrypto & APPLICATION_PGP) != 0) &&
667  mutt_param_get(&e_new->content->parameter, "protocol"),
668  "application/pgp-signature") == 0))
669  {
670  e_new->security |= APPLICATION_PGP;
671  }
672  else if (WithCrypto & APPLICATION_SMIME)
673  e_new->security |= APPLICATION_SMIME;
674 
675  /* destroy the signature */
676  mutt_body_free(&e_new->content->parts->next);
677  e_new->content = mutt_remove_multipart(e_new->content);
678 
679  if (e_new->content->mime_headers)
680  {
681  mutt_env_free(&protected_headers);
682  protected_headers = e_new->content->mime_headers;
683  e_new->content->mime_headers = NULL;
684  }
685  }
686 
687  /* We don't need no primary multipart.
688  * Note: We _do_ preserve messages!
689  *
690  * XXX - we don't handle multipart/alternative in any
691  * smart way when sending messages. However, one may
692  * consider this a feature. */
693  if (e_new->content->type == TYPE_MULTIPART)
694  e_new->content = mutt_remove_multipart(e_new->content);
695 
696  s.fp_in = fp_body;
697 
698  struct Buffer *file = mutt_buffer_pool_get();
699 
700  /* create temporary files for all attachments */
701  for (b = e_new->content; b; b = b->next)
702  {
703  /* what follows is roughly a receive-mode variant of
704  * mutt_get_tmp_attachment () from muttlib.c */
705 
706  mutt_buffer_reset(file);
707  if (b->filename)
708  {
709  mutt_buffer_strcpy(file, b->filename);
711  }
712  else
713  {
714  /* avoid Content-Disposition: header with temporary filename */
715  b->use_disp = false;
716  }
717 
718  /* set up state flags */
719 
720  s.flags = 0;
721 
722  if (b->type == TYPE_TEXT)
723  {
724  if (mutt_str_strcasecmp("yes",
725  mutt_param_get(&b->parameter, "x-mutt-noconv")) == 0)
726  {
727  b->noconv = true;
728  }
729  else
730  {
731  s.flags |= MUTT_CHARCONV;
732  b->noconv = false;
733  }
734 
735  mutt_param_delete(&b->parameter, "x-mutt-noconv");
736  }
737 
738  mutt_adv_mktemp(file);
739  s.fp_out = mutt_file_fopen(mutt_b2s(file), "w");
740  if (!s.fp_out)
741  goto bail;
742 
743  if (((WithCrypto & APPLICATION_PGP) != 0) &&
744  ((sec_type = mutt_is_application_pgp(b)) & (SEC_ENCRYPT | SEC_SIGN)))
745  {
746  if (sec_type & SEC_ENCRYPT)
747  {
748  if (!crypt_valid_passphrase(APPLICATION_PGP))
749  goto bail;
750  mutt_message(_("Decrypting message..."));
751  }
752 
753  if (mutt_body_handler(b, &s) < 0)
754  {
755  mutt_error(_("Decryption failed"));
756  goto bail;
757  }
758 
759  if ((b == e_new->content) && !protected_headers)
760  {
761  protected_headers = b->mime_headers;
762  b->mime_headers = NULL;
763  }
764 
765  e_new->security |= sec_type;
766  b->type = TYPE_TEXT;
767  mutt_str_replace(&b->subtype, "plain");
768  mutt_param_delete(&b->parameter, "x-action");
769  }
770  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
771  ((sec_type = mutt_is_application_smime(b)) & (SEC_ENCRYPT | SEC_SIGN)))
772  {
773  if (sec_type & SEC_ENCRYPT)
774  {
775  if (!crypt_valid_passphrase(APPLICATION_SMIME))
776  goto bail;
777  crypt_smime_getkeys(e_new->env);
778  mutt_message(_("Decrypting message..."));
779  }
780 
781  if (mutt_body_handler(b, &s) < 0)
782  {
783  mutt_error(_("Decryption failed"));
784  goto bail;
785  }
786 
787  e_new->security |= sec_type;
788  b->type = TYPE_TEXT;
789  mutt_str_replace(&b->subtype, "plain");
790  }
791  else
792  mutt_decode_attachment(b, &s);
793 
794  if (mutt_file_fclose(&s.fp_out) != 0)
795  goto bail;
796 
797  mutt_str_replace(&b->filename, mutt_b2s(file));
798  b->unlink = true;
799 
801 
802  mutt_body_free(&b->parts);
803  if (b->email)
804  b->email->content = NULL; /* avoid dangling pointer */
805  }
806 
807  if (C_CryptProtectedHeadersRead && protected_headers && protected_headers->subject &&
808  (mutt_str_strcmp(e_new->env->subject, protected_headers->subject) != 0))
809  {
810  mutt_str_replace(&e_new->env->subject, protected_headers->subject);
811  }
812  mutt_env_free(&protected_headers);
813 
814  /* Fix encryption flags. */
815 
816  /* No inline if multipart. */
817  if ((WithCrypto != 0) && (e_new->security & SEC_INLINE) && e_new->content->next)
818  e_new->security &= ~SEC_INLINE;
819 
820  /* Do we even support multiple mechanisms? */
821  e_new->security &= WithCrypto | ~(APPLICATION_PGP | APPLICATION_SMIME);
822 
823  /* Theoretically, both could be set. Take the one the user wants to set by default. */
824  if ((e_new->security & APPLICATION_PGP) && (e_new->security & APPLICATION_SMIME))
825  {
826  if (C_SmimeIsDefault)
827  e_new->security &= ~APPLICATION_PGP;
828  else
829  e_new->security &= ~APPLICATION_SMIME;
830  }
831 
832  rc = 0;
833 
834 bail:
835 
836  /* that's it. */
838  if (fp_body != fp)
839  mutt_file_fclose(&fp_body);
840  if (msg)
841  mx_msg_close(m, &msg);
842 
843  if (rc == -1)
844  {
845  mutt_env_free(&e_new->env);
846  mutt_body_free(&e_new->content);
847  }
848 
849  return rc;
850 }
void mutt_decode_attachment(struct Body *b, struct State *s)
Decode an email&#39;s attachment.
Definition: handler.c:1790
void mutt_stamp_attachment(struct Body *a)
Timestamp an Attachment.
Definition: sendlib.c:1418
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1742
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:100
struct AddressList mail_followup_to
Email&#39;s &#39;mail-followup-to&#39;.
Definition: envelope.h:63
#define MUTT_CHARCONV
Do character set conversions.
Definition: state.h:36
#define mutt_message(...)
Definition: logging.h:83
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:111
struct Body * content
List of MIME parts.
Definition: email.h:92
bool noconv
Don&#39;t do character set conversion.
Definition: body.h:73
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
FILE * fp_out
File to write to.
Definition: state.h:47
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
FILE * fp_in
File to read from.
Definition: state.h:46
The body of an email.
Definition: body.h:34
WHERE bool C_SmimeIsDefault
Config: Use SMIME rather than PGP by default.
Definition: globals.h:284
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1087
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:147
char * message_id
Message ID.
Definition: envelope.h:69
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:453
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
struct Envelope * env
Envelope information.
Definition: email.h:91
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:412
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:109
char * subtype
content-type subtype
Definition: body.h:37
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
#define mutt_b2s(buf)
Definition: buffer.h:41
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:560
void mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:310
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
A local copy of an email.
Definition: mx.h:81
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Type: &#39;text/*&#39;.
Definition: mime.h:38
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:619
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:281
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
unsigned int type
content-type primary type
Definition: body.h:65
LOFF_T offset
Where in the stream does this message begin?
Definition: email.h:85
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
Definition: parse.c:1398
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:199
char * subject
Email&#39;s subject.
Definition: envelope.h:66
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
FILE * fp
pointer to the message data
Definition: mx.h:83
void mutt_adv_mktemp(struct Buffer *buf)
Create a temporary file.
Definition: muttlib.c:90
#define FREE(x)
Definition: memory.h:40
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
Keep track when processing files.
Definition: state.h:44
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1545
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:583
struct Envelope * mutt_rfc822_read_header(FILE *fp, struct Email *e, bool user_hdrs, bool weed)
parses an RFC822 header
Definition: parse.c:1128
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
struct Email * email
header information for message/rfc822
Definition: body.h:55
#define WithCrypto
Definition: ncrypt.h:160
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
return a stream pointer for a message
Definition: mx.c:1039
The header of an Email.
Definition: envelope.h:54
int msgno
Number displayed to the user.
Definition: email.h:88
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_enter_string()

int mutt_enter_string ( char *  buf,
size_t  buflen,
int  col,
CompletionFlags  flags 
)

Ask the user for a string.

Parameters
bufBuffer to store the string
buflenBuffer length
colInitial cursor position
flagsFlags, see CompletionFlags
Return values
0if input was given
-1if abort

This function is for very basic input, currently used only by the built-in editor. It does not handle screen redrawing on resizes well, because there is no active menu for the built-in editor. Most callers should prefer mutt_get_field() instead.

Definition at line 146 of file enter.c.

147 {
148  int rc;
149  struct EnterState *es = mutt_enter_state_new();
150  do
151  {
152  if (SigWinch)
153  {
154  SigWinch = 0;
156  clearok(stdscr, true);
157  }
158  rc = mutt_enter_string_full(buf, buflen, col, flags, false, NULL, NULL, es);
159  } while (rc == 1);
161  return rc;
162 }
void mutt_resize_screen(void)
Update NeoMutt&#39;s opinion about the window size (CURSES)
Definition: resize.c:98
int mutt_enter_string_full(char *buf, size_t buflen, int col, CompletionFlags flags, bool multiple, char ***files, int *numfiles, struct EnterState *state)
Ask the user for a string.
Definition: enter.c:178
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:85
Keep our place when entering a string.
Definition: enter_state.h:31
void mutt_enter_state_free(struct EnterState **ptr)
Free an EnterState.
Definition: enter.c:823
struct EnterState * mutt_enter_state_new(void)
Create a new EnterState.
Definition: enter.c:127
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_enter_string_full()

int mutt_enter_string_full ( char *  buf,
size_t  buflen,
int  col,
CompletionFlags  flags,
bool  multiple,
char ***  files,
int *  numfiles,
struct EnterState state 
)

Ask the user for a string.

Parameters
[in]bufBuffer to store the string
[in]buflenBuffer length
[in]colInitial cursor position
[in]flagsFlags, see CompletionFlags
[in]multipleAllow multiple matches
[out]filesList of files selected
[out]numfilesNumber of files selected
[out]stateCurrent state (if function is called repeatedly)
Return values
1Redraw the screen and call the function again
0Selection made
-1Aborted

Definition at line 178 of file enter.c.

181 {
182  int width = MuttMessageWindow->cols - col - 1;
183  enum EnterRedrawFlags redraw = ENTER_REDRAW_NONE;
184  bool pass = (flags & MUTT_PASS);
185  bool first = true;
186  int ch;
187  wchar_t *tempbuf = NULL;
188  size_t templen = 0;
189  enum HistoryClass hclass;
190  int rc = 0;
191  mbstate_t mbstate;
192  memset(&mbstate, 0, sizeof(mbstate));
193 
194  if (state->wbuf)
195  {
196  /* Coming back after return 1 */
197  redraw = ENTER_REDRAW_LINE;
198  first = false;
199  }
200  else
201  {
202  /* Initialise wbuf from buf */
203  state->wbuflen = 0;
204  state->lastchar = mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, 0, buf);
205  redraw = ENTER_REDRAW_INIT;
206  }
207 
208  if (flags & MUTT_FILE)
209  hclass = HC_FILE;
210  else if (flags & MUTT_EFILE)
211  hclass = HC_MBOX;
212  else if (flags & MUTT_CMD)
213  hclass = HC_CMD;
214  else if (flags & MUTT_ALIAS)
215  hclass = HC_ALIAS;
216  else if (flags & MUTT_COMMAND)
217  hclass = HC_COMMAND;
218  else if (flags & MUTT_PATTERN)
219  hclass = HC_PATTERN;
220  else
221  hclass = HC_OTHER;
222 
223  while (true)
224  {
225  if (!pass)
226  {
227  if (redraw == ENTER_REDRAW_INIT)
228  {
229  /* Go to end of line */
230  state->curpos = state->lastchar;
231  state->begin = mutt_mb_width_ceiling(
232  state->wbuf, state->lastchar,
233  mutt_mb_wcswidth(state->wbuf, state->lastchar) - width + 1);
234  }
235  if ((state->curpos < state->begin) ||
236  (mutt_mb_wcswidth(state->wbuf + state->begin, state->curpos - state->begin) >= width))
237  {
238  state->begin = mutt_mb_width_ceiling(
239  state->wbuf, state->lastchar,
240  mutt_mb_wcswidth(state->wbuf, state->curpos) - (width / 2));
241  }
243  int w = 0;
244  for (size_t i = state->begin; i < state->lastchar; i++)
245  {
246  w += mutt_mb_wcwidth(state->wbuf[i]);
247  if (w > width)
248  break;
249  my_addwch(state->wbuf[i]);
250  }
253  col + mutt_mb_wcswidth(state->wbuf + state->begin,
254  state->curpos - state->begin));
255  }
256  mutt_refresh();
257 
258  ch = km_dokey(MENU_EDITOR);
259  if (ch < 0)
260  {
261  rc = (SigWinch && (ch == -2)) ? 1 : -1;
262  goto bye;
263  }
264 
265  if (ch != OP_NULL)
266  {
267  first = false;
268  if ((ch != OP_EDITOR_COMPLETE) && (ch != OP_EDITOR_COMPLETE_QUERY))
269  state->tabs = 0;
270  redraw = ENTER_REDRAW_LINE;
271  switch (ch)
272  {
273  case OP_EDITOR_HISTORY_UP:
274  state->curpos = state->lastchar;
275  if (mutt_hist_at_scratch(hclass))
276  {
277  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
278  mutt_hist_save_scratch(hclass, buf);
279  }
280  replace_part(state, 0, mutt_hist_prev(hclass));
281  redraw = ENTER_REDRAW_INIT;
282  break;
283 
284  case OP_EDITOR_HISTORY_DOWN:
285  state->curpos = state->lastchar;
286  if (mutt_hist_at_scratch(hclass))
287  {
288  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
289  mutt_hist_save_scratch(hclass, buf);
290  }
291  replace_part(state, 0, mutt_hist_next(hclass));
292  redraw = ENTER_REDRAW_INIT;
293  break;
294 
295  case OP_EDITOR_HISTORY_SEARCH:
296  state->curpos = state->lastchar;
297  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
298  mutt_hist_complete(buf, buflen, hclass);
299  replace_part(state, 0, buf);
300  rc = 1;
301  goto bye;
302  break;
303 
304  case OP_EDITOR_BACKSPACE:
305  if (state->curpos == 0)
306  {
307  // Pressing backspace when no text is in the command prompt should exit the prompt
308  if (state->lastchar == 0)
309  goto bye;
310  // Pressing backspace with text in the command prompt should just beep
311  BEEP();
312  }
313  else
314  {
315  size_t i = state->curpos;
316  while ((i > 0) && COMB_CHAR(state->wbuf[i - 1]))
317  i--;
318  if (i > 0)
319  i--;
320  memmove(state->wbuf + i, state->wbuf + state->curpos,
321  (state->lastchar - state->curpos) * sizeof(wchar_t));
322  state->lastchar -= state->curpos - i;
323  state->curpos = i;
324  }
325  break;
326 
327  case OP_EDITOR_BOL:
328  state->curpos = 0;
329  break;
330 
331  case OP_EDITOR_EOL:
332  redraw = ENTER_REDRAW_INIT;
333  break;
334 
335  case OP_EDITOR_KILL_LINE:
336  state->curpos = 0;
337  state->lastchar = 0;
338  break;
339 
340  case OP_EDITOR_KILL_EOL:
341  state->lastchar = state->curpos;
342  break;
343 
344  case OP_EDITOR_BACKWARD_CHAR:
345  if (state->curpos == 0)
346  BEEP();
347  else
348  {
349  while (state->curpos && COMB_CHAR(state->wbuf[state->curpos - 1]))
350  state->curpos--;
351  if (state->curpos)
352  state->curpos--;
353  }
354  break;
355 
356  case OP_EDITOR_FORWARD_CHAR:
357  if (state->curpos == state->lastchar)
358  BEEP();
359  else
360  {
361  state->curpos++;
362  while ((state->curpos < state->lastchar) &&
363  COMB_CHAR(state->wbuf[state->curpos]))
364  {
365  state->curpos++;
366  }
367  }
368  break;
369 
370  case OP_EDITOR_BACKWARD_WORD:
371  if (state->curpos == 0)
372  BEEP();
373  else
374  {
375  while (state->curpos && iswspace(state->wbuf[state->curpos - 1]))
376  state->curpos--;
377  while (state->curpos && !iswspace(state->wbuf[state->curpos - 1]))
378  state->curpos--;
379  }
380  break;
381 
382  case OP_EDITOR_FORWARD_WORD:
383  if (state->curpos == state->lastchar)
384  BEEP();
385  else
386  {
387  while ((state->curpos < state->lastchar) &&
388  iswspace(state->wbuf[state->curpos]))
389  {
390  state->curpos++;
391  }
392  while ((state->curpos < state->lastchar) &&
393  !iswspace(state->wbuf[state->curpos]))
394  {
395  state->curpos++;
396  }
397  }
398  break;
399 
400  case OP_EDITOR_CAPITALIZE_WORD:
401  case OP_EDITOR_UPCASE_WORD:
402  case OP_EDITOR_DOWNCASE_WORD:
403  if (state->curpos == state->lastchar)
404  {
405  BEEP();
406  break;
407  }
408  while (state->curpos && !iswspace(state->wbuf[state->curpos]))
409  state->curpos--;
410  while ((state->curpos < state->lastchar) && iswspace(state->wbuf[state->curpos]))
411  state->curpos++;
412  while ((state->curpos < state->lastchar) &&
413  !iswspace(state->wbuf[state->curpos]))
414  {
415  if (ch == OP_EDITOR_DOWNCASE_WORD)
416  state->wbuf[state->curpos] = towlower(state->wbuf[state->curpos]);
417  else
418  {
419  state->wbuf[state->curpos] = towupper(state->wbuf[state->curpos]);
420  if (ch == OP_EDITOR_CAPITALIZE_WORD)
421  ch = OP_EDITOR_DOWNCASE_WORD;
422  }
423  state->curpos++;
424  }
425  break;
426 
427  case OP_EDITOR_DELETE_CHAR:
428  if (state->curpos == state->lastchar)
429  BEEP();
430  else
431  {
432  size_t i = state->curpos;
433  while ((i < state->lastchar) && COMB_CHAR(state->wbuf[i]))
434  i++;
435  if (i < state->lastchar)
436  i++;
437  while ((i < state->lastchar) && COMB_CHAR(state->wbuf[i]))
438  i++;
439  memmove(state->wbuf + state->curpos, state->wbuf + i,
440  (state->lastchar - i) * sizeof(wchar_t));
441  state->lastchar -= i - state->curpos;
442  }
443  break;
444 
445  case OP_EDITOR_KILL_WORD:
446  /* delete to beginning of word */
447  if (state->curpos != 0)
448  {
449  size_t i = state->curpos;
450  while (i && iswspace(state->wbuf[i - 1]))
451  i--;
452  if (i > 0)
453  {
454  if (iswalnum(state->wbuf[i - 1]))
455  {
456  for (--i; (i > 0) && iswalnum(state->wbuf[i - 1]); i--)
457  ;
458  }
459  else
460  i--;
461  }
462  memmove(state->wbuf + i, state->wbuf + state->curpos,
463  (state->lastchar - state->curpos) * sizeof(wchar_t));
464  state->lastchar += i - state->curpos;
465  state->curpos = i;
466  }
467  break;
468 
469  case OP_EDITOR_KILL_EOW:
470  {
471  /* delete to end of word */
472 
473  /* first skip over whitespace */
474  size_t i;
475  for (i = state->curpos; (i < state->lastchar) && iswspace(state->wbuf[i]); i++)
476  ;
477 
478  /* if there are any characters left.. */
479  if (i < state->lastchar)
480  {
481  /* if the current character is alphanumeric.. */
482  if (iswalnum(state->wbuf[i]))
483  {
484  /* skip over the rest of the word consistent of only alphanumerics */
485  for (; (i < state->lastchar) && iswalnum(state->wbuf[i]); i++)
486  ;
487  }
488  else
489  {
490  /* skip over one non-alphanumeric character */
491  i++;
492  }
493  }
494 
495  memmove(state->wbuf + state->curpos, state->wbuf + i,
496  (state->lastchar - i) * sizeof(wchar_t));
497  state->lastchar += state->curpos - i;
498  break;
499  }
500 
501  case OP_EDITOR_MAILBOX_CYCLE:
502  if (flags & MUTT_EFILE)
503  {
504  first = true; /* clear input if user types a real key later */
505  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
506  mutt_mailbox_next(Context ? Context->mailbox : NULL, buf, buflen);
507  state->curpos = state->lastchar =
508  mutt_mb_mbstowcs(&state->wbuf, &state->wbuflen, 0, buf);
509  break;
510  }
511  else if (!(flags & MUTT_FILE))
512  {
513  goto self_insert;
514  }
515  /* fallthrough */
516 
517  case OP_EDITOR_COMPLETE:
518  case OP_EDITOR_COMPLETE_QUERY:
519  state->tabs++;
520  if (flags & MUTT_CMD)
521  {
522  size_t i;
523  for (i = state->curpos;
524  (i > 0) && !mutt_mb_is_shell_char(state->wbuf[i - 1]); i--)
525  {
526  }
527  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
528  if (tempbuf && (templen == (state->lastchar - i)) &&
529  (memcmp(tempbuf, state->wbuf + i, (state->lastchar - i) * sizeof(wchar_t)) == 0))
530  {
531  mutt_select_file(buf, buflen, (flags & MUTT_EFILE) ? MUTT_SEL_FOLDER : MUTT_SEL_NO_FLAGS,
532  NULL, NULL);
533  if (buf[0] != '\0')
534  replace_part(state, i, buf);
535  rc = 1;
536  goto bye;
537  }
538  if (mutt_complete(buf, buflen) == 0)
539  {
540  templen = state->lastchar - i;
541  mutt_mem_realloc(&tempbuf, templen * sizeof(wchar_t));
542  }
543  else
544  BEEP();
545 
546  replace_part(state, i, buf);
547  }
548  else if ((flags & MUTT_ALIAS) && (ch == OP_EDITOR_COMPLETE))
549  {
550  /* invoke the alias-menu to get more addresses */
551  size_t i;
552  for (i = state->curpos;
553  (i > 0) && (state->wbuf[i - 1] != ',') && (state->wbuf[i - 1] != ':'); i--)
554  {
555  }
556  for (; (i < state->lastchar) && (state->wbuf[i] == ' '); i++)
557  ;
558  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
559  int rc2 = mutt_alias_complete(buf, buflen);
560  replace_part(state, i, buf);
561  if (rc2 != 1)
562  {
563  rc = 1;
564  goto bye;
565  }
566  break;
567  }
568  else if ((flags & MUTT_LABEL) && (ch == OP_EDITOR_COMPLETE))
569  {
570  size_t i;
571  for (i = state->curpos;
572  (i > 0) && (state->wbuf[i - 1] != ',') && (state->wbuf[i - 1] != ':'); i--)
573  {
574  }
575  for (; (i < state->lastchar) && (state->wbuf[i] == ' '); i++)
576  ;
577  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
578  int rc2 = mutt_label_complete(buf, buflen, state->tabs);
579  replace_part(state, i, buf);
580  if (rc2 != 1)
581  {
582  rc = 1;
583  goto bye;
584  }
585  break;
586  }
587  else if ((flags & MUTT_PATTERN) && (ch == OP_EDITOR_COMPLETE))
588  {
589  size_t i;
590  for (i = state->curpos; (i > 0) && (state->wbuf[i - 1] != '~'); i--)
591  ;
592  if ((i > 0) && (i < state->curpos) && (state->wbuf[i - 1] == '~') &&
593  (state->wbuf[i] == 'y'))
594  {
595  i++;
596  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
597  int rc2 = mutt_label_complete(buf, buflen, state->tabs);
598  replace_part(state, i, buf);
599  if (rc2 != 1)
600  {
601  rc = 1;
602  goto bye;
603  }
604  }
605  else
606  goto self_insert;
607  break;
608  }
609  else if ((flags & MUTT_ALIAS) && (ch == OP_EDITOR_COMPLETE_QUERY))
610  {
611  size_t i = state->curpos;
612  if (i != 0)
613  {
614  for (; (i > 0) && (state->wbuf[i - 1] != ','); i--)
615  ;
616  for (; (i < state->curpos) && (state->wbuf[i] == ' '); i++)
617  ;
618  }
619 
620  mutt_mb_wcstombs(buf, buflen, state->wbuf + i, state->curpos - i);
621  mutt_query_complete(buf, buflen);
622  replace_part(state, i, buf);
623 
624  rc = 1;
625  goto bye;
626  }
627  else if (flags & MUTT_COMMAND)
628  {
629  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
630  size_t i = strlen(buf);
631  if ((i != 0) && (buf[i - 1] == '=') &&
632  (mutt_var_value_complete(buf, buflen, i) != 0))
633  {
634  state->tabs = 0;
635  }
636  else if (mutt_command_complete(buf, buflen, i, state->tabs) == 0)
637  BEEP();
638  replace_part(state, 0, buf);
639  }
640  else if (flags & (MUTT_FILE | MUTT_EFILE))
641  {
642  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
643 
644  /* see if the path has changed from the last time */
645  if ((!tempbuf && !state->lastchar) ||
646  (tempbuf && (templen == state->lastchar) &&
647  (memcmp(tempbuf, state->wbuf, state->lastchar * sizeof(wchar_t)) == 0)))
648  {
649  mutt_select_file(buf, buflen,
650  ((flags & MUTT_EFILE) ? MUTT_SEL_FOLDER : MUTT_SEL_NO_FLAGS) |
651  (multiple ? MUTT_SEL_MULTI : MUTT_SEL_NO_FLAGS),
652  files, numfiles);
653  if (buf[0] != '\0')
654  {
655  mutt_pretty_mailbox(buf, buflen);
656  if (!pass)
657  mutt_hist_add(hclass, buf, true);
658  rc = 0;
659  goto bye;
660  }
661 
662  /* file selection cancelled */
663  rc = 1;
664  goto bye;
665  }
666 
667  if (mutt_complete(buf, buflen) == 0)
668  {
669  templen = state->lastchar;
670  mutt_mem_realloc(&tempbuf, templen * sizeof(wchar_t));
671  memcpy(tempbuf, state->wbuf, templen * sizeof(wchar_t));
672  }
673  else
674  BEEP(); /* let the user know that nothing matched */
675  replace_part(state, 0, buf);
676  }
677 #ifdef USE_NOTMUCH
678  else if (flags & MUTT_NM_QUERY)
679  {
680  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
681  size_t len = strlen(buf);
682  if (!mutt_nm_query_complete(buf, buflen, len, state->tabs))
683  BEEP();
684 
685  replace_part(state, 0, buf);
686  }
687  else if (flags & MUTT_NM_TAG)
688  {
689  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->curpos);
690  if (!mutt_nm_tag_complete(buf, buflen, state->tabs))
691  BEEP();
692 
693  replace_part(state, 0, buf);
694  }
695 
696 #endif
697  else
698  goto self_insert;
699  break;
700 
701  case OP_EDITOR_QUOTE_CHAR:
702  {
703  struct KeyEvent event;
704  do
705  {
706  event = mutt_getch();
707  } while (event.ch == -2);
708  if (event.ch >= 0)
709  {
710  LastKey = event.ch;
711  goto self_insert;
712  }
713  break;
714  }
715 
716  case OP_EDITOR_TRANSPOSE_CHARS:
717  if (state->lastchar < 2)
718  BEEP();
719  else
720  {
721  wchar_t t;
722 
723  if (state->curpos == 0)
724  state->curpos = 2;
725  else if (state->curpos < state->lastchar)
726  state->curpos++;
727 
728  t = state->wbuf[state->curpos - 2];
729  state->wbuf[state->curpos - 2] = state->wbuf[state->curpos - 1];
730  state->wbuf[state->curpos - 1] = t;
731  }
732  break;
733 
734  default:
735  BEEP();
736  }
737  }
738  else
739  {
740  self_insert:
741  state->tabs = 0;
742  wchar_t wc;
743  /* use the raw keypress */
744  ch = LastKey;
745 
746  /* quietly ignore all other function keys */
747  if (ch & ~0xff)
748  continue;
749 
750  /* gather the octets into a wide character */
751  {
752  char c = ch;
753  size_t k = mbrtowc(&wc, &c, 1, &mbstate);
754  if (k == (size_t)(-2))
755  continue;
756  else if ((k != 0) && (k != 1))
757  {
758  memset(&mbstate, 0, sizeof(mbstate));
759  continue;
760  }
761  }
762 
763  if (first && (flags & MUTT_CLEAR))
764  {
765  first = false;
766  if (IsWPrint(wc)) /* why? */
767  {
768  state->curpos = 0;
769  state->lastchar = 0;
770  }
771  }
772 
773  if ((wc == '\r') || (wc == '\n'))
774  {
775  /* Convert from wide characters */
776  mutt_mb_wcstombs(buf, buflen, state->wbuf, state->lastchar);
777  if (!pass)
778  mutt_hist_add(hclass, buf, true);
779 
780  if (multiple)
781  {
782  char **tfiles = NULL;
783  *numfiles = 1;
784  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
785  mutt_expand_path(buf, buflen);
786  tfiles[0] = mutt_str_strdup(buf);
787  *files = tfiles;
788  }
789  rc = 0;
790  goto bye;
791  }
792  else if (wc && ((wc < ' ') || IsWPrint(wc))) /* why? */
793  {
794  if (state->lastchar >= state->wbuflen)
795  {
796  state->wbuflen = state->lastchar + 20;
797  mutt_mem_realloc(&state->wbuf, state->wbuflen * sizeof(wchar_t));
798  }
799  memmove(state->wbuf + state->curpos + 1, state->wbuf + state->curpos,
800  (state->lastchar - state->curpos) * sizeof(wchar_t));
801  state->wbuf[state->curpos++] = wc;
802  state->lastchar++;
803  }
804  else
805  {
806  mutt_flushinp();
807  BEEP();
808  }
809  }
810  }
811 
812 bye:
813 
814  mutt_hist_reset_state(hclass);
815  FREE(&tempbuf);
816  return rc;
817 }
int km_dokey(enum MenuType menu)
Determine what a keypress should do.
Definition: keymap.c:571
The "current" mailbox.
Definition: context.h:36
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
wchar_t * wbuf
Definition: enter_state.h:33
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:70
Miscellaneous strings.
Definition: history.h:46
char * mutt_hist_next(enum HistoryClass hclass)
Get the next string in a History.
Definition: history.c:516
#define MUTT_ALIAS
Do alias "completion" by calling up the alias-menu.
Definition: mutt.h:65
#define IsWPrint(wc)
Definition: mbyte.h:39
NeoMutt commands.
Definition: history.h:43
HistoryClass
Type to differentiate different histories.
Definition: history.h:39
void mutt_hist_complete(char *buf, size_t buflen, enum HistoryClass hclass)
Complete a string from a history list.
Definition: mutt_history.c:134
int mutt_label_complete(char *buf, size_t buflen, int numtabs)
Complete a label name.
Definition: init.c:3527
#define MUTT_LABEL
Do label completion.
Definition: mutt.h:73
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:804
void mutt_window_clrtoeol(struct MuttWindow *win)
Clear to the end of the line.
Definition: mutt_window.c:107
void mutt_hist_add(enum HistoryClass hclass, const char *str, bool save)
Add a string to a history.
Definition: history.c:479
size_t wbuflen
Definition: enter_state.h:34
bool mutt_nm_tag_complete(char *buf, size_t buflen, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:3648
#define MUTT_NM_QUERY
Notmuch query mode.
Definition: mutt.h:74
Mailboxes.
Definition: history.h:47
int mutt_command_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete a command name.
Definition: init.c:3357
int ch
raw key pressed
Definition: mutt_curses.h:110
#define MUTT_SEL_NO_FLAGS
No flags are set.
Definition: browser.h:44
size_t mutt_mb_width_ceiling(const wchar_t *s, size_t n, int w1)
Keep the end of the string on-screen.
Definition: mbyte.c:217
bool mutt_nm_query_complete(char *buf, size_t buflen, int pos, int numtabs)
Complete to the nearest notmuch tag.
Definition: init.c:3591
External commands.
Definition: history.h:41
#define MUTT_PATTERN
Pattern mode - only used for history classes.
Definition: mutt.h:72
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:47
void mutt_mb_wcstombs(char *dest, size_t dlen, const wchar_t *src, size_t slen)
Convert a string from wide to multibyte characters.
Definition: mbyte.c:237
Aliases.
Definition: history.h:42
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:128
struct Mailbox * mailbox
Definition: context.h:50
#define MUTT_NM_TAG
Notmuch tag +/- mode.
Definition: mutt.h:75
int LastKey
contains the last key the user pressed
Definition: keymap.c:145
int mutt_mb_wcswidth(const wchar_t *s, size_t n)
Measure the screen width of a string.
Definition: mbyte.c:196
#define MUTT_COMMAND
Do command completion.
Definition: mutt.h:71
WHERE SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.h:85
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Patterns.
Definition: history.h:45
#define MUTT_CMD
Do completion on previous word.
Definition: mutt.h:68
size_t begin
Definition: enter_state.h:37
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:94
Nothing to redraw.
Definition: enter.c:59
#define MUTT_PASS
Password mode (no echo)
Definition: mutt.h:69
bool mutt_hist_at_scratch(enum HistoryClass hclass)
Is the current History position at the &#39;scratch&#39; place?
Definition: history.c:634
#define BEEP()
Definition: mutt_curses.h:80
void mutt_select_file(char *file, size_t filelen, SelectFileFlags flags, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:2187
void mutt_hist_save_scratch(enum HistoryClass hclass, const char *str)
Save a temporary string to the History.
Definition: history.c:651
void mutt_mailbox_next(struct Mailbox *m_cur, char *s, size_t slen)
incoming folders completion routine
Definition: mutt_mailbox.c:334
int mutt_query_complete(char *buf, size_t buflen)
Perform auto-complete using an Address Query.
Definition: query.c:613
static int my_addwch(wchar_t wc)
Display one wide character on screen.
Definition: enter.c:73
An event such as a keypress.
Definition: mutt_curses.h:108
size_t curpos
Definition: enter_state.h:36
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:612
int mutt_alias_complete(char *buf, size_t buflen)
alias completion routine
Definition: alias.c:604
struct KeyEvent mutt_getch(void)
Read a character from the input buffer.
Definition: curs_lib.c:175
#define COMB_CHAR(wc)
Definition: enter.c:65
static void replace_part(struct EnterState *state, size_t from, char *buf)
Search and replace on a buffer.
Definition: enter.c:91
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:46
#define MUTT_FILE
Do file completion.
Definition: mutt.h:66
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:188
char * mutt_hist_prev(enum HistoryClass hclass)
Get the previous string in a History.
Definition: history.c:543
int mutt_complete(char *buf, size_t buflen)
Attempt to complete a partial pathname.
Definition: complete.c:57
EnterRedrawFlags
redraw flags for mutt_enter_string_full()
Definition: enter.c:57
bool mutt_mb_is_shell_char(wchar_t ch)
Is character not typically part of a pathname.
Definition: mbyte.c:344
size_t mutt_mb_mbstowcs(wchar_t **pwbuf, size_t *pwbuflen, size_t i, char *buf)
Convert a string from multibyte to wide characters.
Definition: mbyte.c:295
Go to end of line and redraw.
Definition: enter.c:60
#define MUTT_EFILE
Do file completion, plus incoming folders.
Definition: mutt.h:67
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
Redraw entire line.
Definition: enter.c:61
#define FREE(x)
Definition: memory.h:40
int mutt_mb_wcwidth(wchar_t wc)
Measure the screen width of a character.
Definition: mbyte.c:178
Text entry area.
Definition: keymap.h:65
struct MuttWindow * MuttMessageWindow
Message Window.
Definition: mutt_window.c:42
void mutt_hist_reset_state(enum HistoryClass hclass)
Move the &#39;current&#39; position to the end of the History.
Definition: history.c:570
size_t lastchar
Definition: enter_state.h:35
Files.
Definition: history.h:44
int mutt_var_value_complete(char *buf, size_t buflen, int pos)
Complete a variable/value.
Definition: init.c:3701
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_postponed()

int mutt_get_postponed ( struct Context ctx,
struct Email hdr,
struct Email **  cur,
char *  fcc,
size_t  fcclen 
)

Recall a postponed message.

Parameters
[in]ctxContext info, used when recalling a message to which we reply
[in]hdrenvelope/attachment info for recalled message
[out]curif message was a reply, 'cur' is set to the message which 'hdr' is in reply to
[in]fccfcc for the recalled message
[in]fcclenmax length of fcc
Return values
-1Error/no messages
0Normal exit
SEND_REPLYRecalled message is a reply

Definition at line 290 of file postpone.c.

292 {
293  if (!C_Postponed)
294  return -1;
295 
296  struct Email *e = NULL;
297  int rc = SEND_POSTPONED;
298  const char *p = NULL;
299  struct Context *ctx_post = NULL;
300 
301  struct Mailbox *m = mx_path_resolve(C_Postponed);
302  if (ctx->mailbox == m)
303  ctx_post = ctx;
304  else
305  ctx_post = mx_mbox_open(m, MUTT_NOSORT);
306 
307  if (!ctx_post)
308  {
309  PostCount = 0;
310  mutt_error(_("No postponed messages"));
311  mailbox_free(&m);
312  return -1;
313  }
314 
315  if (ctx_post->mailbox->msg_count == 0)
316  {
317  PostCount = 0;
318  if (ctx_post == ctx)
319  ctx_post = NULL;
320  else
321  mx_mbox_close(&ctx_post);
322  mutt_error(_("No postponed messages"));
323  return -1;
324  }
325 
326  if (ctx_post->mailbox->msg_count == 1)
327  {
328  /* only one message, so just use that one. */
329  e = ctx_post->mailbox->emails[0];
330  }
331  else if (!(e = select_msg(ctx_post)))
332  {
333  if (ctx_post == ctx)
334  ctx_post = NULL;
335  else
336  mx_mbox_close(&ctx_post);
337  return -1;
338  }
339 
340  if (mutt_prepare_template(NULL, ctx_post->mailbox, hdr, e, false) < 0)
341  {
342  if (ctx_post != ctx)
343  {
344  mx_fastclose_mailbox(ctx_post->mailbox);
345  FREE(&ctx_post);
346  }
347  return -1;
348  }
349 
350  /* finished with this message, so delete it. */
351  mutt_set_flag(ctx_post->mailbox, e, MUTT_DELETE, true);
352  mutt_set_flag(ctx_post->mailbox, e, MUTT_PURGE, true);
353 
354  /* update the count for the status display */
355  PostCount = ctx_post->mailbox->msg_count - ctx_post->mailbox->msg_deleted;
356 
357  /* avoid the "purge deleted messages" prompt */
358  int opt_delete = C_Delete;
359  C_Delete = MUTT_YES;
360  if (ctx_post == ctx)
361  ctx_post = NULL;
362  else
363  mx_mbox_close(&ctx_post);
364  C_Delete = opt_delete;
365 
366  struct ListNode *np = NULL, *tmp = NULL;
367  STAILQ_FOREACH_SAFE(np, &hdr->env->userhdrs, entries, tmp)
368  {
369  size_t plen = mutt_str_startswith(np->data, "X-Mutt-References:", CASE_IGNORE);
370  if (plen)
371  {
372  /* if a mailbox is currently open, look to see if the original message
373  * the user attempted to reply to is in this mailbox */
374  p = mutt_str_skip_email_wsp(np->data + plen);
375  if (!ctx->mailbox->id_hash)
377  *cur = mutt_hash_find(ctx->mailbox->id_hash, p);
378 
379  if (*cur)
380  rc |= SEND_REPLY;
381  }
382  else if ((plen = mutt_str_startswith(np->data, "X-Mutt-Fcc:", CASE_IGNORE)))
383  {
384  p = mutt_str_skip_email_wsp(np->data + plen);
385  mutt_str_strfcpy(fcc, p, fcclen);
386  mutt_pretty_mailbox(fcc, fcclen);
387 
388  /* note that x-mutt-fcc was present. we do this because we want to add a
389  * default fcc if the header was missing, but preserve the request of the
390  * user to not make a copy if the header field is present, but empty.
391  * see http://dev.mutt.org/trac/ticket/3653 */
392  rc |= SEND_POSTPONED_FCC;
393  }
394  else if (((WithCrypto & APPLICATION_PGP) != 0) &&
395  /* this is generated by old neomutt versions */
396  (mutt_str_startswith(np->data, "Pgp:", CASE_MATCH) ||
397  /* this is the new way */
398  mutt_str_startswith(np->data, "X-Mutt-PGP:", CASE_MATCH)))
399  {
400  hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, true, APPLICATION_PGP);
401  hdr->security |= APPLICATION_PGP;
402  }
403  else if (((WithCrypto & APPLICATION_SMIME) != 0) &&
404  mutt_str_startswith(np->data, "X-Mutt-SMIME:", CASE_MATCH))
405  {
406  hdr->security = mutt_parse_crypt_hdr(strchr(np->data, ':') + 1, true, APPLICATION_SMIME);
407  hdr->security |= APPLICATION_SMIME;
408  }
409 
410 #ifdef MIXMASTER
411  else if (mutt_str_startswith(np->data, "X-Mutt-Mix:", CASE_MATCH))
412  {
413  mutt_list_free(&hdr->chain);
414 
415  char *t = strtok(np->data + 11, " \t\n");
416  while (t)
417  {
418  mutt_list_insert_tail(&hdr->chain, mutt_str_strdup(t));
419  t = strtok(NULL, " \t\n");
420  }
421  }
422 #endif
423 
424  else
425  {
426  // skip header removal
427  continue;
428  }
429 
430  // remove the header
431  STAILQ_REMOVE(&hdr->env->userhdrs, np, ListNode, entries);
432  FREE(&np->data);
433  FREE(&np);
434  }
435 
438 
439  return rc;
440 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
The "current" mailbox.
Definition: context.h:36
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:400
int msg_count
Total number of messages.
Definition: mailbox.h:102
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:69
#define SEND_POSTPONED_FCC
Used by mutt_get_postponed() to signal that the x-mutt-fcc header field was present.
Definition: send.h:96
The envelope/body of an email.
Definition: email.h:39
static struct Email * select_msg(struct Context *ctx)
Create a Menu to select a postponed message.
Definition: postpone.c:215
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:107
int mx_mbox_close(struct Context **ptr)
Save changes and close mailbox.
Definition: mx.c:558
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:39
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
void * mutt_hash_find(const struct Hash *table, const char *strkey)
Find the HashElem data in a Hash table element using a key.
Definition: hash.c:379
WHERE unsigned char C_Delete
Config: Really delete messages, when the mailbox is closed.
Definition: globals.h:187
struct ListHead userhdrs
user defined headers
Definition: envelope.h:83
#define _(a)
Definition: message.h:28
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:254
Messages to be purged (bypass trash)
Definition: mutt.h:106
Match case when comparing strings.
Definition: string2.h:67
#define SEND_POSTPONED
Recall a postponed email.
Definition: send.h:91
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:123
struct Mailbox * mailbox
Definition: context.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:55
struct Envelope * env
Envelope information.
Definition: email.h:91
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:392
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:360
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:280
Messages to be deleted.
Definition: mutt.h:104
A mailbox.
Definition: mailbox.h:92
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mx.h:51
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
static short PostCount
Definition: postpone.c:74
Ignore case when comparing strings.
Definition: string2.h:68
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:776
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:612
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
#define SEND_REPLY
Reply to sender.
Definition: send.h:87
struct Hash * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1437
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
SecurityFlags mutt_parse_crypt_hdr(const char *p, bool set_empty_signas, SecurityFlags crypt_app)
Parse a crypto header string.
Definition: postpone.c:449
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1030
char * data
String.
Definition: list.h:35
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
XXX.
Definition: mx.c:1539
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:139
A List node for strings.
Definition: list.h:33
#define WithCrypto
Definition: ncrypt.h:160
int mutt_prepare_template(FILE *fp, struct Mailbox *m, struct Email *e_new, struct Email *e, bool resend)
Prepare a message template.
Definition: postpone.c:596
struct Hash * id_hash
Hash table by msg id.
Definition: mailbox.h:138
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_crypt_hdr()

SecurityFlags mutt_parse_crypt_hdr ( const char *  p,
bool  set_empty_signas,
SecurityFlags  crypt_app 
)

Parse a crypto header string.

Parameters
pHeader string to parse
set_empty_signasAllow an empty "Sign as"
crypt_appApp, e.g. APPLICATION_PGP
Return values
numSecurityFlags, see SecurityFlags

Definition at line 449 of file postpone.c.

450 {
451  char smime_cryptalg[1024] = { 0 };
452  char sign_as[1024] = { 0 };
453  char *q = NULL;
454  SecurityFlags flags = SEC_NO_FLAGS;
455 
456  if (!WithCrypto)
457  return SEC_NO_FLAGS;
458 
460  for (; p[0] != '\0'; p++)
461  {
462  switch (p[0])
463  {
464  case 'c':
465  case 'C':
466  q = smime_cryptalg;
467 
468  if (p[1] == '<')
469  {
470  for (p += 2; (p[0] != '\0') && (p[0] != '>') &&
471  (q < (smime_cryptalg + sizeof(smime_cryptalg) - 1));
472  *q++ = *p++)
473  {
474  }
475 
476  if (p[0] != '>')
477  {
478  mutt_error(_("Illegal S/MIME header"));
479  return SEC_NO_FLAGS;
480  }
481  }
482 
483  *q = '\0';
484  break;
485 
486  case 'e':
487  case 'E':
488  flags |= SEC_ENCRYPT;
489  break;
490 
491  case 'i':
492  case 'I':
493  flags |= SEC_INLINE;
494  break;
495 
496  /* This used to be the micalg parameter.
497  *
498  * It's no longer needed, so we just skip the parameter in order
499  * to be able to recall old messages. */
500  case 'm':
501  case 'M':
502  if (p[1] == '<')
503  {
504  for (p += 2; (p[0] != '\0') && (p[0] != '>'); p++)
505  ;
506  if (p[0] != '>')
507  {
508  mutt_error(_("Illegal crypto header"));
509  return SEC_NO_FLAGS;
510  }
511  }
512 
513  break;
514 
515  case 'o':
516  case 'O':
517  flags |= SEC_OPPENCRYPT;
518  break;
519 
520  case 'a':
521  case 'A':
522 #ifdef USE_AUTOCRYPT
523  flags |= SEC_AUTOCRYPT;
524 #endif
525  break;
526 
527  case 'z':
528  case 'Z':
529 #ifdef USE_AUTOCRYPT
530  flags |= SEC_AUTOCRYPT_OVERRIDE;
531 #endif
532  break;
533 
534  case 's':
535  case 'S':
536  flags |= SEC_SIGN;
537  q = sign_as;
538 
539  if (p[1] == '<')
540  {
541  for (p += 2;
542  (p[0] != '\0') && (*p != '>') && (q < (sign_as + sizeof(sign_as) - 1));
543  *q++ = *p++)
544  {
545  }
546 
547  if (p[0] != '>')
548  {
549  mutt_error(_("Illegal crypto header"));
550  return SEC_NO_FLAGS;
551  }
552  }
553 
554  q[0] = '\0';
555  break;
556 
557  default:
558  mutt_error(_("Illegal crypto header"));
559  return SEC_NO_FLAGS;
560  }
561  }
562 
563  /* the cryptalg field must not be empty */
564  if (((WithCrypto & APPLICATION_SMIME) != 0) && *smime_cryptalg)
565  mutt_str_replace(&C_SmimeEncryptWith, smime_cryptalg);
566 
567  /* Set {Smime,Pgp}SignAs, if desired. */
568 
569  if (((WithCrypto & APPLICATION_PGP) != 0) && (crypt_app == APPLICATION_PGP) &&
570  (flags & SEC_SIGN) && (set_empty_signas || *sign_as))
571  {
572  mutt_str_replace(&C_PgpSignAs, sign_as);
573  }
574 
575  if (((WithCrypto & APPLICATION_SMIME) != 0) && (crypt_app == APPLICATION_SMIME) &&
576  (flags & SEC_SIGN) && (set_empty_signas || *sign_as))
577  {
578  mutt_str_replace(&C_SmimeSignAs, sign_as);
579  }
580 
581  return flags;
582 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
#define SEC_AUTOCRYPT_OVERRIDE
Indicates manual set/unset of encryption.
Definition: ncrypt.h:132
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
WHERE char * C_SmimeEncryptWith
Config: Algorithm for encryption.
Definition: globals.h:173
char * mutt_str_skip_email_wsp(const char *s)
Skip over whitespace as defined by RFC5322.
Definition: string.c:776
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define mutt_error(...)
Definition: logging.h:84
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
WHERE char * C_PgpSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:168
WHERE char * C_SmimeSignAs
Config: Use this alternative key for signing messages.
Definition: globals.h:172
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_num_postponed()

int mutt_num_postponed ( struct Mailbox m,
bool  force 
)

Return the number of postponed messages.

Parameters
mcurrently selected mailbox
force
  • false Use a cached value if costly to get a fresh count (IMAP)
  • true Force check
Return values
numPostponed messages

Definition at line 85 of file postpone.c.

86 {
87  struct stat st;
88 
89  static time_t LastModify = 0;
90  static char *OldPostponed = NULL;
91 
93  {
94  UpdateNumPostponed = false;
95  force = true;
96  }
97 
98  if (mutt_str_strcmp(C_Postponed, OldPostponed) != 0)
99  {
100  FREE(&OldPostponed);
101  OldPostponed = mutt_str_strdup(C_Postponed);
102  LastModify = 0;
103  force = true;
104  }
105 
106  if (!C_Postponed)
107  return 0;
108 
109  // We currently are in the C_Postponed mailbox so just pick the current status
110  if (m && (mutt_str_strcmp(C_Postponed, m->realpath) == 0))
111  {
112  PostCount = m->msg_count - m->msg_deleted;
113  return PostCount;
114  }
115 
116 #ifdef USE_IMAP
117  /* LastModify is useless for IMAP */
118  if (imap_path_probe(C_Postponed, NULL) == MUTT_IMAP)
119  {
120  if (force)
121  {
122  short newpc;
123 
124  newpc = imap_path_status(C_Postponed, false);
125  if (newpc >= 0)
126  {
127  PostCount = newpc;
128  mutt_debug(LL_DEBUG3, "%d postponed IMAP messages found\n", PostCount);
129  }
130  else
131  mutt_debug(LL_DEBUG3, "using old IMAP postponed count\n");
132  }
133  return PostCount;
134  }
135 #endif
136 
137  if (stat(C_Postponed, &st) == -1)
138  {
139  PostCount = 0;
140  LastModify = 0;
141  return 0;
142  }
143 
144  if (S_ISDIR(st.st_mode))
145  {
146  /* if we have a maildir mailbox, we need to stat the "new" dir */
147 
148  char buf[PATH_MAX];
149 
150  snprintf(buf, sizeof(buf), "%s/new", C_Postponed);
151  if ((access(buf, F_OK) == 0) && (stat(buf, &st) == -1))
152  {
153  PostCount = 0;
154  LastModify = 0;
155  return 0;
156  }
157  }
158 
159  if (LastModify < st.st_mtime)
160  {
161 #ifdef USE_NNTP
162  int optnews = OptNews;
163 #endif
164  LastModify = st.st_mtime;
165 
166  if (access(C_Postponed, R_OK | F_OK) != 0)
167  return PostCount = 0;
168 #ifdef USE_NNTP
169  if (optnews)
170  OptNews = false;
171 #endif
172  struct Mailbox *m_post = mx_path_resolve(C_Postponed);
173  struct Context *ctx = mx_mbox_open(m_post, MUTT_NOSORT | MUTT_QUIET);
174  if (!ctx)
175  {
176  mailbox_free(&m_post);
177  PostCount = 0;
178  }
179  else
180  PostCount = ctx->mailbox->msg_count;
181  mx_fastclose_mailbox(m_post);
182  ctx_free(&ctx);
183 #ifdef USE_NNTP
184  if (optnews)
185  OptNews = true;
186 #endif
187  }
188 
189  return PostCount;
190 }
The "current" mailbox.
Definition: context.h:36
int msg_count
Total number of messages.
Definition: mailbox.h:102
int imap_path_status(const char *path, bool queue)
Refresh the number of total and new messages.
Definition: imap.c:1309
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2425
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:107
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:95
struct Context * mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:254
struct Mailbox * mailbox
Definition: context.h:50
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:55
void mx_fastclose_mailbox(struct Mailbox *m)
free up memory associated with the Mailbox
Definition: mx.c:392
A mailbox.
Definition: mailbox.h:92
#define PATH_MAX
Definition: mutt.h:52
#define MUTT_NOSORT
Do not sort the mailbox after opening it.
Definition: mx.h:51
static short PostCount
Definition: postpone.c:74
#define MUTT_QUIET
Do not print any messages.
Definition: mx.h:54
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
struct Mailbox * mx_path_resolve(const char *path)
XXX.
Definition: mx.c:1539
static bool UpdateNumPostponed
Definition: postpone.c:75
void ctx_free(struct Context **ptr)
Free a Context.
Definition: context.c:48
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
WHERE char * C_Postponed
Config: Folder to store postponed messages.
Definition: globals.h:139
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
Log at debug level 3.
Definition: logging.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_thread_set_flag()

int mutt_thread_set_flag ( struct Email e,
int  flag,
bool  bf,
bool  subthread 
)

Set a flag on an entire thread.

Parameters
eEmail
flagFlag to set, e.g. MUTT_DELETE
bftrue: set the flag; false: clear the flag
subthreadIf true apply to all of the thread
Return values
0Success
-1Failure

Definition at line 375 of file flags.c.

376 {
377  struct MuttThread *start = NULL;
378  struct MuttThread *cur = e->thread;
379 
380  if ((C_Sort & SORT_MASK) != SORT_THREADS)
381  {
382  mutt_error(_("Threading is not enabled"));
383  return -1;
384  }
385 
386  if (!subthread)
387  while (cur->parent)
388  cur = cur->parent;
389  start = cur;
390 
391  if (cur->message && (cur != e->thread))
392  mutt_set_flag(Context->mailbox, cur->message, flag, bf);
393 
394  cur = cur->child;
395  if (!cur)
396  goto done;
397 
398  while (true)
399  {
400  if (cur->message && (cur != e->thread))
401  mutt_set_flag(Context->mailbox, cur->message, flag, bf);
402 
403  if (cur->child)
404  cur = cur->child;
405  else if (cur->next)
406  cur = cur->next;
407  else
408  {
409  while (!cur->next)
410  {
411  cur = cur->parent;
412  if (cur == start)
413  goto done;
414  }
415  cur = cur->next;
416  }
417  }
418 done:
419  cur = e->thread;
420  if (cur->message)
421  mutt_set_flag(Context->mailbox, cur->message, flag, bf);
422  return 0;
423 }
struct MuttThread * next
Next sibling Thread.
Definition: thread.h:47
The "current" mailbox.
Definition: context.h:36
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:69
struct MuttThread * thread
Thread of Emails.
Definition: email.h:96
#define _(a)
Definition: message.h:28
struct MuttThread * parent
Parent of this Thread.
Definition: thread.h:45
struct Mailbox * mailbox
Definition: context.h:50
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:58
struct MuttThread * child
Child of this Thread.
Definition: thread.h:46
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
An Email conversation.
Definition: thread.h:34
#define mutt_error(...)
Definition: logging.h:84
Sort by email threads.
Definition: sort.h:56
#define SORT_MASK
Mask for the sort id.
Definition: sort.h:85
+ Here is the caller graph for this function:

◆ mutt_update_num_postponed()

void mutt_update_num_postponed ( void  )

Force the update of the number of postponed messages.

Definition at line 195 of file postpone.c.

196 {
197  UpdateNumPostponed = true;
198 }
static bool UpdateNumPostponed
Definition: postpone.c:75
+ Here is the caller graph for this function:

◆ mutt_is_quote_line()

int mutt_is_quote_line ( char *  line,
regmatch_t *  pmatch 
)

Is a line of message text a quote?

Parameters
[in]lineLine to test
[out]pmatchRegex sub-matches
Return values
trueLine is quoted

Checks if line matches the C_QuoteRegex and doesn't match C_Smileys. This is used by the pager for calling classify_quote.

Definition at line 945 of file pager.c.

946 {
947  bool is_quote = false;
948  regmatch_t pmatch_internal[1], smatch[1];
949 
950  if (!pmatch)
951  pmatch = pmatch_internal;
952 
953  if (mutt_regex_capture(C_QuoteRegex, line, 1, pmatch))
954  {
955  if (mutt_regex_capture(C_Smileys, line, 1, smatch))
956  {
957  if (smatch[0].rm_so > 0)
958  {
959  char c = line[smatch[0].rm_so];
960  line[smatch[0].rm_so] = 0;
961 
962  if (mutt_regex_capture(C_QuoteRegex, line, 1, pmatch))
963  is_quote = true;
964 
965  line[smatch[0].rm_so] = c;
966  }
967  }
968  else
969  is_quote = true;
970  }
971 
972  return is_quote;
973 }
struct Regex * C_Smileys
Config: Regex to match smileys to prevent mistakes when quoting text.
Definition: pager.c:96
const char * line
Definition: common.c:36
WHERE struct Regex * C_QuoteRegex
Config: Regex to match quoted text in a reply.
Definition: globals.h:182
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
match a regex against a string, with provided options
Definition: regex.c:594
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ wcscasecmp()

int wcscasecmp ( const wchar_t *  a,
const wchar_t *  b 
)

Compare two wide-character strings, ignoring case.

Parameters
aFirst string
bSecond string
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 41 of file wcscasecmp.c.

42 {
43  if (!a && !b)
44  return 0;
45  if (!a && b)
46  return -1;
47  if (a && !b)
48  return 1;
49 
50  for (; *a || *b; a++, b++)
51  {
52  int i = towlower(*a);
53  if ((i - towlower(*b)) != 0)
54  return i;
55  }
56  return 0;
57 }
+ Here is the caller graph for this function:

◆ mutt_reply_observer()

int mutt_reply_observer ( struct NotifyCallback nc)

Listen for config changes to "reply_regex" - Implements observer_t()

Definition at line 3695 of file index.c.

3696 {
3697  if (!nc)
3698  return -1;
3699 
3700  struct EventConfig *ec = (struct EventConfig *) nc->event;
3701 
3702  if (mutt_str_strcmp(ec->name, "reply_regex") != 0)
3703  return 0;
3704 
3705  if (!Context || !Context->mailbox)
3706  return 0;
3707 
3708  regmatch_t pmatch[1];
3709 
3710  for (int i = 0; i < Context->mailbox->msg_count; i++)
3711  {
3712  struct Envelope *e = Context->mailbox->emails[i]->env;
3713  if (!e || !e->subject)
3714  continue;
3715 
3716  if (mutt_regex_capture(C_ReplyRegex, e->subject, 1, pmatch))
3717  {
3718  e->real_subj = e->subject + pmatch[0].rm_eo;
3719  continue;
3720  }
3721 
3722  e->real_subj = e->subject;
3723  }
3724 
3725  OptResortInit = true; /* trigger a redraw of the index */
3726  return 0;
3727 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
The "current" mailbox.
Definition: context.h:36
int msg_count
Total number of messages.
Definition: mailbox.h:102
A config-change event.
Definition: set.h:199
char * real_subj
Offset of the real subject.
Definition: envelope.h:67
intptr_t event
Send: event data.
Definition: observer.h:46
struct Mailbox * mailbox
Definition: context.h:50
struct Envelope * env
Envelope information.
Definition: email.h:91
struct Regex * C_ReplyRegex
Config: Regex to match message reply subjects like "re: ".
Definition: email_globals.c:37
WHERE bool OptResortInit
(pseudo) used to force the next resort to be from scratch
Definition: options.h:49
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
match a regex against a string, with provided options
Definition: regex.c:594
char * subject
Email&#39;s subject.
Definition: envelope.h:66
const char * name
Name of config item that changed.
Definition: set.h:203
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
The header of an Email.
Definition: envelope.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function: