From: Thomas Roessler Date: Wed, 19 Jul 2000 10:21:54 +0000 (+0000) Subject: IMAP socket moves by Brendan Cully, with a fix from Tommi X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8b7dab763885aeed9987aed869f13e3fc9836810;p=neomutt IMAP socket moves by Brendan Cully, with a fix from Tommi Komulainen, and most likely based on input from Vsevolod Voykov (sp?). --- diff --git a/Makefile.am b/Makefile.am index 772e50092..72d9a9d8b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -56,22 +56,21 @@ non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c \ contrib/pgp2.rc contrib/pgp5.rc contrib/gpg.rc \ imap/imap_ssl.c imap/imap_ssl.h README.SSL -EXTRA_mutt_SOURCES = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1dgst.c \ - gnupgparse.c resize.c dotlock.c pop.c remailer.c remailer.h browser.h \ - mbyte.h +EXTRA_mutt_SOURCES = account.c mutt_socket.c pop.c pgp.c pgpinvoke.c pgpkey.c \ + pgplib.c sha1dgst.c gnupgparse.c resize.c dotlock.c remailer.c \ + browser.h mbyte.h remailer.h -EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h attach.h \ - buffy.h charset.h copy.h dotlock.h functions.h gen_defs \ +EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \ + attach.h buffy.h charset.h copy.h dotlock.h functions.h gen_defs \ globals.h hash.h history.h init.h keymap.h \ mailbox.h mapping.h mime.h mutt.h mutt_curses.h mutt_menu.h \ - mutt_regex.h mx.h pager.h parse.h pgp.h protos.h \ + mutt_regex.h mutt_socket.h mx.h pager.h parse.h pgp.h protos.h \ reldate.h rfc1524.h rfc2047.h rfc2231.h rfc822.h sha.h sha_locl.h \ sort.h mime.types VERSION prepare _regex.h OPS.MIX \ README.SECURITY remailer.c remailer.h browser.h \ mbyte.h lib.h extlib.c pgpewrap pgplib.h Muttrc.head Muttrc \ makedoc.c stamp-doc-rc README.SSL README.UPGRADE - mutt_dotlock_SOURCES = mutt_dotlock.c mutt_dotlock_LDADD = @LIBOBJS@ mutt_dotlock_DEPENDENCIES = @LIBOBJS@ @@ -80,7 +79,6 @@ pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1dgst.c pgpring_LDADD = @LIBOBJS@ $(INTLLIBS) pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS) - mutt_dotlock.c: dotlock.c cp $(srcdir)/dotlock.c mutt_dotlock.c diff --git a/acconfig.h b/acconfig.h index 04e5d59aa..c31c44c3e 100644 --- a/acconfig.h +++ b/acconfig.h @@ -36,6 +36,10 @@ */ #undef NFS_ATTRIBUTE_HACK +/* Include code for socket support. Set automatically if you enable pop or + * IMAP */ +#undef USE_SOCKET + /* Do you want support for the POP3 protocol? (--enable-pop) */ #undef USE_POP diff --git a/account.c b/account.c new file mode 100644 index 000000000..52bb58a13 --- /dev/null +++ b/account.c @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2000 Brendan Cully + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + */ + +/* remote host account manipulation (POP/IMAP) */ + +#include "account.h" +#include "mutt.h" + +/* mutt_account_match: compare account info (host/port/user) */ +int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* a2) +{ + const char* user = NONULL (Username); + + if (a1->type != a2->type) + return 0; + if (mutt_strcasecmp (a1->host, a2->host)) + return 0; + if (a1->port != a2->port) + return 0; + +#ifdef USE_IMAP + if (a1->type == M_ACCT_TYPE_IMAP && ImapUser) + user = ImapUser; +#endif + +#ifdef USE_POP + if (a1->type == M_ACCT_TYPE_POP && PopUser) + user = PopUser; +#endif + + if (a1->flags & a2->flags & M_ACCT_USER) + return (!strcmp (a1->user, a2->user)); + if (a1->flags & M_ACCT_USER) + return (!strcmp (a1->user, user)); + if (a2->flags & M_ACCT_USER) + return (!strcmp (a2->user, user)); + + return 1; +} diff --git a/account.h b/account.h new file mode 100644 index 000000000..20c5e63a1 --- /dev/null +++ b/account.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2000 Brendan Cully + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + */ + +/* remote host account manipulation (POP/IMAP) */ + +#ifndef _MUTT_ACCOUNT_H_ +#define _MUTT_ACCOUNT_H_ 1 + +/* account types */ +enum +{ + M_ACCT_TYPE_NONE = 0, + M_ACCT_TYPE_IMAP, + M_ACCT_TYPE_POP +}; + +/* account flags */ +#define M_ACCT_PORT (1<<0) +#define M_ACCT_USER (1<<1) +#define M_ACCT_SSL (1<<2) +#define M_ACCT_CRAM (1<<3) +#define M_ACCT_PASS (1<<4) + +typedef struct +{ + char user[64]; + char pass[32]; + char host[128]; + unsigned short port; + unsigned char type; + unsigned char flags; +} ACCOUNT; + +/* imap_account_match: compare account info (host/port/user) */ +int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* m2); + +#endif /* _MUTT_ACCOUNT_H_ */ diff --git a/browser.c b/browser.c index 0e0c319cd..4d76352cc 100644 --- a/browser.c +++ b/browser.c @@ -527,7 +527,7 @@ void _mutt_select_file (char *f, size_t flen, int buffy, { init_state (&state, NULL); state.imap_browse = 1; - imap_init_browse (f, &state); + imap_browse (f, &state); strfcpy (LastDir, state.folder, sizeof (LastDir)); } else @@ -575,7 +575,7 @@ void _mutt_select_file (char *f, size_t flen, int buffy, { init_state (&state, NULL); state.imap_browse = 1; - imap_init_browse (LastDir, &state); + imap_browse (LastDir, &state); } #endif } @@ -715,7 +715,7 @@ void _mutt_select_file (char *f, size_t flen, int buffy, { init_state (&state, NULL); state.imap_browse = 1; - imap_init_browse (LastDir, &state); + imap_browse (LastDir, &state); menu->data = state.entry; } else @@ -879,7 +879,7 @@ void _mutt_select_file (char *f, size_t flen, int buffy, destroy_state (&state); init_state (&state, NULL); state.imap_browse = 1; - imap_init_browse (LastDir, &state); + imap_browse (LastDir, &state); menu->data = state.entry; menu->current = 0; menu->top = 0; @@ -958,7 +958,7 @@ void _mutt_select_file (char *f, size_t flen, int buffy, { init_state (&state, NULL); state.imap_browse = 1; - imap_init_browse (LastDir, &state); + imap_browse (LastDir, &state); menu->data = state.entry; init_menu (&state, menu, title, sizeof (title), buffy); } @@ -1043,7 +1043,7 @@ void _mutt_select_file (char *f, size_t flen, int buffy, { init_state (&state, NULL); state.imap_browse = 1; - imap_init_browse (LastDir, &state); + imap_browse (LastDir, &state); menu->data = state.entry; } #endif diff --git a/configure.in b/configure.in index f816bafcc..9954804be 100644 --- a/configure.in +++ b/configure.in @@ -530,27 +530,41 @@ AC_ARG_WITH(domain, [ --with-domain=DOMAIN Specify your DNS domain name ] AC_DEFINE_UNQUOTED(DOMAIN, "$withval") fi]) +need_socket="no" + +dnl -- socket dependencies -- + AC_ARG_ENABLE(pop, [ --enable-pop Enable POP3 support], [ if test x$enableval = xyes ; then AC_DEFINE(USE_POP) - AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) - AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pop.o" + need_socket="yes" fi ]) AC_ARG_ENABLE(imap, [ --enable-imap Enable IMAP support], [ if test x$enableval = xyes ; then AC_DEFINE(USE_IMAP) - AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) - AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) LIBIMAP="-Limap -limap" LIBIMAPDEPS="\$(top_srcdir)/imap/imap.h imap/libimap.a" need_imap="yes" + need_socket="yes" fi ]) AM_CONDITIONAL(BUILD_IMAP, test x$need_imap = xyes) +dnl -- end socket dependencies -- + +if test "$need_socket" = "yes" +then + AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt)) + AC_CHECK_FUNC(gethostent, , AC_CHECK_LIB(nsl, gethostent)) + AC_DEFINE(USE_SOCKET) + MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS account.o mutt_socket.o" +fi + +dnl -- imap dependencies -- + AC_ARG_WITH(gss, [ --with-gss[=DIR] Compile in GSSAPI authentication for IMAP], [ if test "$need_imap" != "yes" @@ -646,6 +660,8 @@ AC_ARG_WITH(ssl, [ --with-ssl[=PFX] Compile in SSL socket support for ]) AM_CONDITIONAL(USE_SSL, test x$need_ssl = xyes) +dnl -- end imap dependencies -- + AC_ARG_ENABLE(debug, [ --enable-debug Enable debugging support], [ if test x$enableval = xyes ; then AC_DEFINE(DEBUG) diff --git a/gettext.c b/gettext.c index 09cdef584..f32ccdf39 100644 --- a/gettext.c +++ b/gettext.c @@ -110,7 +110,7 @@ char *mutt_gettext (const char *message) orig = gettext (message); if (debugfile) - dprint (2, (debugfile, "mutt_gettext (`%s'): original gettext returned `%s'\n", + dprint (3, (debugfile, "mutt_gettext (`%s'): original gettext returned `%s'\n", message, orig)); if (!Messages) @@ -119,7 +119,7 @@ char *mutt_gettext (const char *message) if ((mp = hash_find (Messages, orig))) { if (debugfile) - dprint (2, (debugfile, "mutt_gettext: cache hit - key = `%s', data = `%s'\n", orig, mp->data)); + dprint (3, (debugfile, "mutt_gettext: cache hit - key = `%s', data = `%s'\n", orig, mp->data)); return mp->data; } @@ -130,7 +130,7 @@ char *mutt_gettext (const char *message) mutt_convert_string (&mp->data, PoCharset ? PoCharset : "utf-8", MessageCharset); if (debugfile) - dprint (2, (debugfile, "mutt_gettext: conversion done - src = `%s', res = `%s'\n", + dprint (3, (debugfile, "mutt_gettext: conversion done - src = `%s', res = `%s'\n", mp->key, mp->data)); hash_insert (Messages, mp->key, mp, 0); diff --git a/globals.h b/globals.h index e47e714b9..2e4031892 100644 --- a/globals.h +++ b/globals.h @@ -54,7 +54,6 @@ WHERE char *ImapCRAMKey INITVAL (NULL); WHERE char *ImapPass INITVAL (NULL); WHERE short ImapCheckTimeout; WHERE char *ImapHomeNamespace INITVAL (NULL); -WHERE char *ImapPreconnect INITVAL (NULL); #endif WHERE char *InReplyTo; WHERE char *Inbox; @@ -64,6 +63,10 @@ WHERE char *MailcapPath; WHERE char *Maildir; WHERE char *MsgFmt; +#ifdef USE_SOCKET +WHERE char *Preconnect INITVAL (NULL); +#endif /* USE_SOCKET */ + #ifdef MIXMASTER WHERE char *Mixmaster; WHERE char *MixEntryFormat; diff --git a/imap/Makefile.am b/imap/Makefile.am index 124893b2e..5ff4d388b 100644 --- a/imap/Makefile.am +++ b/imap/Makefile.am @@ -16,7 +16,7 @@ EXTRA_DIST = BUGS README TODO imap_ssl.c imap_ssl.h auth_gss.c INCLUDES = -I$(top_srcdir) -I../intl noinst_LIBRARIES = libimap.a -noinst_HEADERS = imap_private.h imap_socket.h md5.h message.h $(SSLHEADERS) +noinst_HEADERS = imap_private.h md5.h message.h $(SSLHEADERS) libimap_a_SOURCES = auth.c browse.c command.c imap.c imap.h md5c.c message.c \ - socket.c utf7.c util.c $(GSSSOURCES) $(SSLSOURCES) + utf7.c util.c $(GSSSOURCES) $(SSLSOURCES) diff --git a/imap/auth.c b/imap/auth.c index 77f25c0d4..0c8577614 100644 --- a/imap/auth.c +++ b/imap/auth.c @@ -242,18 +242,20 @@ static int imap_auth_anon (IMAP_DATA* idata) * Unavailable: * KERBEROS_V4. Superceded by GSSAPI. */ -int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) +int imap_authenticate (IMAP_DATA* idata) { char buf[LONG_STRING]; char user[SHORT_STRING], q_user[SHORT_STRING]; char ckey[SHORT_STRING]; char pass[SHORT_STRING], q_pass[SHORT_STRING]; + CONNECTION* conn = idata->conn; + int r = 1; while (r != 0) { - if (! (conn->mx.flags & M_IMAP_USER)) + if (! (conn->account.flags & M_ACCT_USER)) { if (!ImapUser) { @@ -268,7 +270,7 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) strfcpy (user, ImapUser, sizeof (user)); } else - strfcpy (user, conn->mx.user, sizeof (user)); + strfcpy (user, conn->account.user, sizeof (user)); if (!user[0]) { @@ -300,13 +302,13 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) /* attempt CRAM-MD5 if available */ if (mutt_bit_isset (idata->capabilities, ACRAM_MD5)) { - if (!(conn->mx.flags & M_IMAP_CRAM)) + if (!(conn->account.flags & M_ACCT_CRAM)) { if (!ImapCRAMKey) { ckey[0] = '\0'; snprintf (buf, sizeof (buf), _("CRAM key for %s@%s: "), user, - conn->mx.host); + conn->account.host); if (mutt_get_field (buf, ckey, sizeof (ckey), M_PASS) != 0) return -1; } @@ -314,7 +316,7 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) strfcpy (ckey, ImapCRAMKey, sizeof (ckey)); } else - strfcpy (ckey, conn->mx.pass, sizeof (ckey)); + strfcpy (ckey, conn->account.pass, sizeof (ckey)); if (*ckey) { @@ -322,14 +324,14 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) { mutt_error _("CRAM-MD5 authentication failed."); sleep (1); - if (!(conn->mx.flags & M_IMAP_CRAM)) + if (!(conn->account.flags & M_ACCT_CRAM)) FREE (&ImapCRAMKey); - conn->mx.flags &= ~M_IMAP_CRAM; + conn->account.flags &= ~M_ACCT_CRAM; } else { - strfcpy (conn->mx.pass, ckey, sizeof (conn->mx.pass)); - conn->mx.flags |= M_IMAP_CRAM; + strfcpy (conn->account.pass, ckey, sizeof (conn->account.pass)); + conn->account.flags |= M_ACCT_CRAM; return 0; } } @@ -342,13 +344,13 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) else dprint (2, (debugfile, "CRAM-MD5 authentication is not available\n")); - if (! (conn->mx.flags & M_IMAP_PASS)) + if (! (conn->account.flags & M_ACCT_PASS)) { if (!ImapPass) { pass[0]=0; snprintf (buf, sizeof (buf), _("Password for %s@%s: "), user, - conn->mx.host); + conn->account.host); if (mutt_get_field (buf, pass, sizeof (pass), M_PASS) != 0 || !pass[0]) return -1; @@ -357,7 +359,7 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) strfcpy (pass, ImapPass, sizeof (pass)); } else - strfcpy (pass, conn->mx.pass, sizeof (pass)); + strfcpy (pass, conn->account.pass, sizeof (pass)); imap_quote_string (q_user, sizeof (q_user), user); imap_quote_string (q_pass, sizeof (q_pass), pass); @@ -387,22 +389,22 @@ int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn) mutt_error _("Login failed."); sleep (1); - if (!(conn->mx.flags & M_IMAP_USER)) + if (!(conn->account.flags & M_ACCT_USER)) FREE (&ImapUser); - if (!(conn->mx.flags & M_IMAP_PASS)) + if (!(conn->account.flags & M_ACCT_PASS)) FREE (&ImapPass); - conn->mx.flags &= ~M_IMAP_PASS; + conn->account.flags &= ~M_ACCT_PASS; } else { /* If they have a successful login, we may as well cache the * user/password. */ - if (!(conn->mx.flags & M_IMAP_USER)) - strfcpy (conn->mx.user, user, sizeof (conn->mx.user)); - if (!(conn->mx.flags & M_IMAP_PASS)) - strfcpy (conn->mx.pass, pass, sizeof (conn->mx.pass)); + if (!(conn->account.flags & M_ACCT_USER)) + strfcpy (conn->account.user, user, sizeof (conn->account.user)); + if (!(conn->account.flags & M_ACCT_PASS)) + strfcpy (conn->account.pass, pass, sizeof (conn->account.pass)); - conn->mx.flags |= (M_IMAP_USER | M_IMAP_PASS); + conn->account.flags |= (M_ACCT_USER | M_ACCT_PASS); } } return 0; diff --git a/imap/auth_gss.c b/imap/auth_gss.c index effe47dd4..48a8ba1f2 100644 --- a/imap/auth_gss.c +++ b/imap/auth_gss.c @@ -57,7 +57,7 @@ int imap_auth_gss (IMAP_DATA* idata, const char* user) dprint (2, (debugfile, "Attempting GSS login...\n")); /* get an IMAP service ticket for the server */ - snprintf (buf1, sizeof (buf1), "imap@%s", idata->conn->mx.host); + snprintf (buf1, sizeof (buf1), "imap@%s", idata->conn->account.host); request_buf.value = buf1; request_buf.length = strlen (buf1) + 1; maj_stat = gss_import_name (&min_stat, &request_buf, gss_nt_service_name, diff --git a/imap/browse.c b/imap/browse.c index f039fb9d8..0f0dfebc4 100644 --- a/imap/browse.c +++ b/imap/browse.c @@ -26,7 +26,7 @@ #include "imap_private.h" /* -- forward declarations -- */ -static int browse_add_list_result (CONNECTION* conn, const char* cmd, +static int browse_add_list_result (IMAP_DATA* idata, const char* cmd, struct browser_state* state, short isparent); static void imap_add_folder (char delim, char *folder, int noselect, int noinferiors, struct browser_state *state, short isparent); @@ -36,7 +36,7 @@ static int browse_get_namespace (IMAP_DATA *idata, char *nsbuf, int nsblen, static int browse_verify_namespace (IMAP_DATA* idata, IMAP_NAMESPACE_INFO* nsi, int nns); -int imap_init_browse (char *path, struct browser_state *state) +int imap_browse (char* path, struct browser_state* state) { CONNECTION *conn; IMAP_DATA *idata; @@ -65,8 +65,8 @@ int imap_init_browse (char *path, struct browser_state *state) strfcpy (list_cmd, option (OPTIMAPLSUB) ? "LSUB" : "LIST", sizeof (list_cmd)); - conn = mutt_socket_find (&mx, 0); - idata = CONN_DATA; + conn = mutt_socket_find (&(mx.account), 0); + idata = (IMAP_DATA*) conn->data; if (!idata || (idata->state == IMAP_DISCONNECTED)) { @@ -77,7 +77,7 @@ int imap_init_browse (char *path, struct browser_state *state) conn->data = idata; idata->conn = conn; } - if (imap_open_connection (idata, conn)) + if (imap_open_connection (idata)) return -1; } @@ -138,7 +138,7 @@ int imap_init_browse (char *path, struct browser_state *state) imap_cmd_start (idata, buf); do { - if (imap_parse_list_response(conn, buf, sizeof(buf), &cur_folder, + if (imap_parse_list_response(idata, buf, sizeof(buf), &cur_folder, &noselect, &noinferiors, &(idata->delim)) != 0) return -1; @@ -229,14 +229,14 @@ int imap_init_browse (char *path, struct browser_state *state) * namespace is not "", so we have to list it explicitly. We ask the * server to see if it has descendants. */ dprint (4, (debugfile, "imap_init_browse: adding INBOX\n")); - if (browse_add_list_result (conn, "LIST \"\" \"INBOX\"", state, 0)) + if (browse_add_list_result (idata, "LIST \"\" \"INBOX\"", state, 0)) return -1; } nsup = state->entrylen; snprintf (buf, sizeof (buf), "%s \"\" \"%s%%\"", list_cmd, mbox); - if (browse_add_list_result (conn, buf, state, 0)) + if (browse_add_list_result (idata, buf, state, 0)) return -1; qsort(&(state->entry[nsup]),state->entrylen-nsup,sizeof(state->entry[0]), @@ -256,10 +256,9 @@ int imap_init_browse (char *path, struct browser_state *state) return 0; } -static int browse_add_list_result (CONNECTION* conn, const char* cmd, +static int browse_add_list_result (IMAP_DATA* idata, const char* cmd, struct browser_state* state, short isparent) { - IMAP_DATA* idata = CONN_DATA; char buf[LONG_STRING]; char *name; int noselect; @@ -277,7 +276,7 @@ static int browse_add_list_result (CONNECTION* conn, const char* cmd, do { - if (imap_parse_list_response(conn, buf, sizeof(buf), &name, + if (imap_parse_list_response(idata, buf, sizeof(buf), &name, &noselect, &noinferiors, &(idata->delim)) != 0) return -1; @@ -494,7 +493,7 @@ static int browse_verify_namespace (IMAP_DATA* idata, nsi->home_namespace = 0; do { - if (imap_parse_list_response(idata->conn, buf, sizeof(buf), &name, + if (imap_parse_list_response(idata, buf, sizeof(buf), &name, &(nsi->noselect), &(nsi->noinferiors), &delim) != 0) return -1; nsi->listable |= (name != NULL); diff --git a/imap/imap.c b/imap/imap.c index e446d03bc..f17e19ef8 100644 --- a/imap/imap.c +++ b/imap/imap.c @@ -37,7 +37,7 @@ #include /* imap forward declarations */ -static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn); +static int imap_get_delim (IMAP_DATA *idata); static char* imap_get_flags (LIST** hflags, char* s); static int imap_check_acl (IMAP_DATA *idata); static int imap_check_capabilities (IMAP_DATA *idata); @@ -70,6 +70,33 @@ int imap_delete_mailbox (CONTEXT* ctx, char* mailbox) return 0; } +/* imap_logout_all: close all open connections. Quick and dirty until we can + * make sure we've got all the context we need. */ +void imap_logout_all (void) +{ + CONNECTION* conn; + CONNECTION* tmp; + + conn = mutt_socket_head (); + + while (conn) + { + tmp = conn; + + if (conn->account.type == M_ACCT_TYPE_IMAP && conn->up) + { + mutt_message (_("Closing connection to %s..."), conn->account.host); + imap_logout ((IMAP_DATA*) conn->data); + mutt_clear_error (); + mutt_socket_close (conn); + + mutt_socket_free (tmp); + } + + conn = conn->next; + } +} + /* imap_parse_date: date is of the form: DD-MMM-YYYY HH:MM:SS +ZZzz */ time_t imap_parse_date (char *s) { @@ -121,7 +148,7 @@ time_t imap_parse_date (char *s) /* imap_read_literal: read bytes bytes from server into file. Not explicitly * buffered, relies on FILE buffering. NOTE: strips \r from \r\n. * Apparently even literals use \r\n-terminated strings ?! */ -int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes) +int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes) { long pos; char c; @@ -132,7 +159,7 @@ int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes) for (pos = 0; pos < bytes; pos++) { - if (mutt_socket_readchar (conn, &c) != 1) + if (mutt_socket_readchar (idata->conn, &c) != 1) { dprint (1, (debugfile, "imap_read_literal: error during read, %ld bytes read\n", pos)); return -1; @@ -356,7 +383,7 @@ int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint) return 0; } -static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn) +static int imap_get_delim (IMAP_DATA *idata) { char buf[LONG_STRING]; char *s; @@ -369,10 +396,8 @@ static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn) do { - if (mutt_socket_readln (buf, sizeof (buf), conn) < 0) - { - return (-1); - } + if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0) + return -1; if (buf[0] == '*') { @@ -388,13 +413,13 @@ static int imap_get_delim (IMAP_DATA *idata, CONNECTION *conn) } else { - if (conn->data && - imap_handle_untagged (idata, buf) != 0) - return (-1); + if (imap_handle_untagged (idata, buf) != 0) + return -1; } } } while ((mutt_strncmp (buf, idata->seq, SEQLEN) != 0)); + return 0; } @@ -433,18 +458,18 @@ static int imap_check_capabilities (IMAP_DATA *idata) return 0; } -int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn) +int imap_open_connection (IMAP_DATA* idata) { char buf[LONG_STRING]; - if (mutt_socket_open (conn) < 0) + if (mutt_socket_open (idata->conn) < 0) return -1; idata->state = IMAP_CONNECTED; - if (mutt_socket_readln (buf, sizeof (buf), conn) < 0) + if (mutt_socket_readln (buf, sizeof (buf), idata->conn) < 0) { - mutt_socket_close (conn); + mutt_socket_close (idata->conn); idata->state = IMAP_DISCONNECTED; return -1; @@ -453,9 +478,9 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn) if (mutt_strncmp ("* OK", buf, 4) == 0) { if (imap_check_capabilities(idata) != 0 - || imap_authenticate (idata, conn) != 0) + || imap_authenticate (idata) != 0) { - mutt_socket_close (conn); + mutt_socket_close (idata->conn); idata->state = IMAP_DISCONNECTED; return -1; } @@ -464,7 +489,7 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn) { if (imap_check_capabilities(idata) != 0) { - mutt_socket_close (conn); + mutt_socket_close (idata->conn); idata->state = IMAP_DISCONNECTED; return -1; } @@ -472,14 +497,14 @@ int imap_open_connection (IMAP_DATA *idata, CONNECTION *conn) else { imap_error ("imap_open_connection()", buf); - mutt_socket_close (conn); + mutt_socket_close (idata->conn); idata->state = IMAP_DISCONNECTED; return -1; } idata->state = IMAP_AUTHENTICATED; - imap_get_delim (idata, conn); + imap_get_delim (idata); return 0; } @@ -540,7 +565,7 @@ static char* imap_get_flags (LIST** hflags, char* s) return s; } -int imap_open_mailbox (CONTEXT *ctx) +int imap_open_mailbox (CONTEXT* ctx) { CONNECTION *conn; IMAP_DATA *idata; @@ -556,8 +581,8 @@ int imap_open_mailbox (CONTEXT *ctx) return -1; } - conn = mutt_socket_find (&mx, 0); - idata = CONN_DATA; + conn = mutt_socket_find (&(mx.account), 0); + idata = (IMAP_DATA*) conn->data; if (!idata || (idata->state != IMAP_AUTHENTICATED)) { @@ -567,11 +592,11 @@ int imap_open_mailbox (CONTEXT *ctx) /* We need to create a new connection, the current one isn't useful */ idata = safe_calloc (1, sizeof (IMAP_DATA)); - conn = mutt_socket_find (&mx, 1); + conn = mutt_socket_find (&(mx.account), 1); conn->data = idata; idata->conn = conn; } - if (imap_open_connection (idata, conn)) + if (imap_open_connection (idata)) return -1; } ctx->data = (void *) idata; @@ -727,18 +752,18 @@ int imap_open_mailbox (CONTEXT *ctx) int imap_select_mailbox (CONTEXT* ctx, const char* path) { IMAP_DATA* idata; - CONNECTION* conn; char curpath[LONG_STRING]; IMAP_MBOX mx; + idata = CTX_DATA; + strfcpy (curpath, path, sizeof (curpath)); /* check that the target folder makes sense */ if (imap_parse_path (curpath, &mx)) return -1; /* and that it's on the same server as the current folder */ - conn = mutt_socket_find (&mx, 0); - if (!CTX_DATA || !CONN_DATA || (CTX_DATA->conn != CONN_DATA->conn)) + if (!mutt_account_match (&(mx.account), &(idata->conn->account))) { dprint(2, (debugfile, "imap_select_mailbox: source server is not target server\n")); @@ -767,12 +792,12 @@ int imap_open_mailbox_append (CONTEXT *ctx) IMAP_MBOX mx; if (imap_parse_path (ctx->path, &mx)) - return (-1); + return -1; ctx->magic = M_IMAP; - conn = mutt_socket_find (&mx, 0); - idata = CONN_DATA; + conn = mutt_socket_find (&(mx.account), 0); + idata = (IMAP_DATA*) conn->data; if (!idata || (idata->state == IMAP_DISCONNECTED)) { @@ -783,8 +808,8 @@ int imap_open_mailbox_append (CONTEXT *ctx) conn->data = idata; idata->conn = conn; } - if (imap_open_connection (idata, conn)) - return (-1); + if (imap_open_connection (idata)) + return -1; } ctx->data = (void *) idata; @@ -1194,7 +1219,7 @@ int imap_check_mailbox (CONTEXT *ctx, int *index_hint) /* returns count of recent messages if new = 1, else count of total messages. * (useful for at least postponed function) * Question of taste: use RECENT or UNSEEN for new? */ -int imap_mailbox_check (char *path, int new) +int imap_mailbox_check (char* path, int new) { CONNECTION *conn; IMAP_DATA *idata; @@ -1208,8 +1233,8 @@ int imap_mailbox_check (char *path, int new) if (imap_parse_path (path, &mx)) return -1; - conn = mutt_socket_find (&mx, 0); - idata = CONN_DATA; + conn = mutt_socket_find (&(mx.account), 0); + idata = (IMAP_DATA*) conn->data; if (!idata || (idata->state == IMAP_DISCONNECTED)) { @@ -1224,7 +1249,7 @@ int imap_mailbox_check (char *path, int new) conn->data = idata; idata->conn = conn; } - if (imap_open_connection (idata, conn)) + if (imap_open_connection (idata)) return -1; } @@ -1301,16 +1326,15 @@ int imap_mailbox_check (char *path, int new) return msgcount; } -int imap_parse_list_response(CONNECTION *conn, char *buf, int buflen, +int imap_parse_list_response(IMAP_DATA* idata, char *buf, int buflen, char **name, int *noselect, int *noinferiors, char *delim) { - IMAP_DATA *idata = CONN_DATA; char *s; long bytes; *name = NULL; - if (mutt_socket_readln (buf, buflen, conn) < 0) + if (mutt_socket_readln (buf, buflen, idata->conn) < 0) return -1; if (buf[0] == '*') @@ -1358,7 +1382,7 @@ int imap_parse_list_response(CONNECTION *conn, char *buf, int buflen, if (imap_get_literal_count(buf, &bytes) < 0) return -1; - len = mutt_socket_readln (buf, buflen, conn); + len = mutt_socket_readln (buf, buflen, idata->conn); if (len < 0) return -1; *name = buf; @@ -1385,10 +1409,10 @@ int imap_subscribe (char *path, int subscribe) IMAP_MBOX mx; if (imap_parse_path (path, &mx)) - return (-1); + return -1; - conn = mutt_socket_find (&mx, 0); - idata = CONN_DATA; + conn = mutt_socket_find (&(mx.account), 0); + idata = (IMAP_DATA*) conn->data; if (!idata || (idata->state == IMAP_DISCONNECTED)) { @@ -1399,7 +1423,7 @@ int imap_subscribe (char *path, int subscribe) conn->data = idata; idata->conn = conn; } - if (imap_open_connection (idata, conn)) + if (imap_open_connection (idata)) return -1; } @@ -1442,8 +1466,8 @@ int imap_complete(char* dest, size_t dlen, char* path) { return -1; } - conn = mutt_socket_find (&mx, 0); - idata = CONN_DATA; + conn = mutt_socket_find (&(mx.account), 0); + idata = (IMAP_DATA*) conn->data; /* don't open a new socket just for completion */ if (!idata) @@ -1470,7 +1494,7 @@ int imap_complete(char* dest, size_t dlen, char* path) { strfcpy (completion, mx.mbox, sizeof(completion)); do { - if (imap_parse_list_response(conn, buf, sizeof(buf), &list_word, + if (imap_parse_list_response(idata, buf, sizeof(buf), &list_word, &noselect, &noinferiors, &delim)) break; diff --git a/imap/imap.h b/imap/imap.h index 2b0b5b744..c4997a105 100644 --- a/imap/imap.h +++ b/imap/imap.h @@ -19,22 +19,17 @@ #ifndef _IMAP_H #define _IMAP_H 1 +#include "account.h" #include "browser.h" #include "mailbox.h" +/* -- data structures -- */ typedef struct { - char user[64]; - char pass[32]; - char host[128]; - int port; - char type[16]; - int socktype; - char *mbox; - int flags; + ACCOUNT account; + char* mbox; } IMAP_MBOX; - /* imap.c */ int imap_check_mailbox (CONTEXT *ctx, int *index_hint); int imap_create_mailbox (CONTEXT* idata, char* mailbox); @@ -54,7 +49,7 @@ void imap_allow_reopen (CONTEXT *ctx); void imap_disallow_reopen (CONTEXT *ctx); /* browse.c */ -int imap_init_browse (char *path, struct browser_state *state); +int imap_browse (char* path, struct browser_state* state); /* message.c */ int imap_append_message (CONTEXT* ctx, MESSAGE* msg); @@ -65,8 +60,8 @@ int imap_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno); void imap_logout_all (void); /* util.c */ -int imap_parse_path (const char* path, IMAP_MBOX *mx); -void imap_qualify_path (char* dest, size_t len, const IMAP_MBOX *mx, +int imap_parse_path (const char* path, IMAP_MBOX* mx); +void imap_qualify_path (char* dest, size_t len, const IMAP_MBOX* mx, const char* path, const char* name); int imap_wait_keepalive (pid_t pid); diff --git a/imap/imap_private.h b/imap/imap_private.h index ea55e25be..f2639ab8e 100644 --- a/imap/imap_private.h +++ b/imap/imap_private.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1996-9 Brandon Long - * Copyright (C) 1999 Brendan Cully + * Copyright (C) 1999-2000 Brendan Cully * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ #define _IMAP_PRIVATE_H 1 #include "imap.h" -#include "imap_socket.h" +#include "mutt_socket.h" /* -- symbols -- */ #define IMAP_PORT 143 @@ -37,12 +37,6 @@ #define SEQLEN 5 -#define M_IMAP_USER (1<<0) -#define M_IMAP_PORT (1<<1) -#define M_IMAP_TYPE (1<<2) -#define M_IMAP_PASS (1<<3) -#define M_IMAP_CRAM (1<<4) - #define IMAP_REOPEN_ALLOW (1<<0) #define IMAP_REOPEN_PENDING (1<<1) #define IMAP_NEWMAIL_PENDING (1<<2) @@ -166,22 +160,21 @@ typedef struct /* -- macros -- */ #define CTX_DATA ((IMAP_DATA *) ctx->data) -#define CONN_DATA ((IMAP_DATA *) conn->data) /* -- private IMAP functions -- */ /* imap.c */ int imap_make_msg_set (char* buf, size_t buflen, CONTEXT* ctx, int flag, int changed); -int imap_open_connection (IMAP_DATA* idata, CONNECTION* conn); +int imap_open_connection (IMAP_DATA* idata); time_t imap_parse_date (char* s); -int imap_parse_list_response(CONNECTION* conn, char* buf, int buflen, +int imap_parse_list_response(IMAP_DATA* idata, char* buf, int buflen, char** name, int* noselect, int* noinferiors, char* delim); -int imap_read_literal (FILE* fp, CONNECTION* conn, long bytes); +int imap_read_literal (FILE* fp, IMAP_DATA* idata, long bytes); int imap_reopen_mailbox (CONTEXT *ctx, int *index_hint); -void imap_logout (IMAP_DATA* conn); +void imap_logout (IMAP_DATA* idata); /* auth.c */ -int imap_authenticate (IMAP_DATA *idata, CONNECTION *conn); +int imap_authenticate (IMAP_DATA* idata); /* command.c */ void imap_cmd_start (IMAP_DATA* idata, const char* cmd); @@ -197,7 +190,6 @@ void imap_free_header_data (void** data); int imap_read_headers (CONTEXT* ctx, int msgbegin, int msgend); /* util.c */ -int imap_account_match (const IMAP_MBOX* m1, const IMAP_MBOX* m2); int imap_continue (const char* msg, const char* resp); void imap_error (const char* where, const char* msg); char* imap_fix_path (IMAP_DATA* idata, char* mailbox, char* path, diff --git a/imap/imap_ssl.c b/imap/imap_ssl.c index a805c3319..1a97499eb 100644 --- a/imap/imap_ssl.c +++ b/imap/imap_ssl.c @@ -31,7 +31,7 @@ #include "mutt.h" #include "imap.h" #include "imap_private.h" -#include "imap_socket.h" +#include "mutt_socket.h" #include "mutt_menu.h" #include "mutt_curses.h" #include "imap_ssl.h" @@ -144,12 +144,11 @@ static int add_entropy (const char *file) return n; } -void imap_set_ssl (IMAP_MBOX *mx) +void imap_set_ssl (ACCOUNT* account) { - if (! (mx->flags & M_IMAP_PORT)) - mx->port = IMAP_SSL_PORT; - mx->socktype = M_NEW_SSL_SOCKET; - mx->flags |= M_IMAP_TYPE; + if (! (account->flags & M_ACCT_PORT)) + account->port = IMAP_SSL_PORT; + account->flags |= M_ACCT_SSL; } static int ssl_socket_open_err (CONNECTION *conn) diff --git a/imap/imap_ssl.h b/imap/imap_ssl.h index 4ee7062d6..8c8ec747e 100644 --- a/imap/imap_ssl.h +++ b/imap/imap_ssl.h @@ -19,10 +19,12 @@ #ifndef _MUTT_SSL_H_ #define _MUTT_SSL_H_ 1 +#include "mutt_socket.h" + extern char *SslCertFile; extern char *SslEntropyFile; extern int ssl_socket_setup (CONNECTION *conn); -extern void imap_set_ssl (IMAP_MBOX *mx); +extern void imap_set_ssl (ACCOUNT* account); -#endif +#endif /* _MUTT_SSL_H_ */ diff --git a/imap/message.c b/imap/message.c index 72574b4df..954a1d677 100644 --- a/imap/message.c +++ b/imap/message.c @@ -261,7 +261,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno) imap_error ("imap_fetch_message()", buf); goto bail; } - if (imap_read_literal (msg->fp, CTX_DATA->conn, bytes) < 0) + if (imap_read_literal (msg->fp, CTX_DATA, bytes) < 0) goto bail; /* pick up trailing line */ if (mutt_socket_readln (buf, sizeof (buf), CTX_DATA->conn) < 0) @@ -499,7 +499,7 @@ int imap_copy_messages (CONTEXT* ctx, HEADER* h, char* dest, int delete) } /* check that the save-to folder is in the same account */ - if (!imap_account_match (&(CTX_DATA->conn->mx), &mx)) + if (!mutt_account_match (&(CTX_DATA->conn->account), &(mx.account))) { dprint (3, (debugfile, "imap_copy_message: %s not same server as %s\n", dest, ctx->path)); @@ -647,7 +647,7 @@ static int msg_fetch_header (CONTEXT* ctx, IMAP_HEADER* h, char* buf, FILE* fp) if (imap_get_literal_count (buf, &bytes) < 0) return rc; - imap_read_literal (fp, CTX_DATA->conn, bytes); + imap_read_literal (fp, CTX_DATA, bytes); /* we may have other fields of the FETCH _after_ the literal * (eg Domino puts FLAGS here). Nothing wrong with that, either. diff --git a/imap/util.c b/imap/util.c index e6e15d381..958c87493 100644 --- a/imap/util.c +++ b/imap/util.c @@ -34,26 +34,6 @@ #include -/* imap_account_match: compare account info (host/port/user) */ -int imap_account_match (const IMAP_MBOX* m1, const IMAP_MBOX* m2) -{ - const char* user = ImapUser ? ImapUser : NONULL (Username); - - if (mutt_strcasecmp (m1->host, m2->host)) - return 0; - if (m1->port != m2->port) - return 0; - - if (m1->flags & m2->flags & M_IMAP_USER) - return (!strcmp (m1->user, m2->user)); - if (m1->flags & M_IMAP_USER) - return (!strcmp (m1->user, user)); - if (m2->flags & M_IMAP_USER) - return (!strcmp (m2->user, user)); - - return 1; -} - /* imap_continue: display a message and ask the user if she wants to * go on. */ int imap_continue (const char* msg, const char* resp) @@ -148,17 +128,17 @@ char *imap_next_word (char *s) /* imap_parse_path: given an IMAP mailbox name, return host, port * and a path IMAP servers will recognise. */ -int imap_parse_path (const char *path, IMAP_MBOX *mx) +int imap_parse_path (const char* path, IMAP_MBOX* mx) { char tmp[128]; char *c; int n; - mx->type[0] = '\0'; if (sscanf (path, "{%128[^}]}", tmp) != 1) - { return -1; - } + + mx->account.type = M_ACCT_TYPE_IMAP; + c = strchr (path, '}'); if (!c) return -1; @@ -167,44 +147,43 @@ int imap_parse_path (const char *path, IMAP_MBOX *mx) mx->mbox = safe_strdup (c+1); /* Defaults */ - mx->flags = 0; - mx->port = IMAP_PORT; - mx->socktype = M_NEW_SOCKET; + mx->account.flags = 0; + mx->account.port = IMAP_PORT; if ((c = strrchr (tmp, '@'))) { *c = '\0'; - strfcpy (mx->user, tmp, sizeof (mx->user)); + strfcpy (mx->account.user, tmp, sizeof (mx->account.user)); strfcpy (tmp, c+1, sizeof (tmp)); - mx->flags |= M_IMAP_USER; + mx->account.flags |= M_ACCT_USER; } - if ((n = sscanf (tmp, "%128[^:/]%128s", mx->host, tmp)) < 1) + if ((n = sscanf (tmp, "%128[^:/]%128s", mx->account.host, tmp)) < 1) { dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path)); return -1; } if (n > 1) { - if (sscanf (tmp, ":%d%128s", &mx->port, tmp) >= 1) - mx->flags |= M_IMAP_PORT; - if (sscanf (tmp, "/%s", mx->type) == 1) + if (sscanf (tmp, ":%hd%128s", &(mx->account.port), tmp) >= 1) + mx->account.flags |= M_ACCT_PORT; + if (sscanf (tmp, "/%s", tmp) == 1) { #ifdef USE_SSL - if (!strcmp (mx->type, "ssl")) - imap_set_ssl (mx); + if (!strncmp (tmp, "ssl", 3)) + imap_set_ssl (&(mx->account)); else #endif { dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path)); - return (-1); + return -1; } } } #ifdef USE_SSL if (option (OPTIMAPFORCESSL)) - imap_set_ssl (mx); + imap_set_ssl (&(mx->account)); #endif return 0; @@ -220,24 +199,20 @@ void imap_qualify_path (char *dest, size_t len, const IMAP_MBOX *mx, char tmp[128]; strcpy (dest, "{"); - if ((mx->flags & M_IMAP_USER) && (!ImapUser || strcmp (mx->user, ImapUser))) + if ((mx->account.flags & M_ACCT_USER) && (!ImapUser || strcmp (mx->account.user, ImapUser))) { - snprintf (tmp, sizeof (tmp), "%s@", mx->user); + snprintf (tmp, sizeof (tmp), "%s@", mx->account.user); strncat (dest, tmp, len); } - strncat (dest, mx->host, len); - if (mx->flags & M_IMAP_PORT) + strncat (dest, mx->account.host, len); + if (mx->account.flags & M_ACCT_PORT) { - snprintf (tmp, sizeof (tmp), ":%d", mx->port); + snprintf (tmp, sizeof (tmp), ":%d", mx->account.port); strncat (dest, tmp, len); } -#ifdef USE_SSL - if (mx->flags & M_IMAP_TYPE) - { - snprintf (tmp, sizeof (tmp), "/%s", mx->type); - strncat (dest, tmp, len); - } -#endif + if (mx->account.flags & M_ACCT_SSL) + strncat (dest, "/ssl", len); + snprintf (tmp, sizeof (tmp), "}%s%s", NONULL (path), NONULL (name)); strncat (dest, tmp, len); } diff --git a/init.c b/init.c index eba3331f2..533f8b71a 100644 --- a/init.c +++ b/init.c @@ -33,7 +33,6 @@ #ifdef USE_SSL #include "imap.h" -#include "imap_socket.h" #include "imap_ssl.h" #endif diff --git a/init.h b/init.h index 82c52916e..6f8b61342 100644 --- a/init.h +++ b/init.h @@ -95,6 +95,9 @@ struct option_t # ifndef USE_SSL # define USE_SSL # endif +# ifndef USE_SOCKET +# define USE_SOCKET +# endif #endif struct option_t MuttVars[] = { @@ -725,23 +728,6 @@ struct option_t MuttVars[] = { ** your INBOX in the IMAP browser. If you see something else, you may set ** this variable to the IMAP path to your folders. */ - { "imap_preconnect", DT_STR, R_NONE, UL &ImapPreconnect, UL 0}, - /* - ** .pp - ** If set, a shell command to be executed if mutt fails to establish - ** a connection to the server. This is useful for setting up secure - ** connections, e.g. with ssh(1). If the command returns a nonzero - ** status, mutt gives up opening the server. Example: - ** .pp - ** imap_preconnect="ssh -f -q -L 1234:mailhost.net:143 mailhost.net - ** sleep 20 < /dev/null > /dev/null" - ** .pp - ** Mailbox 'foo' on mailhost.net can now be reached - ** as '{localhost:1234}foo'. - ** .pp - ** NOTE: For this example to work, you must be able to log in to the - ** remote machine without having to enter a password. - */ #endif { "implicit_autoview", DT_BOOL,R_NONE, OPTIMPLICITAUTOVIEW, 0}, /* @@ -1481,6 +1467,25 @@ struct option_t MuttVars[] = { ** in the folder specified by this variable. Also see the ``$$postpone'' ** variable. */ +#ifdef USE_SOCKET + { "preconnect", DT_STR, R_NONE, UL &Preconnect, UL 0}, + /* + ** .pp + ** If set, a shell command to be executed if mutt fails to establish + ** a connection to the server. This is useful for setting up secure + ** connections, e.g. with ssh(1). If the command returns a nonzero + ** status, mutt gives up opening the server. Example: + ** .pp + ** preconnect="ssh -f -q -L 1234:mailhost.net:143 mailhost.net + ** sleep 20 < /dev/null > /dev/null" + ** .pp + ** Mailbox 'foo' on mailhost.net can now be reached + ** as '{localhost:1234}foo'. + ** .pp + ** NOTE: For this example to work, you must be able to log in to the + ** remote machine without having to enter a password. + */ +#endif /* USE_SOCKET */ { "print", DT_QUAD, R_NONE, OPT_PRINT, M_ASKNO }, /* ** .pp diff --git a/imap/socket.c b/mutt_socket.c similarity index 78% rename from imap/socket.c rename to mutt_socket.c index b70fc6986..48f3a0d26 100644 --- a/imap/socket.c +++ b/mutt_socket.c @@ -20,9 +20,7 @@ #include "mutt.h" #include "globals.h" -#include "imap.h" -#include "imap_socket.h" -#include "imap_private.h" +#include "mutt_socket.h" #ifdef USE_SSL #include "imap_ssl.h" #endif @@ -113,7 +111,41 @@ int mutt_socket_readln_d (char* buf, size_t buflen, CONNECTION* conn, int dbg) return i+1; } -CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn) +CONNECTION* mutt_socket_head (void) +{ + return Connections; +} + +/* mutt_socket_free: remove connection from connection list and free it */ +void mutt_socket_free (CONNECTION* conn) +{ + CONNECTION* iter; + CONNECTION* tmp; + + iter = Connections; + + /* head is special case, doesn't need prev updated */ + if (iter == conn) + { + Connections = iter->next; + FREE (&iter); + return; + } + + while (iter->next) + { + if (iter->next == conn) + { + tmp = iter->next; + iter->next = tmp->next; + FREE (&tmp); + return; + } + iter = iter->next; + } +} + +CONNECTION* mutt_socket_find (const ACCOUNT* account, int newconn) { CONNECTION* conn; @@ -122,24 +154,21 @@ CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn) conn = Connections; while (conn) { - if (imap_account_match (mx, &conn->mx)) + if (mutt_account_match (account, &(conn->account))) return conn; conn = conn->next; } } conn = socket_new_conn (); - memcpy (&conn->mx, mx, sizeof (conn->mx)); - conn->mx.mbox = 0; + memcpy (&conn->account, account, sizeof (ACCOUNT)); conn->next = Connections; Connections = conn; #ifdef USE_SSL - if (mx->socktype == M_NEW_SSL_SOCKET) - { + if (account->flags & M_ACCT_SSL) ssl_socket_setup (conn); - } else #endif { @@ -152,36 +181,6 @@ CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn) return conn; } -/* imap_logout_all: close all open connections. Quick and dirty until we can - * make sure we've got all the context we need. */ -void imap_logout_all (void) -{ - CONNECTION* conn; - - conn = Connections; - - while (conn) - { - if (conn->up) - { - mutt_message (_("Closing connection to %s..."), - conn->mx.host); - - imap_logout (CONN_DATA); - - mutt_clear_error (); - - mutt_socket_close (conn); - } - - Connections = conn->next; - - free (conn); - - conn = Connections; - } -} - /* socket_connect: attempt to bind a socket and connect to it */ static int socket_connect (CONNECTION* conn, struct sockaddr_in sin, int verbose) @@ -237,29 +236,29 @@ int raw_socket_write (CONNECTION *conn, const char *buf) return write (conn->fd, buf, mutt_strlen (buf)); } -int raw_socket_open (CONNECTION *conn) +int raw_socket_open (CONNECTION* conn) { struct sockaddr_in sin; struct hostent *he; int verbose; - int do_preconnect = mutt_strlen (ImapPreconnect) > 0; + int do_preconnect = mutt_strlen (Preconnect) > 0; /* This might be a config variable */ int first_try_without_preconnect = TRUE; - mutt_message (_("Looking up %s..."), conn->mx.host); + mutt_message (_("Looking up %s..."), conn->account.host); memset (&sin, 0, sizeof (sin)); - sin.sin_port = htons (conn->mx.port); + sin.sin_port = htons (conn->account.port); sin.sin_family = AF_INET; - if ((he = gethostbyname (conn->mx.host)) == NULL) + if ((he = gethostbyname (conn->account.host)) == NULL) { - mutt_error (_("Could not find the host \"%s\""), conn->mx.host); + mutt_error (_("Could not find the host \"%s\""), conn->account.host); return -1; } memcpy (&sin.sin_addr, he->h_addr_list[0], he->h_length); - mutt_message (_("Connecting to %s..."), conn->mx.host); + mutt_message (_("Connecting to %s..."), conn->account.host); if (do_preconnect && first_try_without_preconnect) { @@ -272,14 +271,14 @@ int raw_socket_open (CONNECTION *conn) { int ret; - dprint (1, (debugfile, "Preconnect to server %s:\n", conn->mx.host)); - dprint (1, (debugfile, "\t%s\n", ImapPreconnect)); + dprint (1, (debugfile, "Preconnect to server %s:\n", conn->account.host)); + dprint (1, (debugfile, "\t%s\n", Preconnect)); /* Execute preconnect command */ - ret = mutt_system (ImapPreconnect) < 0; + ret = mutt_system (Preconnect) < 0; dprint (1, (debugfile, "\t%s: %d\n", "Exit status", ret)); if (ret < 0) { - mutt_perror (_("IMAP Preconnect command failed")); + mutt_perror (_("Preconnect command failed.")); sleep (1); return ret; diff --git a/imap/imap_socket.h b/mutt_socket.h similarity index 76% rename from imap/imap_socket.h rename to mutt_socket.h index a5145427b..04ffe055e 100644 --- a/imap/imap_socket.h +++ b/mutt_socket.h @@ -17,12 +17,19 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ -#ifndef _IMAP_SOCKET_H_ -#define _IMAP_SOCKET_H_ 1 +#ifndef _MUTT_SOCKET_H_ +#define _MUTT_SOCKET_H_ 1 + +#include "account.h" + +/* logging levels */ +#define M_SOCK_LOG_CMD 2 +#define M_SOCK_LOG_HDR 3 +#define M_SOCK_LOG_FULL 4 typedef struct _connection { - IMAP_MBOX mx; + ACCOUNT account; char inbuf[LONG_STRING]; int bufpos; @@ -46,16 +53,19 @@ typedef struct _connection int mutt_socket_open (CONNECTION* conn); int mutt_socket_close (CONNECTION* conn); int mutt_socket_readchar (CONNECTION *conn, char *c); -#define mutt_socket_readln(A,B,C) mutt_socket_readln_d(A,B,C,IMAP_LOG_CMD) +#define mutt_socket_readln(A,B,C) mutt_socket_readln_d(A,B,C,M_SOCK_LOG_CMD) int mutt_socket_readln_d (char *buf, size_t buflen, CONNECTION *conn, int dbg); -#define mutt_socket_write(A,B) mutt_socket_write_d(A,B,IMAP_LOG_CMD); +#define mutt_socket_write(A,B) mutt_socket_write_d(A,B,M_SOCK_LOG_CMD); int mutt_socket_write_d (CONNECTION *conn, const char *buf, int dbg); -CONNECTION* mutt_socket_find (const IMAP_MBOX* mx, int newconn); +/* stupid hack for imap_logout_all */ +CONNECTION* mutt_socket_head (void); +void mutt_socket_free (CONNECTION* conn); +CONNECTION* mutt_socket_find (const ACCOUNT* mx, int newconn); int raw_socket_read (CONNECTION *conn); int raw_socket_write (CONNECTION *conn, const char *buf); int raw_socket_open (CONNECTION *conn); int raw_socket_close (CONNECTION *conn); -#endif /* _IMAP_SOCKET_H_ */ +#endif /* _MUTT_SOCKET_H_ */ diff --git a/po/POTFILES.in b/po/POTFILES.in index 67250c5de..41a8d86a4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -23,7 +23,6 @@ imap/command.c imap/imap.c imap/imap_ssl.c imap/message.c -imap/socket.c imap/util.c init.c keymap.c @@ -35,6 +34,7 @@ mbox.c menu.c mh.c muttlib.c +mutt_socket.c mx.c pager.c pager.h