return clean;
}
+/**
+ * free_mboxdata - Free data attached to the Mailbox
+ * @param data POP data
+ *
+ * The PopMboxData struct stores global POP data, such as the connection to
+ * the database. This function will close the database, free the resources and
+ * the struct itself.
+ */
+static void free_mboxdata(void *data)
+{
+ FREE(&data);
+}
+
+/**
+ * new_mboxdata - Create a new PopMboxData object
+ * @retval ptr New PopMboxData struct
+ */
+static struct PopMboxData *new_mboxdata(void)
+{
+ return mutt_mem_calloc(1, sizeof(struct PopMboxData));
+}
+
/**
* fetch_message - write line to file
* @param line String to write
/**
* pop_read_header - Read header
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @param e Email header
* @retval 0 Success
* @retval -1 Connection lost
* @retval -2 Invalid command or execution error
* @retval -3 Error writing to tempfile
*/
-static int pop_read_header(struct PopData *pop_data, struct Email *e)
+static int pop_read_header(struct PopMboxData *mdata, struct Email *e)
{
FILE *f = mutt_file_mkstemp();
if (!f)
char buf[LONG_STRING];
snprintf(buf, sizeof(buf), "LIST %d\r\n", e->refno);
- int rc = pop_query(pop_data, buf, sizeof(buf));
+ int rc = pop_query(mdata, buf, sizeof(buf));
if (rc == 0)
{
sscanf(buf, "+OK %d %zu", &index, &length);
snprintf(buf, sizeof(buf), "TOP %d 0\r\n", e->refno);
- rc = pop_fetch_data(pop_data, buf, NULL, fetch_message, f);
+ rc = pop_fetch_data(mdata, buf, NULL, fetch_message, f);
- if (pop_data->cmd_top == 2)
+ if (mdata->cmd_top == 2)
{
if (rc == 0)
{
- pop_data->cmd_top = 1;
+ mdata->cmd_top = 1;
mutt_debug(1, "set TOP capability\n");
}
if (rc == -2)
{
- pop_data->cmd_top = 0;
+ mdata->cmd_top = 0;
mutt_debug(1, "unset TOP capability\n");
- snprintf(pop_data->err_msg, sizeof(pop_data->err_msg), "%s",
+ snprintf(mdata->err_msg, sizeof(mdata->err_msg), "%s",
_("Command TOP is not supported by server"));
}
}
}
case -2:
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
break;
}
case -3:
static int fetch_uidl(char *line, void *data)
{
struct Mailbox *mailbox = data;
- struct PopData *pop_data = mailbox->data;
+ struct PopMboxData *mdata = mailbox->data;
char *endp = NULL;
errno = 0;
mailbox->hdrs[i]->data = mutt_str_strdup(line);
}
else if (mailbox->hdrs[i]->index != index - 1)
- pop_data->clear_cache = true;
+ mdata->clear_cache = true;
mailbox->hdrs[i]->refno = index;
mailbox->hdrs[i]->index = index - 1;
if (!mailbox)
return -1;
- struct PopData *pop_data = mailbox->data;
- if (!pop_data)
+ struct PopMboxData *mdata = mailbox->data;
+ if (!mdata)
return -1;
#ifdef USE_HCACHE
/**
* pop_hcache_open - Open the header cache
- * @param pop_data POP server data
+ * @param mdata POP Mailbox data
* @param path Path to the mailbox
* @retval ptr Header cache
*/
-static header_cache_t *pop_hcache_open(struct PopData *pop_data, const char *path)
+static header_cache_t *pop_hcache_open(struct PopMboxData *mdata, const char *path)
{
- if (!pop_data || !pop_data->conn)
+ if (!mdata || !mdata->conn)
return mutt_hcache_open(HeaderCache, path, NULL);
struct Url url;
char p[LONG_STRING];
- mutt_account_tourl(&pop_data->conn->account, &url);
+ mutt_account_tourl(&mdata->conn->account, &url);
url.path = HC_FNAME;
url_tostring(&url, p, sizeof(p), U_PATH);
return mutt_hcache_open(HeaderCache, p, pop_hcache_namer);
*/
static int pop_fetch_headers(struct Context *ctx)
{
- struct PopData *pop_data = ctx->mailbox->data;
+ struct PopMboxData *mdata = ctx->mailbox->data;
struct Progress progress;
#ifdef USE_HCACHE
- header_cache_t *hc = pop_hcache_open(pop_data, ctx->mailbox->path);
+ header_cache_t *hc = pop_hcache_open(mdata, ctx->mailbox->path);
#endif
- time(&pop_data->check_time);
- pop_data->clear_cache = false;
+ time(&mdata->check_time);
+ mdata->clear_cache = false;
for (int i = 0; i < ctx->mailbox->msg_count; i++)
ctx->mailbox->hdrs[i]->refno = -1;
const int old_count = ctx->mailbox->msg_count;
- int ret = pop_fetch_data(pop_data, "UIDL\r\n", NULL, fetch_uidl, ctx->mailbox);
+ int ret = pop_fetch_data(mdata, "UIDL\r\n", NULL, fetch_uidl, ctx->mailbox);
const int new_count = ctx->mailbox->msg_count;
ctx->mailbox->msg_count = old_count;
- if (pop_data->cmd_uidl == 2)
+ if (mdata->cmd_uidl == 2)
{
if (ret == 0)
{
- pop_data->cmd_uidl = 1;
+ mdata->cmd_uidl = 1;
mutt_debug(1, "set UIDL capability\n");
}
- if (ret == -2 && pop_data->cmd_uidl == 2)
+ if (ret == -2 && mdata->cmd_uidl == 2)
{
- pop_data->cmd_uidl = 0;
+ mdata->cmd_uidl = 0;
mutt_debug(1, "unset UIDL capability\n");
- snprintf(pop_data->err_msg, sizeof(pop_data->err_msg), "%s",
+ snprintf(mdata->err_msg, sizeof(mdata->err_msg), "%s",
_("Command UIDL is not supported by server"));
}
}
}
else
#endif
- if ((ret = pop_read_header(pop_data, ctx->mailbox->hdrs[i])) < 0)
+ if ((ret = pop_read_header(mdata, ctx->mailbox->hdrs[i])) < 0)
break;
#ifdef USE_HCACHE
else
* - if we don't have a body: new
*/
const bool bcached =
- (mutt_bcache_exists(pop_data->bcache, cache_id(ctx->mailbox->hdrs[i]->data)) == 0);
+ (mutt_bcache_exists(mdata->bcache, cache_id(ctx->mailbox->hdrs[i]->data)) == 0);
ctx->mailbox->hdrs[i]->old = false;
ctx->mailbox->hdrs[i]->read = false;
if (hcached)
* the availability of our cache
*/
if (MessageCacheClean)
- mutt_bcache_list(pop_data->bcache, msg_cache_check, ctx->mailbox);
+ mutt_bcache_list(mdata->bcache, msg_cache_check, ctx->mailbox);
mutt_clear_error();
return new_count - old_count;
/**
* pop_clear_cache - delete all cached messages
- * @param pop_data POP server data
+ * @param mdata POP Mailbox data
*/
-static void pop_clear_cache(struct PopData *pop_data)
+static void pop_clear_cache(struct PopMboxData *mdata)
{
- if (!pop_data->clear_cache)
+ if (!mdata->clear_cache)
return;
mutt_debug(1, "delete cached messages\n");
for (int i = 0; i < POP_CACHE_LEN; i++)
{
- if (pop_data->cache[i].path)
+ if (mdata->cache[i].path)
{
- unlink(pop_data->cache[i].path);
- FREE(&pop_data->cache[i].path);
+ unlink(mdata->cache[i].path);
+ FREE(&mdata->cache[i].path);
}
}
}
if (!conn)
return;
- struct PopData *pop_data = mutt_mem_calloc(1, sizeof(struct PopData));
- pop_data->conn = conn;
+ struct PopMboxData *mdata = new_mboxdata();
+ mdata->conn = conn;
- if (pop_open_connection(pop_data) < 0)
+ if (pop_open_connection(mdata) < 0)
{
- mutt_socket_free(pop_data->conn);
- FREE(&pop_data);
+ mutt_socket_free(mdata->conn);
+ FREE(&mdata);
return;
}
- conn->data = pop_data;
+ conn->data = mdata;
mutt_message(_("Checking for new messages..."));
/* find out how many messages are in the mailbox. */
mutt_str_strfcpy(buffer, "STAT\r\n", sizeof(buffer));
- ret = pop_query(pop_data, buffer, sizeof(buffer));
+ ret = pop_query(mdata, buffer, sizeof(buffer));
if (ret == -1)
goto fail;
if (ret == -2)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
goto finish;
}
if (msgs > 0 && PopLast)
{
mutt_str_strfcpy(buffer, "LAST\r\n", sizeof(buffer));
- ret = pop_query(pop_data, buffer, sizeof(buffer));
+ ret = pop_query(mdata, buffer, sizeof(buffer));
if (ret == -1)
goto fail;
if (ret == 0)
else
{
snprintf(buffer, sizeof(buffer), "RETR %d\r\n", i);
- ret = pop_fetch_data(pop_data, buffer, NULL, fetch_message, msg->fp);
+ ret = pop_fetch_data(mdata, buffer, NULL, fetch_message, msg->fp);
if (ret == -3)
rset = 1;
{
/* delete the message on the server */
snprintf(buffer, sizeof(buffer), "DELE %d\r\n", i);
- ret = pop_query(pop_data, buffer, sizeof(buffer));
+ ret = pop_query(mdata, buffer, sizeof(buffer));
}
if (ret == -1)
}
if (ret == -2)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
break;
}
if (ret == -3)
{
/* make sure no messages get deleted */
mutt_str_strfcpy(buffer, "RSET\r\n", sizeof(buffer));
- if (pop_query(pop_data, buffer, sizeof(buffer)) == -1)
+ if (pop_query(mdata, buffer, sizeof(buffer)) == -1)
goto fail;
}
finish:
/* exit gracefully */
mutt_str_strfcpy(buffer, "QUIT\r\n", sizeof(buffer));
- if (pop_query(pop_data, buffer, sizeof(buffer)) == -1)
+ if (pop_query(mdata, buffer, sizeof(buffer)) == -1)
goto fail;
mutt_socket_close(conn);
- FREE(&pop_data);
+ FREE(&mdata);
return;
fail:
mutt_error(_("Server closed connection"));
mutt_socket_close(conn);
- FREE(&pop_data);
+ FREE(&mdata);
}
/**
mutt_str_strfcpy(ctx->mailbox->realpath, ctx->mailbox->path,
sizeof(ctx->mailbox->realpath));
- struct PopData *pop_data = mutt_mem_calloc(1, sizeof(struct PopData));
- pop_data->conn = conn;
- ctx->mailbox->data = pop_data;
+ struct PopMboxData *mdata = new_mboxdata();
+ mdata->conn = conn;
+ ctx->mailbox->data = mdata;
+ ctx->mailbox->free_data = free_mboxdata;
- if (pop_open_connection(pop_data) < 0)
+ if (pop_open_connection(mdata) < 0)
return -1;
- conn->data = pop_data;
- pop_data->bcache = mutt_bcache_open(&acct, NULL);
+ conn->data = mdata;
+ mdata->bcache = mutt_bcache_open(&acct, NULL);
/* init (hard-coded) ACL rights */
memset(ctx->mailbox->rights, 0, sizeof(ctx->mailbox->rights));
if (pop_reconnect(ctx->mailbox) < 0)
return -1;
- ctx->mailbox->size = pop_data->size;
+ ctx->mailbox->size = mdata->size;
mutt_message(_("Fetching list of messages..."));
*/
static int pop_mbox_check(struct Context *ctx, int *index_hint)
{
- struct PopData *pop_data = ctx->mailbox->data;
+ struct PopMboxData *mdata = ctx->mailbox->data;
- if ((pop_data->check_time + PopCheckinterval) > time(NULL))
+ if ((mdata->check_time + PopCheckinterval) > time(NULL))
return 0;
pop_logout(ctx->mailbox);
- mutt_socket_close(pop_data->conn);
+ mutt_socket_close(mdata->conn);
- if (pop_open_connection(pop_data) < 0)
+ if (pop_open_connection(mdata) < 0)
return -1;
- ctx->mailbox->size = pop_data->size;
+ ctx->mailbox->size = mdata->size;
mutt_message(_("Checking for new messages..."));
int ret = pop_fetch_headers(ctx);
- pop_clear_cache(pop_data);
+ pop_clear_cache(mdata);
if (ret < 0)
return -1;
{
int i, j, ret = 0;
char buf[LONG_STRING];
- struct PopData *pop_data = ctx->mailbox->data;
+ struct PopMboxData *mdata = ctx->mailbox->data;
struct Progress progress;
#ifdef USE_HCACHE
header_cache_t *hc = NULL;
#endif
- pop_data->check_time = 0;
+ mdata->check_time = 0;
int num_deleted = 0;
for (i = 0; i < ctx->mailbox->msg_count; i++)
MUTT_PROGRESS_MSG, WriteInc, num_deleted);
#ifdef USE_HCACHE
- hc = pop_hcache_open(pop_data, ctx->mailbox->path);
+ hc = pop_hcache_open(mdata, ctx->mailbox->path);
#endif
for (i = 0, j = 0, ret = 0; ret == 0 && i < ctx->mailbox->msg_count; i++)
if (!ctx->mailbox->quiet)
mutt_progress_update(&progress, j, -1);
snprintf(buf, sizeof(buf), "DELE %d\r\n", ctx->mailbox->hdrs[i]->refno);
- ret = pop_query(pop_data, buf, sizeof(buf));
+ ret = pop_query(mdata, buf, sizeof(buf));
if (ret == 0)
{
- mutt_bcache_del(pop_data->bcache, cache_id(ctx->mailbox->hdrs[i]->data));
+ mutt_bcache_del(mdata->bcache, cache_id(ctx->mailbox->hdrs[i]->data));
#ifdef USE_HCACHE
mutt_hcache_delete(hc, ctx->mailbox->hdrs[i]->data,
strlen(ctx->mailbox->hdrs[i]->data));
if (ret == 0)
{
mutt_str_strfcpy(buf, "QUIT\r\n", sizeof(buf));
- ret = pop_query(pop_data, buf, sizeof(buf));
+ ret = pop_query(mdata, buf, sizeof(buf));
}
if (ret == 0)
{
- pop_data->clear_cache = true;
- pop_clear_cache(pop_data);
- pop_data->status = POP_DISCONNECTED;
+ mdata->clear_cache = true;
+ pop_clear_cache(mdata);
+ mdata->status = POP_DISCONNECTED;
return 0;
}
if (ret == -2)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
return -1;
}
}
*/
static int pop_mbox_close(struct Context *ctx)
{
- struct PopData *pop_data = ctx->mailbox->data;
- if (!pop_data)
+ struct PopMboxData *mdata = ctx->mailbox->data;
+ if (!mdata)
return 0;
pop_logout(ctx->mailbox);
- if (pop_data->status != POP_NONE)
- mutt_socket_close(pop_data->conn);
+ if (mdata->status != POP_NONE)
+ mutt_socket_close(mdata->conn);
- pop_data->status = POP_NONE;
+ mdata->status = POP_NONE;
- pop_data->clear_cache = true;
- pop_clear_cache(pop_data);
+ mdata->clear_cache = true;
+ pop_clear_cache(mdata);
- if (!pop_data->conn->data)
- mutt_socket_free(pop_data->conn);
+ if (!mdata->conn->data)
+ mutt_socket_free(mdata->conn);
- mutt_bcache_close(&pop_data->bcache);
+ mutt_bcache_close(&mdata->bcache);
return 0;
}
char buf[LONG_STRING];
char path[PATH_MAX];
struct Progress progressbar;
- struct PopData *pop_data = ctx->mailbox->data;
+ struct PopMboxData *mdata = ctx->mailbox->data;
struct Email *e = ctx->mailbox->hdrs[msgno];
bool bcache = true;
/* see if we already have the message in body cache */
- msg->fp = mutt_bcache_get(pop_data->bcache, cache_id(e->data));
+ msg->fp = mutt_bcache_get(mdata->bcache, cache_id(e->data));
if (msg->fp)
return 0;
/* see if we already have the message in our cache in
* case $message_cachedir is unset
*/
- struct PopCache *cache = &pop_data->cache[e->index % POP_CACHE_LEN];
+ struct PopCache *cache = &mdata->cache[e->index % POP_CACHE_LEN];
if (cache->path)
{
NetInc, e->content->length + e->content->offset - 1);
/* see if we can put in body cache; use our cache as fallback */
- msg->fp = mutt_bcache_put(pop_data->bcache, cache_id(e->data));
+ msg->fp = mutt_bcache_put(mdata->bcache, cache_id(e->data));
if (!msg->fp)
{
/* no */
snprintf(buf, sizeof(buf), "RETR %d\r\n", e->refno);
- const int ret = pop_fetch_data(pop_data, buf, &progressbar, fetch_message, msg->fp);
+ const int ret = pop_fetch_data(mdata, buf, &progressbar, fetch_message, msg->fp);
if (ret == 0)
break;
if (ret == -2)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
return -1;
}
* portion of the headers, those required for the main display.
*/
if (bcache)
- mutt_bcache_commit(pop_data->bcache, cache_id(e->data));
+ mutt_bcache_commit(mdata->bcache, cache_id(e->data));
else
{
cache->index = e->index;
#ifdef USE_SASL
/**
* pop_auth_sasl - POP SASL authenticator
- * @param pop_data POP Server data
+ * @param mdata POP Mailbox data
* @param method Authentication method
* @retval num Result, e.g. #POP_A_SUCCESS
*/
-static enum PopAuthRes pop_auth_sasl(struct PopData *pop_data, const char *method)
+static enum PopAuthRes pop_auth_sasl(struct PopMboxData *mdata, const char *method)
{
sasl_conn_t *saslconn = NULL;
sasl_interact_t *interaction = NULL;
const char *pc = NULL;
unsigned int len = 0, olen = 0, client_start;
- if (mutt_account_getpass(&pop_data->conn->account) || !pop_data->conn->account.pass[0])
+ if (mutt_account_getpass(&mdata->conn->account) || !mdata->conn->account.pass[0])
return POP_A_FAILURE;
- if (mutt_sasl_client_new(pop_data->conn, &saslconn) < 0)
+ if (mutt_sasl_client_new(mdata->conn, &saslconn) < 0)
{
mutt_debug(1, "Error allocating SASL connection.\n");
return POP_A_FAILURE;
}
if (!method)
- method = pop_data->auth_list;
+ method = mdata->auth_list;
while (true)
{
while (true)
{
mutt_str_strfcpy(buf + olen, "\r\n", bufsize - olen);
- mutt_socket_send(pop_data->conn, buf);
- if (mutt_socket_readln(inbuf, sizeof(inbuf), pop_data->conn) < 0)
+ mutt_socket_send(mdata->conn, buf);
+ if (mutt_socket_readln(inbuf, sizeof(inbuf), mdata->conn) < 0)
{
sasl_dispose(&saslconn);
- pop_data->status = POP_DISCONNECTED;
+ mdata->status = POP_DISCONNECTED;
FREE(&buf);
return POP_A_SOCKET;
}
if (mutt_str_strncmp(inbuf, "+OK", 3) == 0)
{
- mutt_sasl_setup_conn(pop_data->conn, saslconn);
+ mutt_sasl_setup_conn(mdata->conn, saslconn);
FREE(&buf);
return POP_A_SUCCESS;
}
if (mutt_str_strncmp(inbuf, "+ ", 2) == 0)
{
snprintf(buf, bufsize, "*\r\n");
- if (pop_query(pop_data, buf, bufsize) == -1)
+ if (pop_query(mdata, buf, bufsize) == -1)
{
FREE(&buf);
return POP_A_SOCKET;
/**
* pop_apop_timestamp - Get the server timestamp for APOP authentication
- * @param pop_data POP Server data
+ * @param mdata POP Mailbox data
* @param buf Timestamp string
*/
-void pop_apop_timestamp(struct PopData *pop_data, char *buf)
+void pop_apop_timestamp(struct PopMboxData *mdata, char *buf)
{
char *p1 = NULL, *p2 = NULL;
- FREE(&pop_data->timestamp);
+ FREE(&mdata->timestamp);
if ((p1 = strchr(buf, '<')) && (p2 = strchr(p1, '>')))
{
p2[1] = '\0';
- pop_data->timestamp = mutt_str_strdup(p1);
+ mdata->timestamp = mutt_str_strdup(p1);
}
}
/**
* pop_auth_apop - APOP authenticator
- * @param pop_data POP Server data
+ * @param mdata POP Mailbox data
* @param method Authentication method
* @retval num Result, e.g. #POP_A_SUCCESS
*/
-static enum PopAuthRes pop_auth_apop(struct PopData *pop_data, const char *method)
+static enum PopAuthRes pop_auth_apop(struct PopMboxData *mdata, const char *method)
{
struct Md5Ctx ctx;
unsigned char digest[16];
char hash[33];
char buf[LONG_STRING];
- if (mutt_account_getpass(&pop_data->conn->account) || !pop_data->conn->account.pass[0])
+ if (mutt_account_getpass(&mdata->conn->account) || !mdata->conn->account.pass[0])
return POP_A_FAILURE;
- if (!pop_data->timestamp)
+ if (!mdata->timestamp)
return POP_A_UNAVAIL;
- if (!mutt_addr_valid_msgid(pop_data->timestamp))
+ if (!mutt_addr_valid_msgid(mdata->timestamp))
{
mutt_error(_("POP timestamp is invalid"));
return POP_A_UNAVAIL;
/* Compute the authentication hash to send to the server */
mutt_md5_init_ctx(&ctx);
- mutt_md5_process(pop_data->timestamp, &ctx);
- mutt_md5_process(pop_data->conn->account.pass, &ctx);
+ mutt_md5_process(mdata->timestamp, &ctx);
+ mutt_md5_process(mdata->conn->account.pass, &ctx);
mutt_md5_finish_ctx(&ctx, digest);
mutt_md5_toascii(digest, hash);
/* Send APOP command to server */
- snprintf(buf, sizeof(buf), "APOP %s %s\r\n", pop_data->conn->account.user, hash);
+ snprintf(buf, sizeof(buf), "APOP %s %s\r\n", mdata->conn->account.user, hash);
- switch (pop_query(pop_data, buf, sizeof(buf)))
+ switch (pop_query(mdata, buf, sizeof(buf)))
{
case 0:
return POP_A_SUCCESS;
/**
* pop_auth_user - USER authenticator
- * @param pop_data POP Server data
+ * @param mdata POP Mailbox data
* @param method Authentication method
* @retval num Result, e.g. #POP_A_SUCCESS
*/
-static enum PopAuthRes pop_auth_user(struct PopData *pop_data, const char *method)
+static enum PopAuthRes pop_auth_user(struct PopMboxData *mdata, const char *method)
{
- if (!pop_data->cmd_user)
+ if (!mdata->cmd_user)
return POP_A_UNAVAIL;
- if (mutt_account_getpass(&pop_data->conn->account) || !pop_data->conn->account.pass[0])
+ if (mutt_account_getpass(&mdata->conn->account) || !mdata->conn->account.pass[0])
return POP_A_FAILURE;
mutt_message(_("Logging in..."));
char buf[LONG_STRING];
- snprintf(buf, sizeof(buf), "USER %s\r\n", pop_data->conn->account.user);
- int ret = pop_query(pop_data, buf, sizeof(buf));
+ snprintf(buf, sizeof(buf), "USER %s\r\n", mdata->conn->account.user);
+ int ret = pop_query(mdata, buf, sizeof(buf));
- if (pop_data->cmd_user == 2)
+ if (mdata->cmd_user == 2)
{
if (ret == 0)
{
- pop_data->cmd_user = 1;
+ mdata->cmd_user = 1;
mutt_debug(1, "set USER capability\n");
}
if (ret == -2)
{
- pop_data->cmd_user = 0;
+ mdata->cmd_user = 0;
mutt_debug(1, "unset USER capability\n");
- snprintf(pop_data->err_msg, sizeof(pop_data->err_msg), "%s",
+ snprintf(mdata->err_msg, sizeof(mdata->err_msg), "%s",
_("Command USER is not supported by server"));
}
}
if (ret == 0)
{
- snprintf(buf, sizeof(buf), "PASS %s\r\n", pop_data->conn->account.pass);
- ret = pop_query_d(pop_data, buf, sizeof(buf),
+ snprintf(buf, sizeof(buf), "PASS %s\r\n", mdata->conn->account.pass);
+ ret = pop_query_d(mdata, buf, sizeof(buf),
/* don't print the password unless we're at the ungodly debugging level */
DebugLevel < MUTT_SOCK_LOG_FULL ? "PASS *\r\n" : NULL);
}
return POP_A_SOCKET;
}
- mutt_error("%s %s", _("Login failed"), pop_data->err_msg);
+ mutt_error("%s %s", _("Login failed"), mdata->err_msg);
return POP_A_FAILURE;
}
/**
* pop_auth_oauth - Authenticate a POP connection using OAUTHBEARER
- * @param pop_data POP Server data
+ * @param mdata POP Mailbox data
* @param method Name of this authentication method (UNUSED)
* @retval num Result, e.g. #POP_A_SUCCESS
*/
-static enum PopAuthRes pop_auth_oauth(struct PopData *pop_data, const char *method)
+static enum PopAuthRes pop_auth_oauth(struct PopMboxData *mdata, const char *method)
{
mutt_message(_("Authenticating (OAUTHBEARER)..."));
- char *oauthbearer = mutt_account_getoauthbearer(&pop_data->conn->account);
+ char *oauthbearer = mutt_account_getoauthbearer(&mdata->conn->account);
if (!oauthbearer)
return POP_A_FAILURE;
FREE(&oauthbearer);
int ret =
- pop_query_d(pop_data, auth_cmd, strlen(auth_cmd),
+ pop_query_d(mdata, auth_cmd, strlen(auth_cmd),
#ifdef DEBUG
/* don't print the bearer token unless we're at the ungodly debugging level */
(DebugLevel < MUTT_SOCK_LOG_FULL) ? "AUTH OAUTHBEARER *\r\n" :
/* The error response was a SASL continuation, so "continue" it.
* See RFC7628 3.2.3 */
- mutt_socket_send(pop_data->conn, "\001");
+ mutt_socket_send(mdata->conn, "\001");
- char *err = pop_data->err_msg;
+ char *err = mdata->err_msg;
char decoded_err[LONG_STRING];
- int len = mutt_b64_decode(pop_data->err_msg, decoded_err, sizeof(decoded_err) - 1);
+ int len = mutt_b64_decode(mdata->err_msg, decoded_err, sizeof(decoded_err) - 1);
if (len >= 0)
{
decoded_err[len] = '\0';
/**
* pop_authenticate - Authenticate with a POP server
- * @param pop_data POP Server data
+ * @param mdata POP Mailbox data
* @retval num Result, e.g. #POP_A_SUCCESS
* @retval 0 Successful
* @retval -1 Connection lost
* @retval -2 Login failed
* @retval -3 Authentication cancelled
*/
-int pop_authenticate(struct PopData *pop_data)
+int pop_authenticate(struct PopMboxData *mdata)
{
- struct ConnAccount *acct = &pop_data->conn->account;
+ struct ConnAccount *acct = &mdata->conn->account;
const struct PopAuth *authenticator = NULL;
char *methods = NULL;
char *comma = NULL;
if (!authenticator->method ||
(mutt_str_strcasecmp(authenticator->method, method) == 0))
{
- ret = authenticator->authenticate(pop_data, method);
+ ret = authenticator->authenticate(mdata, method);
if (ret == POP_A_SOCKET)
{
- switch (pop_connect(pop_data))
+ switch (pop_connect(mdata))
{
case 0:
{
- ret = authenticator->authenticate(pop_data, method);
+ ret = authenticator->authenticate(mdata, method);
break;
}
case -2:
while (authenticator->authenticate)
{
- ret = authenticator->authenticate(pop_data, authenticator->method);
+ ret = authenticator->authenticate(mdata, authenticator->method);
if (ret == POP_A_SOCKET)
{
- switch (pop_connect(pop_data))
+ switch (pop_connect(mdata))
{
case 0:
{
- ret = authenticator->authenticate(pop_data, authenticator->method);
+ ret = authenticator->authenticate(mdata, authenticator->method);
break;
}
case -2:
/**
* pop_error - Copy error message to err_msg buffer
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @param msg Error message to save
*/
-static void pop_error(struct PopData *pop_data, char *msg)
+static void pop_error(struct PopMboxData *mdata, char *msg)
{
- char *t = strchr(pop_data->err_msg, '\0');
+ char *t = strchr(mdata->err_msg, '\0');
char *c = msg;
if (mutt_str_strncmp(msg, "-ERR ", 5) == 0)
c = c2;
}
- mutt_str_strfcpy(t, c, sizeof(pop_data->err_msg) - strlen(pop_data->err_msg));
- mutt_str_remove_trailing_ws(pop_data->err_msg);
+ mutt_str_strfcpy(t, c, sizeof(mdata->err_msg) - strlen(mdata->err_msg));
+ mutt_str_remove_trailing_ws(mdata->err_msg);
}
/**
*/
static int fetch_capa(char *line, void *data)
{
- struct PopData *pop_data = data;
+ struct PopMboxData *mdata = data;
char *c = NULL;
if (mutt_str_strncasecmp(line, "SASL", 4) == 0)
{
- FREE(&pop_data->auth_list);
+ FREE(&mdata->auth_list);
c = mutt_str_skip_email_wsp(line + 4);
- pop_data->auth_list = mutt_str_strdup(c);
+ mdata->auth_list = mutt_str_strdup(c);
}
else if (mutt_str_strncasecmp(line, "STLS", 4) == 0)
- pop_data->cmd_stls = true;
+ mdata->cmd_stls = true;
else if (mutt_str_strncasecmp(line, "USER", 4) == 0)
- pop_data->cmd_user = 1;
+ mdata->cmd_user = 1;
else if (mutt_str_strncasecmp(line, "UIDL", 4) == 0)
- pop_data->cmd_uidl = 1;
+ mdata->cmd_uidl = 1;
else if (mutt_str_strncasecmp(line, "TOP", 3) == 0)
- pop_data->cmd_top = 1;
+ mdata->cmd_top = 1;
return 0;
}
*/
static int fetch_auth(char *line, void *data)
{
- struct PopData *pop_data = data;
+ struct PopMboxData *mdata = data;
- if (!pop_data->auth_list)
+ if (!mdata->auth_list)
{
- pop_data->auth_list = mutt_mem_malloc(strlen(line) + 1);
- *pop_data->auth_list = '\0';
+ mdata->auth_list = mutt_mem_malloc(strlen(line) + 1);
+ *mdata->auth_list = '\0';
}
else
{
- mutt_mem_realloc(&pop_data->auth_list, strlen(pop_data->auth_list) + strlen(line) + 2);
- strcat(pop_data->auth_list, " ");
+ mutt_mem_realloc(&mdata->auth_list, strlen(mdata->auth_list) + strlen(line) + 2);
+ strcat(mdata->auth_list, " ");
}
- strcat(pop_data->auth_list, line);
+ strcat(mdata->auth_list, line);
return 0;
}
/**
* pop_capabilities - Get capabilities from a POP server
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @param mode Initial capabilities
* @retval 0 Successful
* @retval -1 Connection lost
* @retval -2 Execution error
*/
-static int pop_capabilities(struct PopData *pop_data, int mode)
+static int pop_capabilities(struct PopMboxData *mdata, int mode)
{
char buf[LONG_STRING];
/* don't check capabilities on reconnect */
- if (pop_data->capabilities)
+ if (mdata->capabilities)
return 0;
/* init capabilities */
if (mode == 0)
{
- pop_data->cmd_capa = false;
- pop_data->cmd_stls = false;
- pop_data->cmd_user = 0;
- pop_data->cmd_uidl = 0;
- pop_data->cmd_top = 0;
- pop_data->resp_codes = false;
- pop_data->expire = true;
- pop_data->login_delay = 0;
- FREE(&pop_data->auth_list);
+ mdata->cmd_capa = false;
+ mdata->cmd_stls = false;
+ mdata->cmd_user = 0;
+ mdata->cmd_uidl = 0;
+ mdata->cmd_top = 0;
+ mdata->resp_codes = false;
+ mdata->expire = true;
+ mdata->login_delay = 0;
+ FREE(&mdata->auth_list);
}
/* Execute CAPA command */
- if (mode == 0 || pop_data->cmd_capa)
+ if (mode == 0 || mdata->cmd_capa)
{
mutt_str_strfcpy(buf, "CAPA\r\n", sizeof(buf));
- switch (pop_fetch_data(pop_data, buf, NULL, fetch_capa, pop_data))
+ switch (pop_fetch_data(mdata, buf, NULL, fetch_capa, mdata))
{
case 0:
{
- pop_data->cmd_capa = true;
+ mdata->cmd_capa = true;
break;
}
case -1:
}
/* CAPA not supported, use defaults */
- if (mode == 0 && !pop_data->cmd_capa)
+ if (mode == 0 && !mdata->cmd_capa)
{
- pop_data->cmd_user = 2;
- pop_data->cmd_uidl = 2;
- pop_data->cmd_top = 2;
+ mdata->cmd_user = 2;
+ mdata->cmd_uidl = 2;
+ mdata->cmd_top = 2;
mutt_str_strfcpy(buf, "AUTH\r\n", sizeof(buf));
- if (pop_fetch_data(pop_data, buf, NULL, fetch_auth, pop_data) == -1)
+ if (pop_fetch_data(mdata, buf, NULL, fetch_auth, mdata) == -1)
return -1;
}
{
char *msg = NULL;
- if (!pop_data->expire)
+ if (!mdata->expire)
msg = _("Unable to leave messages on server");
- if (!pop_data->cmd_top)
+ if (!mdata->cmd_top)
msg = _("Command TOP is not supported by server");
- if (!pop_data->cmd_uidl)
+ if (!mdata->cmd_uidl)
msg = _("Command UIDL is not supported by server");
- if (msg && pop_data->cmd_capa)
+ if (msg && mdata->cmd_capa)
{
mutt_error(msg);
return -2;
}
- pop_data->capabilities = true;
+ mdata->capabilities = true;
}
return 0;
/**
* pop_connect - Open connection
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @retval 0 Successful
* @retval -1 Connection lost
* @retval -2 Invalid response
*/
-int pop_connect(struct PopData *pop_data)
+int pop_connect(struct PopMboxData *mdata)
{
char buf[LONG_STRING];
- pop_data->status = POP_NONE;
- if (mutt_socket_open(pop_data->conn) < 0 ||
- mutt_socket_readln(buf, sizeof(buf), pop_data->conn) < 0)
+ mdata->status = POP_NONE;
+ if (mutt_socket_open(mdata->conn) < 0 ||
+ mutt_socket_readln(buf, sizeof(buf), mdata->conn) < 0)
{
- mutt_error(_("Error connecting to server: %s"), pop_data->conn->account.host);
+ mutt_error(_("Error connecting to server: %s"), mdata->conn->account.host);
return -1;
}
- pop_data->status = POP_CONNECTED;
+ mdata->status = POP_CONNECTED;
if (mutt_str_strncmp(buf, "+OK", 3) != 0)
{
- *pop_data->err_msg = '\0';
- pop_error(pop_data, buf);
- mutt_error("%s", pop_data->err_msg);
+ *mdata->err_msg = '\0';
+ pop_error(mdata, buf);
+ mutt_error("%s", mdata->err_msg);
return -2;
}
- pop_apop_timestamp(pop_data, buf);
+ pop_apop_timestamp(mdata, buf);
return 0;
}
/**
* pop_open_connection - Open connection and authenticate
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @retval 0 Successful
* @retval -1 Connection lost
* @retval -2 Invalid command or execution error
* @retval -3 Authentication cancelled
*/
-int pop_open_connection(struct PopData *pop_data)
+int pop_open_connection(struct PopMboxData *mdata)
{
char buf[LONG_STRING];
- int rc = pop_connect(pop_data);
+ int rc = pop_connect(mdata);
if (rc < 0)
{
mutt_sleep(2);
return rc;
}
- rc = pop_capabilities(pop_data, 0);
+ rc = pop_capabilities(mdata, 0);
if (rc == -1)
goto err_conn;
if (rc == -2)
#ifdef USE_SSL
/* Attempt STLS if available and desired. */
- if (!pop_data->conn->ssf && (pop_data->cmd_stls || SslForceTls))
+ if (!mdata->conn->ssf && (mdata->cmd_stls || SslForceTls))
{
if (SslForceTls)
- pop_data->use_stls = 2;
- if (pop_data->use_stls == 0)
+ mdata->use_stls = 2;
+ if (mdata->use_stls == 0)
{
rc = query_quadoption(SslStarttls, _("Secure connection with TLS?"));
if (rc == MUTT_ABORT)
return -2;
- pop_data->use_stls = 1;
+ mdata->use_stls = 1;
if (rc == MUTT_YES)
- pop_data->use_stls = 2;
+ mdata->use_stls = 2;
}
- if (pop_data->use_stls == 2)
+ if (mdata->use_stls == 2)
{
mutt_str_strfcpy(buf, "STLS\r\n", sizeof(buf));
- rc = pop_query(pop_data, buf, sizeof(buf));
+ rc = pop_query(mdata, buf, sizeof(buf));
if (rc == -1)
goto err_conn;
if (rc != 0)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
}
- else if (mutt_ssl_starttls(pop_data->conn))
+ else if (mutt_ssl_starttls(mdata->conn))
{
mutt_error(_("Could not negotiate TLS connection"));
return -2;
else
{
/* recheck capabilities after STLS completes */
- rc = pop_capabilities(pop_data, 1);
+ rc = pop_capabilities(mdata, 1);
if (rc == -1)
goto err_conn;
if (rc == -2)
}
}
- if (SslForceTls && !pop_data->conn->ssf)
+ if (SslForceTls && !mdata->conn->ssf)
{
mutt_error(_("Encrypted connection unavailable"));
return -2;
}
#endif
- rc = pop_authenticate(pop_data);
+ rc = pop_authenticate(mdata);
if (rc == -1)
goto err_conn;
if (rc == -3)
return rc;
/* recheck capabilities after authentication */
- rc = pop_capabilities(pop_data, 2);
+ rc = pop_capabilities(mdata, 2);
if (rc == -1)
goto err_conn;
if (rc == -2)
/* get total size of mailbox */
mutt_str_strfcpy(buf, "STAT\r\n", sizeof(buf));
- rc = pop_query(pop_data, buf, sizeof(buf));
+ rc = pop_query(mdata, buf, sizeof(buf));
if (rc == -1)
goto err_conn;
if (rc == -2)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
return rc;
}
unsigned int n = 0, size = 0;
sscanf(buf, "+OK %u %u", &n, &size);
- pop_data->size = size;
+ mdata->size = size;
return 0;
err_conn:
- pop_data->status = POP_DISCONNECTED;
+ mdata->status = POP_DISCONNECTED;
mutt_error(_("Server closed connection"));
return -1;
}
*/
void pop_logout(struct Mailbox *mailbox)
{
- struct PopData *pop_data = mailbox->data;
+ struct PopMboxData *mdata = mailbox->data;
- if (pop_data->status == POP_CONNECTED)
+ if (mdata->status == POP_CONNECTED)
{
int ret = 0;
char buf[LONG_STRING];
if (mailbox->readonly)
{
mutt_str_strfcpy(buf, "RSET\r\n", sizeof(buf));
- ret = pop_query(pop_data, buf, sizeof(buf));
+ ret = pop_query(mdata, buf, sizeof(buf));
}
if (ret != -1)
{
mutt_str_strfcpy(buf, "QUIT\r\n", sizeof(buf));
- ret = pop_query(pop_data, buf, sizeof(buf));
+ ret = pop_query(mdata, buf, sizeof(buf));
}
if (ret < 0)
mutt_clear_error();
}
- pop_data->status = POP_DISCONNECTED;
+ mdata->status = POP_DISCONNECTED;
}
/**
* pop_query_d - Send data from buffer and receive answer to the same buffer
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @param buf Buffer to send/store data
* @param buflen Buffer length
* @param msg Progress message
* @retval -1 Connection lost
* @retval -2 Invalid command or execution error
*/
-int pop_query_d(struct PopData *pop_data, char *buf, size_t buflen, char *msg)
+int pop_query_d(struct PopMboxData *mdata, char *buf, size_t buflen, char *msg)
{
int dbg = MUTT_SOCK_LOG_CMD;
- if (pop_data->status != POP_CONNECTED)
+ if (mdata->status != POP_CONNECTED)
return -1;
/* print msg instead of real command */
mutt_debug(MUTT_SOCK_LOG_CMD, "> %s", msg);
}
- mutt_socket_send_d(pop_data->conn, buf, dbg);
+ mutt_socket_send_d(mdata->conn, buf, dbg);
char *c = strpbrk(buf, " \r\n");
if (c)
*c = '\0';
- snprintf(pop_data->err_msg, sizeof(pop_data->err_msg), "%s: ", buf);
+ snprintf(mdata->err_msg, sizeof(mdata->err_msg), "%s: ", buf);
- if (mutt_socket_readln(buf, buflen, pop_data->conn) < 0)
+ if (mutt_socket_readln(buf, buflen, mdata->conn) < 0)
{
- pop_data->status = POP_DISCONNECTED;
+ mdata->status = POP_DISCONNECTED;
return -1;
}
if (mutt_str_strncmp(buf, "+OK", 3) == 0)
return 0;
- pop_error(pop_data, buf);
+ pop_error(mdata, buf);
return -2;
}
/**
* pop_fetch_data - Read Headers with callback function
- * @param pop_data POP data
+ * @param mdata POP Mailbox data
* @param query POP query to send to server
* @param progressbar Progress bar
* @param func Function called for each header read
* This function calls func(*line, *data) for each received line,
* func(NULL, *data) if rewind(*data) needs, exits when fail or done.
*/
-int pop_fetch_data(struct PopData *pop_data, const char *query,
+int pop_fetch_data(struct PopMboxData *mdata, const char *query,
struct Progress *progressbar, int (*func)(char *, void *), void *data)
{
char buf[LONG_STRING];
size_t lenbuf = 0;
mutt_str_strfcpy(buf, query, sizeof(buf));
- int ret = pop_query(pop_data, buf, sizeof(buf));
+ int ret = pop_query(mdata, buf, sizeof(buf));
if (ret < 0)
return ret;
while (true)
{
const int chunk =
- mutt_socket_readln_d(buf, sizeof(buf), pop_data->conn, MUTT_SOCK_LOG_HDR);
+ mutt_socket_readln_d(buf, sizeof(buf), mdata->conn, MUTT_SOCK_LOG_HDR);
if (chunk < 0)
{
- pop_data->status = POP_DISCONNECTED;
+ mdata->status = POP_DISCONNECTED;
ret = -1;
break;
}
*/
int pop_reconnect(struct Mailbox *mailbox)
{
- struct PopData *pop_data = mailbox->data;
+ struct PopMboxData *mdata = mailbox->data;
- if (pop_data->status == POP_CONNECTED)
+ if (mdata->status == POP_CONNECTED)
return 0;
- if (pop_data->status == POP_BYE)
+ if (mdata->status == POP_BYE)
return -1;
while (true)
{
- mutt_socket_close(pop_data->conn);
+ mutt_socket_close(mdata->conn);
- int ret = pop_open_connection(pop_data);
+ int ret = pop_open_connection(mdata);
if (ret == 0)
{
struct Progress progressbar;
for (int i = 0; i < mailbox->msg_count; i++)
mailbox->hdrs[i]->refno = -1;
- ret = pop_fetch_data(pop_data, "UIDL\r\n", &progressbar, check_uidl, mailbox);
+ ret = pop_fetch_data(mdata, "UIDL\r\n", &progressbar, check_uidl, mailbox);
if (ret == -2)
{
- mutt_error("%s", pop_data->err_msg);
+ mutt_error("%s", mdata->err_msg);
}
}
if (ret == 0)
};
/**
- * struct PopData - POP-specific server data
+ * struct PopMboxData - POP data attached to a Mailbox - @extends Mailbox
*/
-struct PopData
+struct PopMboxData
{
struct Connection *conn;
unsigned int status : 2;
struct PopAuth
{
/* do authentication, using named method or any available if method is NULL */
- enum PopAuthRes (*authenticate)(struct PopData *, const char *);
+ enum PopAuthRes (*authenticate)(struct PopMboxData *, const char *);
/* name of authentication method supported, NULL means variable. If this
* is not null, authenticate may ignore the second parameter. */
const char *method;
};
/* pop_auth.c */
-int pop_authenticate(struct PopData *pop_data);
-void pop_apop_timestamp(struct PopData *pop_data, char *buf);
+int pop_authenticate(struct PopMboxData *mdata);
+void pop_apop_timestamp(struct PopMboxData *mdata, char *buf);
/* pop_lib.c */
#define pop_query(A, B, C) pop_query_d(A, B, C, NULL)
int pop_parse_path(const char *path, struct ConnAccount *acct);
-int pop_connect(struct PopData *pop_data);
-int pop_open_connection(struct PopData *pop_data);
-int pop_query_d(struct PopData *pop_data, char *buf, size_t buflen, char *msg);
-int pop_fetch_data(struct PopData *pop_data, const char *query, struct Progress *progressbar,
+int pop_connect(struct PopMboxData *mdata);
+int pop_open_connection(struct PopMboxData *mdata);
+int pop_query_d(struct PopMboxData *mdata, char *buf, size_t buflen, char *msg);
+int pop_fetch_data(struct PopMboxData *mdata, const char *query, struct Progress *progressbar,
int (*func)(char *, void *), void *data);
int pop_reconnect(struct Mailbox *mailbox);
void pop_logout(struct Mailbox *mailbox);