/*
* Copyright (C) 1996-1998,2010,2012-2013 Michael R. Elkins <me@mutt.org>
* Copyright (C) 1996-1999 Brandon Long <blong@fiction.net>
* Copyright (C) 1999-2009,2012 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* general IMAP utility functions */
#include "config.h"
#include "mutt.h"
#include "mx.h" /* for MUTT_IMAP */
#include "url.h"
#include "imap_private.h"
#ifdef USE_HCACHE
#include "hcache.h"
#endif
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <netdb.h>
#include <netinet/in.h>
#include <errno.h>
/* -- public functions -- */
/* imap_expand_path: IMAP implementation of mutt_expand_path. Rewrite
* an IMAP path in canonical and absolute form.
* Inputs: a buffer containing an IMAP path, and the number of bytes in
* that buffer.
* Outputs: The buffer is rewritten in place with the canonical IMAP path.
* Returns 0 on success, or -1 if imap_parse_path chokes or url_ciss_tostring
* fails, which it might if there isn't enough room in the buffer. */
int imap_expand_path (char* path, size_t len)
{
IMAP_MBOX mx;
IMAP_DATA* idata;
ciss_url_t url;
char fixedpath[LONG_STRING];
int rc;
if (imap_parse_path (path, &mx) < 0)
return -1;
idata = imap_conn_find (&mx.account, MUTT_IMAP_CONN_NONEW);
mutt_account_tourl (&mx.account, &url);
imap_fix_path (idata, mx.mbox, fixedpath, sizeof (fixedpath));
url.path = fixedpath;
rc = url_ciss_tostring (&url, path, len, U_DECODE_PASSWD);
FREE (&mx.mbox);
return rc;
}
#ifdef USE_HCACHE
/* Generates a seqseq of the UIDs in msn_index to persist in the header cache.
*
* Empty spots are stored as 0.
*/
static void imap_msn_index_to_uid_seqset (BUFFER *b, IMAP_DATA *idata)
{
int first = 1, state = 0, match = 0;
HEADER *cur_header;
unsigned int msn, cur_uid = 0, last_uid = 0;
unsigned int range_begin = 0, range_end = 0;
for (msn = 1; msn <= idata->max_msn + 1; msn++)
{
match = 0;
if (msn <= idata->max_msn)
{
cur_header = idata->msn_index[msn - 1];
cur_uid = cur_header ? HEADER_DATA(cur_header)->uid : 0;
if (!state || (cur_uid && (cur_uid - 1 == last_uid)))
match = 1;
last_uid = cur_uid;
}
if (match)
{
switch (state)
{
case 1: /* single: convert to a range */
state = 2;
/* fall through */
case 2: /* extend range ending */
range_end = cur_uid;
break;
default:
state = 1;
range_begin = cur_uid;
break;
}
}
else if (state)
{
if (first)
first = 0;
else
mutt_buffer_addch (b, ',');
if (state == 1)
mutt_buffer_add_printf (b, "%u", range_begin);
else if (state == 2)
mutt_buffer_add_printf (b, "%u:%u", range_begin, range_end);
state = 1;
range_begin = cur_uid;
}
}
}
static int imap_hcache_namer (const char* path, char* dest, size_t dlen)
{
return snprintf (dest, dlen, "%s.hcache", path);
}
header_cache_t* imap_hcache_open (IMAP_DATA* idata, const char* path)
{
IMAP_MBOX mx;
<