summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--browser.c214
-rw-r--r--configure.ac4
-rw-r--r--contrib/mutt_oauth2.py1
-rw-r--r--curs_lib.c14
-rw-r--r--curs_main.c2
-rw-r--r--enter.c2
-rw-r--r--globals.h2
-rw-r--r--headers.c4
-rw-r--r--hook.c2
-rw-r--r--init.h16
-rw-r--r--main.c2
-rw-r--r--mutt.h9
-rw-r--r--mutt_socket.c16
-rw-r--r--mutt_ssl.c234
-rw-r--r--po/fr.po914
-rwxr-xr-xsmime_keys.pl2
16 files changed, 725 insertions, 713 deletions
diff --git a/browser.c b/browser.c
index 4f365ebd..a4566395 100644
--- a/browser.c
+++ b/browser.c
@@ -56,13 +56,13 @@ typedef struct folder_t
int num;
} FOLDER;
-static BUFFER *LastDir = NULL;
-static BUFFER *LastDirBackup = NULL;
+static BUFFER *LastMailboxDir = NULL;
+static BUFFER *LastFileDir = NULL;
void mutt_browser_cleanup (void)
{
- mutt_buffer_free (&LastDir);
- mutt_buffer_free (&LastDirBackup);
+ mutt_buffer_free (&LastMailboxDir);
+ mutt_buffer_free (&LastFileDir);
}
/* Frees up the memory allocated for the local-global variables. */
@@ -728,7 +728,8 @@ static void set_sticky_cursor (struct browser_state *state, MUTTMENU *menu, cons
}
static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
- size_t titlelen, const char *defaultsel)
+ size_t titlelen, const char *defaultsel,
+ const char *working_dir)
{
BUFFER *path = NULL;
@@ -749,7 +750,7 @@ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
snprintf (title, titlelen, _("Mailboxes [%d]"), mutt_buffy_check (0));
else
{
- mutt_buffer_strcpy (path, mutt_b2s (LastDir));
+ mutt_buffer_strcpy (path, working_dir);
mutt_buffer_pretty_mailbox (path);
#ifdef USE_IMAP
if (state->imap_browse && option (OPTIMAPLSUB))
@@ -807,8 +808,8 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
BUFFER *buf = NULL;
BUFFER *prefix = NULL;
BUFFER *tmp = NULL;
- BUFFER *OldLastDir = NULL;
BUFFER *defaultsel = NULL;
+ BUFFER *working_dir = NULL, *old_working_dir = NULL;
char helpstr[LONG_STRING];
char title[STRING];
struct browser_state state;
@@ -817,31 +818,35 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
int op, killPrefix = 0;
int i, j;
int multiple = (flags & MUTT_SEL_MULTI) ? 1 : 0;
- int folder = (flags & MUTT_SEL_FOLDER) ? 1 : 0;
- int buffy = (flags & MUTT_SEL_BUFFY) ? 1 : 0;
-
- buffy = buffy && folder;
buf = mutt_buffer_pool_get ();
prefix = mutt_buffer_pool_get ();
tmp = mutt_buffer_pool_get ();
- OldLastDir = mutt_buffer_pool_get ();
- defaultsel = mutt_buffer_pool_get ();
+ defaultsel = mutt_buffer_pool_get ();
+ working_dir = mutt_buffer_pool_get ();
+ old_working_dir = mutt_buffer_pool_get ();
memset (&state, 0, sizeof (struct browser_state));
- state.buffy = buffy;
+ state.buffy = (flags & MUTT_SEL_BUFFY) ? 1 : 0;
- if (!LastDir)
+ if (!LastMailboxDir)
+ {
+ LastMailboxDir = mutt_buffer_new ();
+ mutt_buffer_increase_size (LastMailboxDir, _POSIX_PATH_MAX);
+ }
+ if (!LastFileDir)
{
- LastDir = mutt_buffer_new ();
- mutt_buffer_increase_size (LastDir, _POSIX_PATH_MAX);
- LastDirBackup = mutt_buffer_new ();
- mutt_buffer_increase_size (LastDirBackup, _POSIX_PATH_MAX);
+ LastFileDir = mutt_buffer_new ();
+ mutt_buffer_increase_size (LastFileDir, _POSIX_PATH_MAX);
}
- if (!folder)
- mutt_buffer_strcpy (LastDirBackup, mutt_b2s (LastDir));
+ if (flags & MUTT_SEL_MAILBOX)
+ mutt_buffer_strcpy (working_dir, mutt_b2s (LastMailboxDir));
+ else if (flags & MUTT_SEL_FILE)
+ mutt_buffer_strcpy (working_dir, mutt_b2s (LastFileDir));
+ else
+ mutt_getcwd (working_dir);
if (*(mutt_b2s (f)))
{
@@ -859,7 +864,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
init_state (&state, NULL);
state.imap_browse = 1;
if (!imap_browse (mutt_b2s (f), &state))
- mutt_buffer_strcpy (LastDir, state.folder);
+ mutt_buffer_strcpy (working_dir, state.folder);
}
else
{
@@ -870,20 +875,20 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
if (i > 0)
{
if ((mutt_b2s (f))[0] == '/')
- mutt_buffer_strcpy_n (LastDir, mutt_b2s (f), i);
+ mutt_buffer_strcpy_n (working_dir, mutt_b2s (f), i);
else
{
- mutt_getcwd (LastDir);
- mutt_buffer_addch (LastDir, '/');
- mutt_buffer_addstr_n (LastDir, mutt_b2s (f), i);
+ mutt_getcwd (working_dir);
+ mutt_buffer_addch (working_dir, '/');
+ mutt_buffer_addstr_n (working_dir, mutt_b2s (f), i);
}
}
else
{
if ((mutt_b2s (f))[0] == '/')
- mutt_buffer_strcpy (LastDir, "/");
+ mutt_buffer_strcpy (working_dir, "/");
else
- mutt_getcwd (LastDir);
+ mutt_getcwd (working_dir);
}
if (i <= 0 && (mutt_b2s (f))[0] != '/')
@@ -897,31 +902,34 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
}
else
{
- if (!folder)
- mutt_getcwd (LastDir);
- else if (!*(mutt_b2s (LastDir)))
- mutt_buffer_strcpy (LastDir, NONULL(Maildir));
+ if (!*(mutt_b2s (working_dir)))
+ {
+ if (flags & MUTT_SEL_MAILBOX)
+ mutt_buffer_strcpy (working_dir, NONULL(Maildir));
+ else
+ mutt_getcwd (working_dir);
+ }
if (Context)
mutt_buffer_strcpy (defaultsel, NONULL (Context->path));
#ifdef USE_IMAP
- if (!state.buffy && mx_is_imap (mutt_b2s (LastDir)))
+ if (!state.buffy && mx_is_imap (mutt_b2s (working_dir)))
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
}
else
#endif
{
- i = mutt_buffer_len (LastDir);
- while (i && mutt_b2s (LastDir)[--i] == '/')
- LastDir->data[i] = '\0';
- mutt_buffer_fix_dptr (LastDir);
- if (!*(mutt_b2s (LastDir)))
- mutt_getcwd (LastDir);
+ i = mutt_buffer_len (working_dir);
+ while (i && mutt_b2s (working_dir)[--i] == '/')
+ working_dir->data[i] = '\0';
+ mutt_buffer_fix_dptr (working_dir);
+ if (!*(mutt_b2s (working_dir)))
+ mutt_getcwd (working_dir);
}
}
@@ -936,7 +944,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
#ifdef USE_IMAP
if (!state.imap_browse)
#endif
- if (examine_directory (NULL, &state, mutt_b2s (LastDir), mutt_b2s (prefix)) == -1)
+ if (examine_directory (NULL, &state, mutt_b2s (working_dir), mutt_b2s (prefix)) == -1)
goto bail;
menu = mutt_new_menu (MENU_FOLDER);
@@ -951,7 +959,8 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
FolderHelp);
mutt_push_current_menu (menu);
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
FOREVER
{
@@ -987,9 +996,9 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
)
{
/* save the old directory */
- mutt_buffer_strcpy (OldLastDir, mutt_b2s (LastDir));
+ mutt_buffer_strcpy (old_working_dir, mutt_b2s (working_dir));
- mutt_buffer_strcpy (defaultsel, mutt_b2s (OldLastDir));
+ mutt_buffer_strcpy (defaultsel, mutt_b2s (old_working_dir));
if (mutt_buffer_len (defaultsel) && (*(defaultsel->dptr - 1) == '/'))
{
defaultsel->dptr--;
@@ -998,46 +1007,46 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
if (mutt_strcmp (state.entry[menu->current].display_name, "..") == 0)
{
- size_t lastdirlen = mutt_buffer_len (LastDir);
+ size_t workingdirlen = mutt_buffer_len (working_dir);
- if ((lastdirlen > 1) &&
- mutt_strcmp ("..", mutt_b2s (LastDir) + lastdirlen - 2) == 0)
+ if ((workingdirlen > 1) &&
+ mutt_strcmp ("..", mutt_b2s (working_dir) + workingdirlen - 2) == 0)
{
- mutt_buffer_addstr (LastDir, "/..");
+ mutt_buffer_addstr (working_dir, "/..");
}
else
{
char *p = NULL;
- if (lastdirlen > 1)
+ if (workingdirlen > 1)
{
- /* "mutt_b2s (LastDir) + 1" triggers a compiler warning */
- p = strrchr (LastDir->data + 1, '/');
+ /* "mutt_b2s (working_dir) + 1" triggers a compiler warning */
+ p = strrchr (working_dir->data + 1, '/');
}
if (p)
{
*p = 0;
- mutt_buffer_fix_dptr (LastDir);
+ mutt_buffer_fix_dptr (working_dir);
}
else
{
- if (mutt_b2s (LastDir)[0] == '/')
- mutt_buffer_strcpy (LastDir, "/");
+ if (mutt_b2s (working_dir)[0] == '/')
+ mutt_buffer_strcpy (working_dir, "/");
else
- mutt_buffer_addstr (LastDir, "/..");
+ mutt_buffer_addstr (working_dir, "/..");
}
}
}
else if (state.buffy)
{
- mutt_buffer_strcpy (LastDir, state.entry[menu->current].full_path);
+ mutt_buffer_strcpy (working_dir, state.entry[menu->current].full_path);
}
#ifdef USE_IMAP
else if (state.imap_browse)
{
ciss_url_t url;
- mutt_buffer_strcpy (LastDir, state.entry[menu->current].full_path);
+ mutt_buffer_strcpy (working_dir, state.entry[menu->current].full_path);
/* tack on delimiter here */
/* special case "" needs no delimiter */
@@ -1045,13 +1054,13 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
if (url.path &&
(state.entry[menu->current].delim != '\0'))
{
- mutt_buffer_addch (LastDir, state.entry[menu->current].delim);
+ mutt_buffer_addch (working_dir, state.entry[menu->current].delim);
}
}
#endif
else
{
- mutt_buffer_strcpy (LastDir, state.entry[menu->current].full_path);
+ mutt_buffer_strcpy (working_dir, state.entry[menu->current].full_path);
}
destroy_state (&state);
@@ -1066,25 +1075,26 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
menu->data = state.entry;
}
else
#endif
- if (examine_directory (menu, &state, mutt_b2s (LastDir), mutt_b2s (prefix)) == -1)
+ if (examine_directory (menu, &state, mutt_b2s (working_dir), mutt_b2s (prefix)) == -1)
{
/* try to restore the old values */
- mutt_buffer_strcpy (LastDir, mutt_b2s (OldLastDir));
- if (examine_directory (menu, &state, mutt_b2s (LastDir), mutt_b2s (prefix)) == -1)
+ mutt_buffer_strcpy (working_dir, mutt_b2s (old_working_dir));
+ if (examine_directory (menu, &state, mutt_b2s (working_dir), mutt_b2s (prefix)) == -1)
{
- mutt_buffer_strcpy (LastDir, NONULL(Homedir));
+ mutt_buffer_strcpy (working_dir, NONULL(Homedir));
goto bail;
}
}
menu->current = 0;
menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
break;
}
}
@@ -1161,19 +1171,20 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
break;
}
- if (!imap_mailbox_create (mutt_b2s (LastDir), defaultsel))
+ if (!imap_mailbox_create (mutt_b2s (working_dir), defaultsel))
{
/* TODO: find a way to detect if the new folder would appear in
* this window, and insert it without starting over. */
destroy_state (&state);
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
menu->data = state.entry;
menu->current = 0;
menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
}
/* else leave error on screen */
break;
@@ -1190,12 +1201,13 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
destroy_state (&state);
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
menu->data = state.entry;
menu->current = 0;
menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
}
}
break;
@@ -1233,7 +1245,8 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
state.entrylen--;
mutt_message _("Mailbox deleted.");
mutt_buffer_clear (defaultsel);
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
}
else
mutt_error _("Mailbox deletion failed.");
@@ -1247,15 +1260,15 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
case OP_CHANGE_DIRECTORY:
- mutt_buffer_strcpy (buf, mutt_b2s (LastDir));
+ mutt_buffer_strcpy (buf, mutt_b2s (working_dir));
mutt_buffer_clear (defaultsel);
#ifdef USE_IMAP
if (!state.imap_browse)
#endif
{
/* add '/' at the end of the directory name if not already there */
- size_t len = mutt_buffer_len (LastDir);
- if (len && (mutt_b2s (LastDir)[len-1] != '/'))
+ size_t len = mutt_buffer_len (working_dir);
+ if (len && (mutt_b2s (working_dir)[len-1] != '/'))
mutt_buffer_addch (buf, '/');
}
@@ -1265,30 +1278,31 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
{
state.buffy = 0;
/* no relative path expansion, because that should be compared
- * to LastDir, not cwd */
+ * to working_dir, not cwd */
mutt_buffer_expand_path_norel (buf);
#ifdef USE_IMAP
if (mx_is_imap (mutt_b2s (buf)))
{
- mutt_buffer_strcpy (LastDir, mutt_b2s (buf));
+ mutt_buffer_strcpy (working_dir, mutt_b2s (buf));
destroy_state (&state);
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
menu->data = state.entry;
menu->current = 0;
menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
}
else
#endif
{
if (*(mutt_b2s (buf)) != '/')
{
- /* in case dir is relative, make it relative to LastDir,
+ /* in case dir is relative, make it relative to working_dir,
* not current working dir */
- mutt_buffer_concat_path (tmp, mutt_b2s (LastDir), mutt_b2s (buf));
+ mutt_buffer_concat_path (tmp, mutt_b2s (working_dir), mutt_b2s (buf));
mutt_buffer_strcpy (buf, mutt_b2s (tmp));
}
if (stat (mutt_b2s (buf), &st) == 0)
@@ -1297,18 +1311,19 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
{
destroy_state (&state);
if (examine_directory (menu, &state, mutt_b2s (buf), mutt_b2s (prefix)) == 0)
- mutt_buffer_strcpy (LastDir, mutt_b2s (buf));
+ mutt_buffer_strcpy (working_dir, mutt_b2s (buf));
else
{
mutt_error _("Error scanning directory.");
- if (examine_directory (menu, &state, mutt_b2s (LastDir), mutt_b2s (prefix)) == -1)
+ if (examine_directory (menu, &state, mutt_b2s (working_dir), mutt_b2s (prefix)) == -1)
{
goto bail;
}
}
menu->current = 0;
menu->top = 0;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
}
else
mutt_error (_("%s is not a directory."), mutt_b2s (buf));
@@ -1362,15 +1377,17 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
menu->data = state.entry;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
}
else
#endif
- if (examine_directory (menu, &state, mutt_b2s (LastDir), NULL) == 0)
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ if (examine_directory (menu, &state, mutt_b2s (working_dir), NULL) == 0)
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
else
{
mutt_error _("Error scanning directory.");
@@ -1415,18 +1432,19 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
goto bail;
}
#ifdef USE_IMAP
- else if (mx_is_imap (mutt_b2s (LastDir)))
+ else if (mx_is_imap (mutt_b2s (working_dir)))
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_browse (mutt_b2s (LastDir), &state);
+ imap_browse (mutt_b2s (working_dir), &state);
browser_sort (&state);
menu->data = state.entry;
}
#endif
- else if (examine_directory (menu, &state, mutt_b2s (LastDir), mutt_b2s (prefix)) == -1)
+ else if (examine_directory (menu, &state, mutt_b2s (working_dir), mutt_b2s (prefix)) == -1)
goto bail;
- init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel));
+ init_menu (&state, menu, title, sizeof (title), mutt_b2s (defaultsel),
+ mutt_b2s (working_dir));
break;
case OP_BUFFY_LIST:
@@ -1435,7 +1453,7 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
case OP_BROWSER_NEW_FILE:
- mutt_buffer_printf (buf, "%s/", mutt_b2s (LastDir));
+ mutt_buffer_printf (buf, "%s/", mutt_b2s (working_dir));
/* buf comes from the buffer pool, so defaults to size LONG_STRING */
if (mutt_buffer_get_field (_("New file name: "), buf, MUTT_FILE) == 0)
{
@@ -1495,19 +1513,21 @@ void _mutt_buffer_select_file (BUFFER *f, int flags, char ***files, int *numfile
}
bail:
+ if (flags & MUTT_SEL_MAILBOX)
+ mutt_buffer_strcpy (LastMailboxDir, mutt_b2s (working_dir));
+ else if (flags & MUTT_SEL_FILE)
+ mutt_buffer_strcpy (LastFileDir, mutt_b2s (working_dir));
+
mutt_buffer_pool_release (&buf);
mutt_buffer_pool_release (&prefix);
mutt_buffer_pool_release (&tmp);
- mutt_buffer_pool_release (&OldLastDir);
mutt_buffer_pool_release (&defaultsel);
+ mutt_buffer_pool_release (&working_dir);
+ mutt_buffer_pool_release (&old_working_dir);
if (menu)
{
mutt_pop_current_menu (menu);
mutt_menuDestroy (&menu);
}
-
- if (!folder)
- mutt_buffer_strcpy (LastDir, mutt_b2s (LastDirBackup));
-
}
diff --git a/configure.ac b/configure.ac
index 2e38c49f..9348b4c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1325,10 +1325,10 @@ AC_CACHE_CHECK([whether iconv is non-transcribing], mutt_cv_iconv_nontrans,
int main()
{
iconv_t cd;
- const char *ib;
+ char *ib;
char *ob;
size_t ibl, obl;
- const char *s = "\304\211";
+ char *s = (char *) "\304\211";
changequote(, )dnl
char t[3];
changequote([, ])dnl
diff --git a/contrib/mutt_oauth2.py b/contrib/mutt_oauth2.py
index 52358e94..c973b98e 100644
--- a/contrib/mutt_oauth2.py
+++ b/contrib/mutt_oauth2.py
@@ -38,6 +38,7 @@ from pathlib import Path
import socket
import http.server
import subprocess
+import readline
# The token file must be encrypted because it contains multi-use bearer tokens
# whose usage does not require additional verification. Specify whichever
diff --git a/curs_lib.c b/curs_lib.c
index efa76ce6..246cb6be 100644
--- a/curs_lib.c
+++ b/curs_lib.c
@@ -1093,11 +1093,19 @@ static int _enter_fname (const char *prompt, BUFFER *fname, int flags,
}
else if (ch.ch == '?')
{
+ int sel_flags = 0;
+
+ if (flags & MUTT_MAILBOX)
+ sel_flags |= MUTT_SEL_MAILBOX;
+ else if (flags & MUTT_FILE)
+ sel_flags |= MUTT_SEL_FILE;
+
+ if (multiple)
+ sel_flags |= MUTT_SEL_MULTI;
+
mutt_refresh ();
mutt_buffer_clear (fname);
- _mutt_buffer_select_file (fname,
- MUTT_SEL_FOLDER | (multiple ? MUTT_SEL_MULTI : 0),
- files, numfiles);
+ _mutt_buffer_select_file (fname, sel_flags, files, numfiles);
}
else
{
diff --git a/curs_main.c b/curs_main.c
index 71a4e06e..3d79723c 100644
--- a/curs_main.c
+++ b/curs_main.c
@@ -1360,7 +1360,7 @@ int mutt_index_menu (void)
else if ((op == OP_MAIN_BROWSE_MAILBOXES) ||
(op == OP_MAIN_BROWSE_MAILBOXES_READONLY))
- mutt_buffer_select_file (folderbuf, MUTT_SEL_FOLDER | MUTT_SEL_BUFFY);
+ mutt_buffer_select_file (folderbuf, MUTT_SEL_MAILBOX | MUTT_SEL_BUFFY);
else
{
diff --git a/enter.c b/enter.c
index f09dd265..693f3b1d 100644
--- a/enter.c
+++ b/enter.c
@@ -725,7 +725,7 @@ int _mutt_enter_string (char *buf, size_t buflen, int col,
!memcmp (tempbuf, state->wbuf, state->lastchar * sizeof (wchar_t))))
{
_mutt_select_file (buf, buflen,
- ((flags & MUTT_MAILBOX) ? MUTT_SEL_FOLDER : 0) | (multiple ? MUTT_SEL_MULTI : 0),
+ ((flags & MUTT_MAILBOX) ? MUTT_SEL_MAILBOX : 0) | (multiple ? MUTT_SEL_MULTI : 0),
files, numfiles);
if (!multiple && *buf)
{
diff --git a/globals.h b/globals.h
index 631f88a6..fd63bd43 100644
--- a/globals.h
+++ b/globals.h
@@ -103,6 +103,8 @@ WHERE char *MsgFmt;
WHERE char *Preconnect;
WHERE char *Tunnel;
WHERE short NetInc;
+WHERE short SocketReceiveTimeout;
+WHERE short SocketSendTimeout;
#endif /* USE_SOCKET */
#ifdef MIXMASTER
diff --git a/headers.c b/headers.c
index 063525ea..15edf8ef 100644
--- a/headers.c
+++ b/headers.c
@@ -347,9 +347,7 @@ int mutt_label_message(HEADER *hdr)
if (label_message(Context, HDR_OF(i), new))
{
++changed;
- mutt_set_flag(Context, HDR_OF(i),
- MUTT_TAG, 0);
- /* mutt_set_flag re-evals the header color */
+ mutt_set_header_color (Context, HDR_OF(i));
}
}
}
diff --git a/hook.c b/hook.c
index a0a6cab6..cd4c6a76 100644
--- a/hook.c
+++ b/hook.c
@@ -165,7 +165,7 @@ int mutt_parse_hook (BUFFER *buf, BUFFER *s, union pointer_long_t udata, BUFFER
}
else if (data & MUTT_FCCHOOK)
{
- /* Do not perform relative path expansion "\^" can be expanded later:
+ /* Do not perform relative path expansion. "\^" can be expanded later:
* mutt_select_fcc() => mutt_addr_hook() => mutt_make_string()
* which will perform backslash expansion, converting "\^" to "^".
* save_fcc_mailbox_part() then calls mutt_buffer_expand_path() on each part.
diff --git a/init.h b/init.h
index 5e15a3e3..dcb664f8 100644
--- a/init.h
+++ b/init.h
@@ -4161,6 +4161,22 @@ struct option_t MuttVars[] = {
** Also see $$write_bcc.
*/
#endif /* USE_SMTP */
+#ifdef USE_SOCKET
+ { "socket_receive_timeout", DT_NUM, R_NONE, {.p=&SocketReceiveTimeout}, {.l=0} },
+ /*
+ ** .pp
+ ** Causes Mutt to timeout any socket read operation (e.g. SSL_read) after
+ ** this many seconds. A zero (default) or negative value causes Mutt to wait
+ ** indefinitely for the read to complete.
+ */
+ { "socket_send_timeout", DT_NUM, R_NONE, {.p=&SocketSendTimeout}, {.l=0} },
+ /*
+ ** .pp
+ ** Causes Mutt to timeout any socket write operation (e.g. SSL_write) after
+ ** this many seconds. A zero (default) or negative value causes Mutt to wait
+ ** indefinitely for the write to complete.
+ */
+#endif /* USE_SOCKET */
{ "sort", DT_SORT, R_INDEX|R_RESORT, {.p=&Sort}, {.l=SORT_DATE} },
/*
** .pp
diff --git a/main.c b/main.c
index 9172d8bc..c3c67669 100644
--- a/main.c
+++ b/main.c
@@ -1356,7 +1356,7 @@ int main (int argc, char **argv, char **environ)
goto cleanup_and_exit;
}
mutt_buffer_clear (folder);
- mutt_buffer_select_file (folder, MUTT_SEL_FOLDER | MUTT_SEL_BUFFY);
+ mutt_buffer_select_file (folder, MUTT_SEL_MAILBOX | MUTT_SEL_BUFFY);
if (!mutt_buffer_len (folder))
{
exit_code = 0;
diff --git a/mutt.h b/mutt.h
index 2946c78b..ca30791d 100644
--- a/mutt.h
+++ b/mutt.h
@@ -371,10 +371,11 @@ enum
#define MUTT_EDIT_HEADERS_RESUME 2
/* flags to _mutt_select_file() */
-#define MUTT_SEL_BUFFY (1<<0)
-#define MUTT_SEL_MULTI (1<<1)
-#define MUTT_SEL_FOLDER (1<<2)
-#define MUTT_SEL_DIRECTORY (1<<3) /* Allow directories to be selected
+#define MUTT_SEL_BUFFY (1<<0)
+#define MUTT_SEL_MULTI (1<<1)
+#define MUTT_SEL_MAILBOX (1<<2) /* Use LastMailboxDir state */
+#define MUTT_SEL_FILE (1<<3) /* Use LastFileDir state */
+#define MUTT_SEL_DIRECTORY (1<<4) /* Allow directories to be selected
* via <view-file> */
/* flags for parse_spam_list */
diff --git a/mutt_socket.c b/mutt_socket.c
index 3e192072..898faa07 100644
--- a/mutt_socket.c
+++ b/mutt_socket.c
@@ -433,6 +433,22 @@ static int socket_connect (int fd, struct sockaddr* sa)
save_errno = 0;
+ if (SocketReceiveTimeout > 0)
+ {
+ struct timeval tv = { SocketReceiveTimeout, 0 };
+ if (setsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) < 0)
+ dprint (1, (debugfile, "socket_connect: error setting receive timeout (%s)\n",
+ strerror(errno)));
+ }
+
+ if (SocketSendTimeout > 0)
+ {
+ struct timeval tv = { SocketSendTimeout, 0 };
+ if (setsockopt (fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, sizeof(tv)) < 0)
+ dprint (1, (debugfile, "socket_connect: error setting send timeout (%s)\n",
+ strerror(errno)));
+ }
+
if (connect (fd, sa, sa_size) < 0)
{
save_errno = errno;
diff --git a/mutt_ssl.c b/mutt_ssl.c
index 4dc431db..4d272da2 100644
--- a/mutt_ssl.c
+++ b/mutt_ssl.c
@@ -92,7 +92,7 @@ static int ssl_socket_write (CONNECTION* conn, const char* buf, size_t len);
static int ssl_socket_poll (CONNECTION* conn, time_t wait_secs);
static int ssl_socket_open (CONNECTION * conn);
static int ssl_socket_close (CONNECTION * conn);
-static int tls_close (CONNECTION* conn);
+static int starttls_close (CONNECTION* conn);
static void ssl_err (sslsockdata *data, int err);
static void ssl_dprint_err_stack (void);
static int ssl_cache_trusted_cert (X509 *cert);
@@ -204,44 +204,33 @@ static void reset_allowed_proto_version_range (sslsockdata *ssldata)
#endif
}
-/* mutt_ssl_starttls: Negotiate TLS over an already opened connection.
- * TODO: Merge this code better with ssl_socket_open. */
-int mutt_ssl_starttls (CONNECTION* conn)
+/* mutt_ssl_setup_common: common code paths for Implicit TLS and in-band STARTTLS (STLS) modes */
+static int mutt_ssl_setup_common (CONNECTION *conn, long ssl_options)
{
- sslsockdata* ssldata;
+ sslsockdata *data;
int maxbits;
- long ssl_options = 0;
-
- if (mutt_socket_has_buffered_input (conn))
- {
- /* L10N:
- The server is not supposed to send data immediately after
- confirming STARTTLS. This warns the user that something
- weird is going on.
- */
- mutt_error _("Warning: clearing unexpected server data before TLS negotiation");
- mutt_sleep (0);
- mutt_socket_clear_buffered_input (conn);
- }
- if (ssl_init())
+ if (ssl_init ())
goto bail;
- ssldata = (sslsockdata*) safe_calloc (1, sizeof (sslsockdata));
- /* the ssl_use_xxx protocol options don't apply. We must use TLS in TLS.
+ data = (sslsockdata*) safe_calloc (1, sizeof (sslsockdata));
+ /* the ssl_use_sslxxx protocol options don't apply to starttls,
+ * we must use TLS in TLS, so we do not refactor these.
*
* However, we need to be able to negotiate amongst various TLS versions,
* which at present can only be done with the SSLv23_client_method;
* TLSv1_client_method gives us explicitly TLSv1.0, not 1.1 or 1.2 (True as
- * of OpenSSL 1.0.1c)
+ * of OpenSSL 1.0.1c ... 3.0.x)
*/
- if (! (ssldata->ctx = SSL_CTX_new (SSLv23_client_method())))
+ if (! (data->ctx = SSL_CTX_new (SSLv23_client_method())))
{
dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL_CTX\n"));
+ mutt_error (_("Unable to create SSL context"));
+ ssl_dprint_err_stack ();
goto bail_ssldata;
}
- reset_allowed_proto_version_range (ssldata);
+ reset_allowed_proto_version_range (data);
#ifdef SSL_OP_NO_TLSv1_3
if (!option(OPTTLSV1_3))
@@ -259,89 +248,112 @@ int mutt_ssl_starttls (CONNECTION* conn)
if (!option(OPTTLSV1))
ssl_options |= SSL_OP_NO_TLSv1;
#endif
- /* these are always set */
-#ifdef SSL_OP_NO_SSLv3
- ssl_options |= SSL_OP_NO_SSLv3;
-#endif
-#ifdef SSL_OP_NO_SSLv2
- ssl_options |= SSL_OP_NO_SSLv2;
-#endif
- if (! SSL_CTX_set_options(ssldata->ctx, ssl_options))
- {
- dprint(1, (debugfile, "mutt_ssl_starttls: Error setting options to %ld\n", ssl_options));
- goto bail_ctx;
- }
+ (void)SSL_CTX_set_options (data->ctx, ssl_options); /* would only return new values -> discard */
if (option (OPTSSLSYSTEMCERTS))
{
- if (! SSL_CTX_set_default_verify_paths (ssldata->ctx))
+ if (! SSL_CTX_set_default_verify_paths (data->ctx))
{
dprint (1, (debugfile, "mutt_ssl_starttls: Error setting default verify paths\n"));
goto bail_ctx;
}
}
- if (SslCertFile && !ssl_load_certificates (ssldata->ctx))
- dprint (1, (debugfile, "mutt_ssl_starttls: Error loading trusted certificates\n"));
+ if (SslCertFile && !ssl_load_certificates (data->ctx))
+ dprint (1, (debugfile, "mutt_ssl_setup_common: Error loading trusted certificates\n"));
- ssl_get_client_cert(ssldata, conn);
+ ssl_get_client_cert (data, conn);
if (SslCiphers)
{
- if (!SSL_CTX_set_cipher_list (ssldata->ctx, SslCiphers))
+ if (!SSL_CTX_set_cipher_list (data->ctx, SslCiphers))
{
- dprint (1, (debugfile, "mutt_ssl_starttls: Could not select preferred ciphers\n"));
+ dprint (1, (debugfile, "mutt_ssl_setup_common: Could not select preferred ciphers\n"));
goto bail_ctx;
}
}
- if (ssl_set_verify_partial (ssldata->ctx))
+ if (ssl_set_verify_partial (data->ctx))
{
mutt_error (_("Warning: error enabling ssl_verify_partial_chains"));
mutt_sleep (2);
}
- if (! (ssldata->ssl = SSL_new (ssldata->ctx)))
+ if (! (data->ssl = SSL_new (data->ctx)))
{
- dprint (1, (debugfile, "mutt_ssl_starttls: Error allocating SSL\n"));
+ dprint (1, (debugfile, "mutt_ssl_setup_common: Error allocating SSL\n"));
goto bail_ctx;
}
- if (SSL_set_fd (ssldata->ssl, conn->fd) != 1)
+ if (SSL_set_fd (data->ssl, conn->fd) != 1)
{
- dprint (1, (debugfile, "mutt_ssl_starttls: Error setting fd\n"));
+ dprint (1, (debugfile, "mutt_ssl_setup_common: Error setting fd\n"));
goto bail_ssl;
}
- if (ssl_negotiate (conn, ssldata))