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@
pgpring_LDADD = @LIBOBJS@ $(INTLLIBS)
pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS)
-
mutt_dotlock.c: dotlock.c
cp $(srcdir)/dotlock.c mutt_dotlock.c
*/
#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
--- /dev/null
+/*
+ * Copyright (C) 2000 Brendan Cully <brendan@kublai.com>
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * Copyright (C) 2000 Brendan Cully <brendan@kublai.com>
+ *
+ * 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_ */
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_init_browse (f, &state);
+ imap_browse (f, &state);
strfcpy (LastDir, state.folder, sizeof (LastDir));
}
else
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_init_browse (LastDir, &state);
+ imap_browse (LastDir, &state);
}
#endif
}
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_init_browse (LastDir, &state);
+ imap_browse (LastDir, &state);
menu->data = state.entry;
}
else
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;
{
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);
}
{
init_state (&state, NULL);
state.imap_browse = 1;
- imap_init_browse (LastDir, &state);
+ imap_browse (LastDir, &state);
menu->data = state.entry;
}
#endif
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"
])
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)
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)
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;
}
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);
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;
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;
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)
* 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)
{
strfcpy (user, ImapUser, sizeof (user));
}
else
- strfcpy (user, conn->mx.user, sizeof (user));
+ strfcpy (user, conn->account.user, sizeof (user));
if (!user[0])
{
/* 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;
}
strfcpy (ckey, ImapCRAMKey, sizeof (ckey));
}
else
- strfcpy (ckey, conn->mx.pass, sizeof (ckey));
+ strfcpy (ckey, conn->account.pass, sizeof (ckey));
if (*ckey)
{
{
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;
}
}
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;
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);
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;
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,
#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);
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;
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))
{
conn->data = idata;
idata->conn = conn;
}
- if (imap_open_connection (idata, conn))
+ if (imap_open_connection (idata))
return -1;
}
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;
* 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]),
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;
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;
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);
#include <sys/stat.h>
/* 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);
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)
{
/* 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;
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;
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;
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] == '*')
{
}
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;
}
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;
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;
}
{
if (imap_check_capabilities(idata) != 0)
{
- mutt_socket_close (conn);
+ mutt_socket_close (idata->conn);
idata->state = IMAP_DISCONNECTED;
return -1;
}
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;
}
return s;
}
-int imap_open_mailbox (CONTEXT *ctx)
+int imap_open_mailbox (CONTEXT* ctx)
{
CONNECTION *conn;
IMAP_DATA *idata;
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))
{
/* 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;
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"));
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))
{
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;
/* 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;
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))
{
conn->data = idata;
idata->conn = conn;
}
- if (imap_open_connection (idata, conn))
+ if (imap_open_connection (idata))
return -1;
}
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] == '*')
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;
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))
{
conn->data = idata;
idata->conn = conn;
}
- if (imap_open_connection (idata, conn))
+ if (imap_open_connection (idata))
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;
/* don't open a new socket just for completion */
if (!idata)
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;
#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);
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);
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);
/*
* Copyright (C) 1996-9 Brandon Long <blong@fiction.net>
- * Copyright (C) 1999 Brendan Cully <brendan@kublai.com>
+ * Copyright (C) 1999-2000 Brendan Cully <brendan@kublai.com>
*
* 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
#define _IMAP_PRIVATE_H 1
#include "imap.h"
-#include "imap_socket.h"
+#include "mutt_socket.h"
/* -- symbols -- */
#define IMAP_PORT 143
#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)
/* -- 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);
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,
#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"
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)
#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_ */
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)
}
/* 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));
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.
#include <errno.h>
-/* 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)
/* 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;
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;
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);
}
#ifdef USE_SSL
#include "imap.h"
-#include "imap_socket.h"
#include "imap_ssl.h"
#endif
# ifndef USE_SSL
# define USE_SSL
# endif
+# ifndef USE_SOCKET
+# define USE_SOCKET
+# endif
#endif
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},
/*
** 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
#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
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;
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
{
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)
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)
{
{
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;
* 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;
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_ */
imap/imap.c
imap/imap_ssl.c
imap/message.c
-imap/socket.c
imap/util.c
init.c
keymap.c
menu.c
mh.c
muttlib.c
+mutt_socket.c
mx.c
pager.c
pager.h