Commit d915b258 authored by Thomas Roessler's avatar Thomas Roessler

patch-bac.imapurl-2, with small modifications.

parent d4228054
...@@ -18,8 +18,9 @@ ...@@ -18,8 +18,9 @@
/* remote host account manipulation (POP/IMAP) */ /* remote host account manipulation (POP/IMAP) */
#include "account.h"
#include "mutt.h" #include "mutt.h"
#include "account.h"
#include "url.h"
/* mutt_account_match: compare account info (host/port/user) */ /* mutt_account_match: compare account info (host/port/user) */
int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* a2) int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* a2)
...@@ -53,6 +54,34 @@ int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* a2) ...@@ -53,6 +54,34 @@ int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* a2)
return 1; return 1;
} }
/* mutt_account_fromurl: fill account with information from url. */
int mutt_account_fromurl (ACCOUNT* account, ciss_url_t* url)
{
/* must be present */
if (url->host)
strfcpy (account->host, url->host, sizeof (account->host));
else
return -1;
if (url->user)
{
strfcpy (account->user, url->user, sizeof (account->user));
account->flags |= M_ACCT_USER;
}
if (url->pass)
{
strfcpy (account->pass, url->pass, sizeof (account->pass));
account->flags |= M_ACCT_PASS;
}
if (url->port)
{
account->port = url->port;
account->flags |= M_ACCT_PORT;
}
return 0;
}
/* mutt_account_getuser: retrieve username into ACCOUNT, if neccessary */ /* mutt_account_getuser: retrieve username into ACCOUNT, if neccessary */
int mutt_account_getuser (ACCOUNT* account) int mutt_account_getuser (ACCOUNT* account)
{ {
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifndef _MUTT_ACCOUNT_H_ #ifndef _MUTT_ACCOUNT_H_
#define _MUTT_ACCOUNT_H_ 1 #define _MUTT_ACCOUNT_H_ 1
#include "url.h"
/* account types */ /* account types */
enum enum
{ {
...@@ -46,6 +48,7 @@ typedef struct ...@@ -46,6 +48,7 @@ typedef struct
} ACCOUNT; } ACCOUNT;
int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* m2); int mutt_account_match (const ACCOUNT* a1, const ACCOUNT* m2);
int mutt_account_fromurl (ACCOUNT* account, ciss_url_t* url);
int mutt_account_getuser (ACCOUNT* account); int mutt_account_getuser (ACCOUNT* account);
int mutt_account_getpass (ACCOUNT* account); int mutt_account_getpass (ACCOUNT* account);
......
...@@ -144,6 +144,7 @@ folder_format_str (char *dest, size_t destlen, char op, const char *src, ...@@ -144,6 +144,7 @@ folder_format_str (char *dest, size_t destlen, char op, const char *src,
FOLDER *folder = (FOLDER *) data; FOLDER *folder = (FOLDER *) data;
struct passwd *pw; struct passwd *pw;
struct group *gr; struct group *gr;
int optional = (flags & M_FORMAT_OPTIONAL);
switch (op) switch (op)
{ {
...@@ -257,8 +258,13 @@ folder_format_str (char *dest, size_t destlen, char op, const char *src, ...@@ -257,8 +258,13 @@ folder_format_str (char *dest, size_t destlen, char op, const char *src,
#ifdef USE_IMAP #ifdef USE_IMAP
if (mx_is_imap (folder->ff->desc)) if (mx_is_imap (folder->ff->desc))
{ {
snprintf (tmp, sizeof (tmp), "%%%sd", fmt); if (!optional)
snprintf (dest, destlen, tmp, folder->ff->new); {
snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
snprintf (dest, destlen, tmp, folder->ff->new);
}
else if (!folder->ff->new)
optional = 0;
break; break;
} }
#endif #endif
...@@ -310,6 +316,12 @@ folder_format_str (char *dest, size_t destlen, char op, const char *src, ...@@ -310,6 +316,12 @@ folder_format_str (char *dest, size_t destlen, char op, const char *src,
snprintf (dest, destlen, tmp, op); snprintf (dest, destlen, tmp, op);
break; break;
} }
if (optional)
mutt_FormatString (dest, destlen, ifstring, folder_format_str, data, 0);
else if (flags & M_FORMAT_OPTIONAL)
mutt_FormatString (dest, destlen, elsestring, folder_format_str, data, 0);
return (src); return (src);
} }
......
...@@ -310,7 +310,9 @@ IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags) ...@@ -310,7 +310,9 @@ IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags)
IMAP_DATA* idata; IMAP_DATA* idata;
ACCOUNT* creds; ACCOUNT* creds;
conn = mutt_conn_find (NULL, account); if (!(conn = mutt_conn_find (NULL, account)))
return NULL;
/* if opening a new UNSELECTED connection, preserve existing creds */ /* if opening a new UNSELECTED connection, preserve existing creds */
creds = &(conn->account); creds = &(conn->account);
...@@ -318,11 +320,11 @@ IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags) ...@@ -318,11 +320,11 @@ IMAP_DATA* imap_conn_find (const ACCOUNT* account, int flags)
if (flags & M_IMAP_CONN_NOSELECT) if (flags & M_IMAP_CONN_NOSELECT)
while (conn->data && ((IMAP_DATA*) conn->data)->state == IMAP_SELECTED) while (conn->data && ((IMAP_DATA*) conn->data)->state == IMAP_SELECTED)
{ {
conn = mutt_conn_find (conn, account); if (!(conn = mutt_conn_find (conn, account)))
return NULL;
memcpy (&(conn->account), creds, sizeof (ACCOUNT)); memcpy (&(conn->account), creds, sizeof (ACCOUNT));
} }
idata = (IMAP_DATA*) conn->data; idata = (IMAP_DATA*) conn->data;
/* don't open a new connection if one isn't wanted */ /* don't open a new connection if one isn't wanted */
...@@ -1272,7 +1274,7 @@ int imap_complete(char* dest, size_t dlen, char* path) { ...@@ -1272,7 +1274,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
/* reformat path for IMAP list, and append wildcard */ /* reformat path for IMAP list, and append wildcard */
/* don't use INBOX in place of "" */ /* don't use INBOX in place of "" */
if (mx.mbox[0]) if (mx.mbox && mx.mbox[0])
imap_fix_path (idata, mx.mbox, list, sizeof(list)); imap_fix_path (idata, mx.mbox, list, sizeof(list));
else else
list[0] = '\0'; list[0] = '\0';
...@@ -1284,7 +1286,7 @@ int imap_complete(char* dest, size_t dlen, char* path) { ...@@ -1284,7 +1286,7 @@ int imap_complete(char* dest, size_t dlen, char* path) {
imap_cmd_start (idata, buf); imap_cmd_start (idata, buf);
/* and see what the results are */ /* and see what the results are */
strfcpy (completion, mx.mbox, sizeof(completion)); strfcpy (completion, NONULL(mx.mbox), sizeof(completion));
do do
{ {
if (imap_parse_list_response(idata, &list_word, &noselect, &noinferiors, if (imap_parse_list_response(idata, &list_word, &noselect, &noinferiors,
......
...@@ -144,13 +144,6 @@ static int add_entropy (const char *file) ...@@ -144,13 +144,6 @@ static int add_entropy (const char *file)
return n; return n;
} }
void imap_set_ssl (ACCOUNT* account)
{
if (! (account->flags & M_ACCT_PORT))
account->port = IMAP_SSL_PORT;
account->flags |= M_ACCT_SSL;
}
static int ssl_socket_open_err (CONNECTION *conn) static int ssl_socket_open_err (CONNECTION *conn)
{ {
mutt_error (_("SSL disabled due the lack of entropy")); mutt_error (_("SSL disabled due the lack of entropy"));
......
...@@ -25,6 +25,5 @@ extern char *SslCertFile; ...@@ -25,6 +25,5 @@ extern char *SslCertFile;
extern char *SslEntropyFile; extern char *SslEntropyFile;
extern int ssl_socket_setup (CONNECTION *conn); extern int ssl_socket_setup (CONNECTION *conn);
extern void imap_set_ssl (ACCOUNT* account);
#endif /* _MUTT_SSL_H_ */ #endif /* _MUTT_SSL_H_ */
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "mutt.h" #include "mutt.h"
#include "mx.h" /* for M_IMAP */ #include "mx.h" /* for M_IMAP */
#include "url.h"
#include "imap_private.h" #include "imap_private.h"
#include "imap_ssl.h" #include "imap_ssl.h"
...@@ -132,62 +133,90 @@ char *imap_next_word (char *s) ...@@ -132,62 +133,90 @@ char *imap_next_word (char *s)
int imap_parse_path (const char* path, IMAP_MBOX* mx) int imap_parse_path (const char* path, IMAP_MBOX* mx)
{ {
char tmp[128]; char tmp[128];
url_scheme_t scheme;
ciss_url_t url;
char *c; char *c;
int n; int n;
if (sscanf (path, "{%128[^}]}", tmp) != 1)
return -1;
mx->account.type = M_ACCT_TYPE_IMAP;
c = strchr (path, '}');
if (!c)
return -1;
else
/* walk past closing '}' */
mx->mbox = safe_strdup (c+1);
/* Defaults */ /* Defaults */
mx->account.flags = 0; mx->account.flags = 0;
mx->account.port = IMAP_PORT; mx->account.port = IMAP_PORT;
mx->account.type = M_ACCT_TYPE_IMAP;
#ifdef USE_SSL
if (option (OPTIMAPFORCESSL))
mx->account.flags |= M_ACCT_SSL;
#endif
if ((c = strrchr (tmp, '@'))) scheme = url_check_scheme (NONULL (path));
if (scheme == U_IMAP || scheme == U_IMAPS)
{ {
*c = '\0'; if (url_parse_ciss (&url, path) < 0)
strfcpy (mx->account.user, tmp, sizeof (mx->account.user)); return -1;
strfcpy (tmp, c+1, sizeof (tmp));
mx->account.flags |= M_ACCT_USER; n = mutt_account_fromurl (&mx->account, &url);
FREE (&url.user);
FREE (&url.pass);
FREE (&url.host);
if (n < 0)
{
FREE (&url.path);
return -1;
}
mx->mbox = url.path;
if (scheme == U_IMAPS)
mx->account.flags |= M_ACCT_SSL;
} }
/* old PINE-compatibility code */
if ((n = sscanf (tmp, "%128[^:/]%128s", mx->account.host, tmp)) < 1) else
{ {
dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path)); if (sscanf (path, "{%128[^}]}", tmp) != 1)
FREE (&mx->mbox); return -1;
return -1;
} c = strchr (path, '}');
if (!c)
return -1;
else
/* walk past closing '}' */
mx->mbox = safe_strdup (c+1);
if (n > 1) { if ((c = strrchr (tmp, '@')))
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 *c = '\0';
if (!strncmp (tmp, "ssl", 3)) strfcpy (mx->account.user, tmp, sizeof (mx->account.user));
imap_set_ssl (&(mx->account)); strfcpy (tmp, c+1, sizeof (tmp));
else mx->account.flags |= M_ACCT_USER;
#endif }
if ((n = sscanf (tmp, "%128[^:/]%128s", mx->account.host, tmp)) < 1)
{
dprint (1, (debugfile, "imap_parse_path: NULL host in %s\n", path));
FREE (&mx->mbox);
return -1;
}
if (n > 1) {
if (sscanf (tmp, ":%hd%128s", &(mx->account.port), tmp) >= 1)
mx->account.flags |= M_ACCT_PORT;
if (sscanf (tmp, "/%s", tmp) == 1)
{ {
dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path)); if (!strncmp (tmp, "ssl", 3))
FREE (&mx->mbox); mx->account.flags |= M_ACCT_SSL;
return -1; else
{
dprint (1, (debugfile, "imap_parse_path: Unknown connection type in %s\n", path));
FREE (&mx->mbox);
return -1;
}
} }
} }
} }
#ifdef USE_SSL if ((mx->account.flags & M_ACCT_SSL) && !(mx->account.flags & M_ACCT_PORT))
if (option (OPTIMAPFORCESSL)) mx->account.port = IMAP_SSL_PORT;
imap_set_ssl (&(mx->account));
#endif
return 0; return 0;
} }
......
...@@ -191,11 +191,19 @@ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account) ...@@ -191,11 +191,19 @@ CONNECTION* mutt_conn_find (const CONNECTION* start, const ACCOUNT* account)
conn->next = Connections; conn->next = Connections;
Connections = conn; Connections = conn;
#ifdef USE_SSL
if (account->flags & M_ACCT_SSL) if (account->flags & M_ACCT_SSL)
{
#ifdef USE_SSL
ssl_socket_setup (conn); ssl_socket_setup (conn);
else #else
mutt_error _("SSL is unavailable.");
sleep (2);
FREE (&conn);
return NULL;
#endif #endif
}
else
{ {
conn->read = raw_socket_read; conn->read = raw_socket_read;
conn->write = raw_socket_write; conn->write = raw_socket_write;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "mailbox.h" #include "mailbox.h"
#include "copy.h" #include "copy.h"
#include "keymap.h" #include "keymap.h"
#include "url.h"
#ifdef HAVE_PGP #ifdef HAVE_PGP
#include "pgp.h" #include "pgp.h"
...@@ -313,7 +313,19 @@ void mx_unlink_empty (const char *path) ...@@ -313,7 +313,19 @@ void mx_unlink_empty (const char *path)
int mx_is_imap(const char *p) int mx_is_imap(const char *p)
{ {
return p && (*p == '{'); url_scheme_t scheme;
if (!p)
return 0;
if (*p == '{')
return 1;
scheme = url_check_scheme (p);
if (scheme == U_IMAP || scheme == U_IMAPS)
return 1;
return 0;
} }
#endif #endif
......
...@@ -31,20 +31,10 @@ ...@@ -31,20 +31,10 @@
static struct mapping_t UrlMap[] = static struct mapping_t UrlMap[] =
{ {
{ "file", U_FILE }, { "file", U_FILE },
#ifdef USE_IMAP
{ "imap", U_IMAP }, { "imap", U_IMAP },
#endif
#ifdef USE_POP
{ "pop", U_POP },
#endif
#ifdef USE_SSL
# ifdef USE_IMAP
{ "imaps", U_IMAPS }, { "imaps", U_IMAPS },
# endif { "pop", U_POP },
# ifdef USE_POP
{ "pops", U_POPS }, { "pops", U_POPS },
# endif
#endif
{ "mailto", U_MAILTO }, { "mailto", U_MAILTO },
{ NULL, U_UNKNOWN} { NULL, U_UNKNOWN}
}; };
...@@ -53,6 +43,10 @@ static struct mapping_t UrlMap[] = ...@@ -53,6 +43,10 @@ static struct mapping_t UrlMap[] =
static void url_pct_decode (char *s) static void url_pct_decode (char *s)
{ {
char *d; char *d;
if (!s)
return;
for (d = s; *s; s++) for (d = s; *s; s++)
{ {
if (*s == '%' && s[1] && s[2] && if (*s == '%' && s[1] && s[2] &&
...@@ -106,12 +100,17 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src) ...@@ -106,12 +100,17 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src)
char *t; char *t;
char *p; char *p;
char *path; char *path;
ciss->user = NULL;
ciss->pass = NULL;
ciss->host = NULL;
ciss->port = 0;
if (strncmp (src, "//", 2)) if (strncmp (src, "//", 2))
return src; return src;
src += 2; src += 2;
if ((path = strchr (src, '/'))) if ((path = strchr (src, '/')))
*path++ = '\0'; *path++ = '\0';
...@@ -122,8 +121,10 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src) ...@@ -122,8 +121,10 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src)
{ {
*p = '\0'; *p = '\0';
ciss->pass = safe_strdup (p + 1); ciss->pass = safe_strdup (p + 1);
url_pct_decode (ciss->pass);
} }
ciss->user = safe_strdup (src); ciss->user = safe_strdup (src);
url_pct_decode (ciss->user);
t++; t++;
} }
else else
...@@ -138,12 +139,13 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src) ...@@ -138,12 +139,13 @@ static char *ciss_parse_userhost (ciss_url_t *ciss, char *src)
ciss->port = 0; ciss->port = 0;
ciss->host = safe_strdup (t); ciss->host = safe_strdup (t);
url_pct_decode (ciss->host);
return path; return path;
} }
static void ciss_parse_path (ciss_url_t *ciss, char *src) static void ciss_parse_path (ciss_url_t *ciss, char *src)
{ {
ciss->path = src; ciss->path = safe_strdup (src);
url_pct_decode (ciss->path); url_pct_decode (ciss->path);
} }
......
#ifndef _URL_H #ifndef _URL_H
# define _URL_H # define _URL_H
# include "config.h"
typedef enum url_scheme typedef enum url_scheme
{ {
U_FILE, U_FILE,
# ifdef USE_POP
U_POP, U_POP,
# endif U_POPS,
# ifdef USE_IMAP
U_IMAP, U_IMAP,
# endif
# ifdef USE_SSL
# ifdef USE_IMAP
U_IMAPS, U_IMAPS,
# endif
# ifdef USE_POP
U_POPS,
# endif
# endif
U_MAILTO, U_MAILTO,
U_UNKNOWN U_UNKNOWN
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment