NeoMutt  2020-06-26-250-g349c94
Teaching an old dog new tricks
DOXYGEN
util.c File Reference

IMAP helper functions. More...

#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt_account.h"
#include "mutt_globals.h"
#include "options.h"
#include "bcache/lib.h"
#include "imap/lib.h"
#include "message.h"
#include "hcache/lib.h"
+ Include dependency graph for util.c:

Go to the source code of this file.

Functions

void imap_adata_free (void **ptr)
 Free the private Account data - Implements Account::adata_free() More...
 
struct ImapAccountDataimap_adata_new (struct Account *a)
 Allocate and initialise a new ImapAccountData structure. More...
 
struct ImapAccountDataimap_adata_get (struct Mailbox *m)
 Get the Account data for this mailbox. More...
 
int imap_adata_find (const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
 Find the Account data for this path. More...
 
struct ImapMboxDataimap_mdata_new (struct ImapAccountData *adata, const char *name)
 Allocate and initialise a new ImapMboxData structure. More...
 
void imap_mdata_cache_reset (struct ImapMboxData *mdata)
 Release and clear cache data of ImapMboxData structure. More...
 
void imap_mdata_free (void **ptr)
 Free the private Mailbox data - Implements Mailbox::mdata_free() More...
 
struct ImapMboxDataimap_mdata_get (struct Mailbox *m)
 Get the Mailbox data for this mailbox. More...
 
void imap_get_parent (const char *mbox, char delim, char *buf, size_t buflen)
 Get an IMAP folder's parent. More...
 
void imap_get_parent_path (const char *path, char *buf, size_t buflen)
 Get the path of the parent folder. More...
 
void imap_clean_path (char *path, size_t plen)
 Cleans an IMAP path using imap_fix_path. More...
 
static const char * imap_get_field (enum ConnAccountField field, void *gf_data)
 Get connection login credentials - Implements ConnAccount::get_field() More...
 
static void imap_msn_index_to_uid_seqset (struct Buffer *buf, struct ImapMboxData *mdata)
 Convert MSN index of UIDs to Seqset. More...
 
static void imap_hcache_namer (const char *path, struct Buffer *dest)
 Generate a filename for the header cache - Implements hcache_namer_t. More...
 
void imap_hcache_open (struct ImapAccountData *adata, struct ImapMboxData *mdata)
 Open a header cache. More...
 
void imap_hcache_close (struct ImapMboxData *mdata)
 Close the header cache. More...
 
struct Emailimap_hcache_get (struct ImapMboxData *mdata, unsigned int uid)
 Get a header cache entry by its UID. More...
 
int imap_hcache_put (struct ImapMboxData *mdata, struct Email *e)
 Add an entry to the header cache. More...
 
int imap_hcache_del (struct ImapMboxData *mdata, unsigned int uid)
 Delete an item from the header cache. More...
 
int imap_hcache_store_uid_seqset (struct ImapMboxData *mdata)
 Store a UID Sequence Set in the header cache. More...
 
int imap_hcache_clear_uid_seqset (struct ImapMboxData *mdata)
 Delete a UID Sequence Set from the header cache. More...
 
char * imap_hcache_get_uid_seqset (struct ImapMboxData *mdata)
 Get a UID Sequence Set from the header cache. More...
 
int imap_parse_path (const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
 Parse an IMAP mailbox name into ConnAccount, name. More...
 
int imap_mxcmp (const char *mx1, const char *mx2)
 Compare mailbox names, giving priority to INBOX. More...
 
void imap_pretty_mailbox (char *path, size_t pathlen, const char *folder)
 Prettify an IMAP mailbox name. More...
 
enum QuadOption imap_continue (const char *msg, const char *resp)
 display a message and ask the user if they want to go on More...
 
void imap_error (const char *where, const char *msg)
 show an error and abort More...
 
char * imap_fix_path (char delim, const char *mailbox, char *path, size_t plen)
 Fix up the imap path. More...
 
void imap_cachepath (char delim, const char *mailbox, struct Buffer *dest)
 Generate a cache path for a mailbox. More...
 
int imap_get_literal_count (const char *buf, unsigned int *bytes)
 write number of bytes in an IMAP literal into bytes More...
 
char * imap_get_qualifier (char *buf)
 Get the qualifier from a tagged response. More...
 
char * imap_next_word (char *s)
 Find where the next IMAP word begins. More...
 
void imap_qualify_path (char *buf, size_t buflen, struct ConnAccount *cac, char *path)
 Make an absolute IMAP folder target. More...
 
void imap_quote_string (char *dest, size_t dlen, const char *src, bool quote_backtick)
 quote string according to IMAP rules More...
 
void imap_unquote_string (char *s)
 equally stupid unquoting routine More...
 
void imap_munge_mbox_name (bool unicode, char *dest, size_t dlen, const char *src)
 Quote awkward characters in a mailbox name. More...
 
void imap_unmunge_mbox_name (bool unicode, char *s)
 Remove quoting from a mailbox name. More...
 
void imap_keepalive (void)
 poll the current folder to keep the connection alive More...
 
int imap_wait_keepalive (pid_t pid)
 Wait for a process to change state. More...
 
void imap_allow_reopen (struct Mailbox *m)
 Allow re-opening a folder upon expunge. More...
 
void imap_disallow_reopen (struct Mailbox *m)
 Disallow re-opening a folder upon expunge. More...
 
bool imap_account_match (const struct ConnAccount *a1, const struct ConnAccount *a2)
 Compare two Accounts. More...
 
struct SeqsetIteratormutt_seqset_iterator_new (const char *seqset)
 Create a new Sequence Set Iterator. More...
 
int mutt_seqset_iterator_next (struct SeqsetIterator *iter, unsigned int *next)
 Get the next UID from a Sequence Set. More...
 
void mutt_seqset_iterator_free (struct SeqsetIterator **ptr)
 Free a Sequence Set Iterator. More...
 

Detailed Description

IMAP helper functions.

Authors
  • Michael R. Elkins
  • Brandon Long
  • Brendan Cully
  • Richard Russon

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, see http://www.gnu.org/licenses/.

Definition in file util.c.

Function Documentation

◆ imap_adata_free()

void imap_adata_free ( void **  ptr)

Free the private Account data - Implements Account::adata_free()

Definition at line 65 of file util.c.

66 {
67  if (!ptr || !*ptr)
68  return;
69 
70  struct ImapAccountData *adata = *ptr;
71 
72  FREE(&adata->capstr);
73  mutt_buffer_dealloc(&adata->cmdbuf);
74  FREE(&adata->buf);
75  FREE(&adata->cmds);
76 
77  if (adata->conn)
78  {
79  if (adata->conn->close)
80  adata->conn->close(adata->conn);
81  FREE(&adata->conn);
82  }
83 
84  FREE(ptr);
85 }
struct ImapCommand * cmds
Definition: private.h:199
char * capstr
Definition: private.h:184
struct Buffer cmdbuf
Definition: private.h:203
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
int(* close)(struct Connection *conn)
Close a socket Connection.
Definition: connection.h:100
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:169
char * buf
Definition: private.h:189
#define FREE(x)
Definition: memory.h:40
struct Connection * conn
Definition: private.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_adata_new()

struct ImapAccountData* imap_adata_new ( struct Account a)

Allocate and initialise a new ImapAccountData structure.

Return values
ptrNew ImapAccountData

Definition at line 91 of file util.c.

92 {
93  struct ImapAccountData *adata = mutt_mem_calloc(1, sizeof(struct ImapAccountData));
94  adata->account = a;
95 
96  static unsigned char new_seqid = 'a';
97 
98  adata->seqid = new_seqid;
99  adata->cmdslots = C_ImapPipelineDepth + 2;
100  adata->cmds = mutt_mem_calloc(adata->cmdslots, sizeof(*adata->cmds));
101 
102  if (++new_seqid > 'z')
103  new_seqid = 'a';
104 
105  return adata;
106 }
struct ImapCommand * cmds
Definition: private.h:199
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
unsigned char seqid
tag sequence prefix
Definition: private.h:186
struct Account * account
Parent Account.
Definition: private.h:208
short C_ImapPipelineDepth
Config: (imap) Number of IMAP commands that may be queued up.
Definition: config.c:53
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:169
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_adata_get()

struct ImapAccountData* imap_adata_get ( struct Mailbox m)

Get the Account data for this mailbox.

Parameters
mMailbox
Return values
ptrPrivate data

Definition at line 113 of file util.c.

114 {
115  if (!m || (m->type != MUTT_IMAP) || !m->account)
116  return NULL;
117  return m->account->adata;
118 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the caller graph for this function:

◆ imap_adata_find()

int imap_adata_find ( const char *  path,
struct ImapAccountData **  adata,
struct ImapMboxData **  mdata 
)

Find the Account data for this path.

Parameters
pathPath to search for
adataImap Account data
mdataImap Mailbox data
Return values
0Success
-1Failure

Definition at line 128 of file util.c.

130 {
131  struct ConnAccount cac = { { 0 } };
132  struct ImapAccountData *tmp_adata = NULL;
133  char tmp[1024];
134 
135  if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
136  return -1;
137 
138  struct Account *np = NULL;
139  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
140  {
141  if (np->type != MUTT_IMAP)
142  continue;
143 
144  tmp_adata = np->adata;
145  if (!tmp_adata)
146  continue;
147  if (imap_account_match(&tmp_adata->conn->account, &cac))
148  {
149  *mdata = imap_mdata_new(tmp_adata, tmp);
150  *adata = tmp_adata;
151  return 0;
152  }
153  }
154  mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
155  return -1;
156 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:36
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:618
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: util.c:164
Login details for a remote server.
Definition: connaccount.h:51
IMAP-specific Account data -.
Definition: private.h:169
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
Log at debug level 3.
Definition: logging.h:42
struct Connection * conn
Definition: private.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_new()

struct ImapMboxData* imap_mdata_new ( struct ImapAccountData adata,
const char *  name 
)

Allocate and initialise a new ImapMboxData structure.

Parameters
adataImap Account data
nameName for Mailbox
Return values
ptrNew ImapMboxData

Definition at line 164 of file util.c.

165 {
166  char buf[1024];
167  struct ImapMboxData *mdata = mutt_mem_calloc(1, sizeof(struct ImapMboxData));
168 
169  mdata->real_name = mutt_str_dup(name);
170 
171  imap_fix_path(adata->delim, name, buf, sizeof(buf));
172  if (buf[0] == '\0')
173  mutt_str_copy(buf, "INBOX", sizeof(buf));
174  mdata->name = mutt_str_dup(buf);
175 
176  imap_munge_mbox_name(adata->unicode, buf, sizeof(buf), mdata->name);
177  mdata->munge_name = mutt_str_dup(buf);
178 
179  mdata->reopen &= IMAP_REOPEN_ALLOW;
180 
181  STAILQ_INIT(&mdata->flags);
182 
183 #ifdef USE_HCACHE
184  imap_hcache_open(adata, mdata);
185  if (mdata->hcache)
186  {
187  size_t dlen = 0;
188  void *uidvalidity = mutt_hcache_fetch_raw(mdata->hcache, "/UIDVALIDITY", 12, &dlen);
189  void *uidnext = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8, &dlen);
190  unsigned long long *modseq =
191  mutt_hcache_fetch_raw(mdata->hcache, "/MODSEQ", 7, &dlen);
192  if (uidvalidity)
193  {
194  mdata->uidvalidity = *(uint32_t *) uidvalidity;
195  mdata->uid_next = uidnext ? *(unsigned int *) uidnext : 0;
196  mdata->modseq = modseq ? *modseq : 0;
197  mutt_debug(LL_DEBUG3, "hcache uidvalidity %u, uidnext %u, modseq %llu\n",
198  mdata->uidvalidity, mdata->uid_next, mdata->modseq);
199  }
200  mutt_hcache_free_raw(mdata->hcache, &uidvalidity);
201  mutt_hcache_free_raw(mdata->hcache, &uidnext);
202  mutt_hcache_free_raw(mdata->hcache, (void **) &modseq);
203  imap_hcache_close(mdata);
204  }
205 #endif
206 
207  return mdata;
208 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
uint32_t uidvalidity
Definition: private.h:228
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:475
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:65
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:222
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
struct HeaderCache * hcache
Definition: private.h:242
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:508
#define STAILQ_INIT(head)
Definition: queue.h:369
void * mdata
Driver specific data.
Definition: mailbox.h:136
unsigned long long modseq
Definition: private.h:230
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:435
struct ListHead flags
Definition: private.h:227
char * name
Mailbox name.
Definition: private.h:218
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:220
unsigned int uid_next
Definition: private.h:229
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
IMAP-specific Mailbox data -.
Definition: private.h:216
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1045
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:490
char * munge_name
Munged version of the mailbox name.
Definition: private.h:219
Log at debug level 3.
Definition: logging.h:42
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:192
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_cache_reset()

void imap_mdata_cache_reset ( struct ImapMboxData mdata)

Release and clear cache data of ImapMboxData structure.

Parameters
mdataImap Mailbox data

Definition at line 214 of file util.c.

215 {
216  mutt_hash_free(&mdata->uid_hash);
217  FREE(&mdata->msn_index);
218  mdata->msn_index_size = 0;
219  mdata->max_msn = 0;
220  mutt_bcache_close(&mdata->bcache);
221 }
struct Email ** msn_index
look up headers by (MSN-1)
Definition: private.h:237
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
size_t msn_index_size
allocation size
Definition: private.h:238
unsigned int max_msn
the largest MSN fetched so far
Definition: private.h:239
struct BodyCache * bcache
Definition: private.h:240
struct HashTable * uid_hash
Definition: private.h:236
#define FREE(x)
Definition: memory.h:40
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:157
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_free()

void imap_mdata_free ( void **  ptr)

Free the private Mailbox data - Implements Mailbox::mdata_free()

Definition at line 226 of file util.c.

227 {
228  if (!ptr || !*ptr)
229  return;
230 
231  struct ImapMboxData *mdata = *ptr;
232 
233  imap_mdata_cache_reset(mdata);
234  mutt_list_free(&mdata->flags);
235  FREE(&mdata->name);
236  FREE(&mdata->real_name);
237  FREE(&mdata->munge_name);
238  FREE(ptr);
239 }
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
void * mdata
Driver specific data.
Definition: mailbox.h:136
struct ListHead flags
Definition: private.h:227
char * name
Mailbox name.
Definition: private.h:218
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:214
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:220
IMAP-specific Mailbox data -.
Definition: private.h:216
#define FREE(x)
Definition: memory.h:40
char * munge_name
Munged version of the mailbox name.
Definition: private.h:219
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mdata_get()

struct ImapMboxData* imap_mdata_get ( struct Mailbox m)

Get the Mailbox data for this mailbox.

Parameters
mMailbox

Definition at line 245 of file util.c.

246 {
247  if (!m || (m->type != MUTT_IMAP) || !m->mdata)
248  return NULL;
249  return m->mdata;
250 }
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the caller graph for this function:

◆ imap_get_parent()

void imap_get_parent ( const char *  mbox,
char  delim,
char *  buf,
size_t  buflen 
)

Get an IMAP folder's parent.

Parameters
mboxMailbox whose parent is to be determined
delimPath delimiter
bufBuffer for the result
buflenLength of the buffer

Definition at line 259 of file util.c.

260 {
261  /* Make a copy of the mailbox name, but only if the pointers are different */
262  if (mbox != buf)
263  mutt_str_copy(buf, mbox, buflen);
264 
265  int n = mutt_str_len(buf);
266 
267  /* Let's go backwards until the next delimiter
268  *
269  * If buf[n] is a '/', the first n-- will allow us
270  * to ignore it. If it isn't, then buf looks like
271  * "/aaaaa/bbbb". There is at least one "b", so we can't skip
272  * the "/" after the 'a's.
273  *
274  * If buf == '/', then n-- => n == 0, so the loop ends
275  * immediately */
276  for (n--; (n >= 0) && (buf[n] != delim); n--)
277  ; // do nothing
278 
279  /* We stopped before the beginning. There is a trailing slash. */
280  if (n > 0)
281  {
282  /* Strip the trailing delimiter. */
283  buf[n] = '\0';
284  }
285  else
286  {
287  buf[0] = (n == 0) ? delim : '\0';
288  }
289 }
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int n
Definition: acutest.h:492
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_parent_path()

void imap_get_parent_path ( const char *  path,
char *  buf,
size_t  buflen 
)

Get the path of the parent folder.

Parameters
pathMailbox whose parent is to be determined
bufBuffer for the result
buflenLength of the buffer

Provided an imap path, returns in buf the parent directory if existent. Else returns the same path.

Definition at line 300 of file util.c.

301 {
302  struct ImapAccountData *adata = NULL;
303  struct ImapMboxData *mdata = NULL;
304  char mbox[1024];
305 
306  if (imap_adata_find(path, &adata, &mdata) < 0)
307  {
308  mutt_str_copy(buf, path, buflen);
309  return;
310  }
311 
312  /* Gets the parent mbox in mbox */
313  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
314 
315  /* Returns a fully qualified IMAP url */
316  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
317  imap_mdata_free((void *) &mdata);
318 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:226
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:128
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder&#39;s parent.
Definition: util.c:259
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:218
IMAP-specific Account data -.
Definition: private.h:169
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
IMAP-specific Mailbox data -.
Definition: private.h:216
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
struct Connection * conn
Definition: private.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_clean_path()

void imap_clean_path ( char *  path,
size_t  plen 
)

Cleans an IMAP path using imap_fix_path.

Parameters
pathPath to be cleaned
plenLength of the buffer

Does it in place.

Definition at line 327 of file util.c.

328 {
329  struct ImapAccountData *adata = NULL;
330  struct ImapMboxData *mdata = NULL;
331 
332  if (imap_adata_find(path, &adata, &mdata) < 0)
333  return;
334 
335  /* Returns a fully qualified IMAP url */
336  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
337  imap_mdata_free((void *) &mdata);
338 }
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:226
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:128
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
char * name
Mailbox name.
Definition: private.h:218
IMAP-specific Account data -.
Definition: private.h:169
IMAP-specific Mailbox data -.
Definition: private.h:216
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
struct Connection * conn
Definition: private.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_field()

static const char* imap_get_field ( enum ConnAccountField  field,
void *  gf_data 
)
static

Get connection login credentials - Implements ConnAccount::get_field()

Definition at line 343 of file util.c.

344 {
345  switch (field)
346  {
347  case MUTT_CA_LOGIN:
348  return C_ImapLogin;
349  case MUTT_CA_USER:
350  return C_ImapUser;
351  case MUTT_CA_PASS:
352  return C_ImapPass;
353  case MUTT_CA_OAUTH_CMD:
355  case MUTT_CA_HOST:
356  default:
357  return NULL;
358  }
359 }
char * C_ImapOauthRefreshCommand
Config: (imap) External command to generate OAUTH refresh token.
Definition: config.c:49
Password.
Definition: connaccount.h:36
char * C_ImapUser
Config: (imap) Username for the IMAP server.
Definition: config.c:58
User name.
Definition: connaccount.h:35
OAuth refresh command.
Definition: connaccount.h:37
Login name.
Definition: connaccount.h:34
char * C_ImapPass
Config: (imap) Password for the IMAP server.
Definition: config.c:50
Server name.
Definition: connaccount.h:33
char * C_ImapLogin
Config: (imap) Login name for the IMAP server (defaults to C_ImapUser)
Definition: config.c:48
+ Here is the caller graph for this function:

◆ imap_msn_index_to_uid_seqset()

static void imap_msn_index_to_uid_seqset ( struct Buffer buf,
struct ImapMboxData mdata 
)
static

Convert MSN index of UIDs to Seqset.

Parameters
bufBuffer for the result
mdataImap Mailbox data

Generates a seqseq of the UIDs in msn_index to persist in the header cache. Empty spots are stored as 0.

Definition at line 370 of file util.c.

371 {
372  int first = 1, state = 0;
373  unsigned int cur_uid = 0, last_uid = 0;
374  unsigned int range_begin = 0, range_end = 0;
375 
376  for (unsigned int msn = 1; msn <= mdata->max_msn + 1; msn++)
377  {
378  bool match = false;
379  if (msn <= mdata->max_msn)
380  {
381  struct Email *e_cur = mdata->msn_index[msn - 1];
382  cur_uid = e_cur ? imap_edata_get(e_cur)->uid : 0;
383  if (!state || (cur_uid && ((cur_uid - 1) == last_uid)))
384  match = true;
385  last_uid = cur_uid;
386  }
387 
388  if (match)
389  {
390  switch (state)
391  {
392  case 1: /* single: convert to a range */
393  state = 2;
394  /* fall through */
395  case 2: /* extend range ending */
396  range_end = cur_uid;
397  break;
398  default:
399  state = 1;
400  range_begin = cur_uid;
401  break;
402  }
403  }
404  else if (state)
405  {
406  if (first)
407  first = 0;
408  else
409  mutt_buffer_addch(buf, ',');
410 
411  if (state == 1)
412  mutt_buffer_add_printf(buf, "%u", range_begin);
413  else if (state == 2)
414  mutt_buffer_add_printf(buf, "%u:%u", range_begin, range_end);
415 
416  state = 1;
417  range_begin = cur_uid;
418  }
419  }
420 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
The envelope/body of an email.
Definition: email.h:37
struct Email ** msn_index
look up headers by (MSN-1)
Definition: private.h:237
unsigned int max_msn
the largest MSN fetched so far
Definition: private.h:239
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
unsigned int uid
32-bit Message UID
Definition: message.h:44
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_namer()

static void imap_hcache_namer ( const char *  path,
struct Buffer dest 
)
static

Generate a filename for the header cache - Implements hcache_namer_t.

Definition at line 425 of file util.c.

426 {
427  mutt_buffer_printf(dest, "%s.hcache", path);
428 }
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_open()

void imap_hcache_open ( struct ImapAccountData adata,
struct ImapMboxData mdata 
)

Open a header cache.

Parameters
adataImap Account data
mdataImap Mailbox data

Definition at line 435 of file util.c.

436 {
437  if (!adata || !mdata)
438  return;
439 
440  if (mdata->hcache)
441  return;
442 
443  struct HeaderCache *hc = NULL;
444  struct Buffer *mbox = mutt_buffer_pool_get();
445  struct Buffer *cachepath = mutt_buffer_pool_get();
446 
447  imap_cachepath(adata->delim, mdata->name, mbox);
448 
449  if (strstr(mutt_b2s(mbox), "/../") || mutt_str_equal(mutt_b2s(mbox), "..") ||
450  mutt_strn_equal(mutt_b2s(mbox), "../", 3))
451  {
452  goto cleanup;
453  }
454  size_t len = mutt_buffer_len(mbox);
455  if ((len > 3) && (strcmp(mutt_b2s(mbox) + len - 3, "/..") == 0))
456  goto cleanup;
457 
458  struct Url url = { 0 };
459  mutt_account_tourl(&adata->conn->account, &url);
460  url.path = mbox->data;
461  url_tobuffer(&url, cachepath, U_PATH);
462 
464 
465 cleanup:
467  mutt_buffer_pool_release(&cachepath);
468  mdata->hcache = hc;
469 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
static void imap_hcache_namer(const char *path, struct Buffer *dest)
Generate a filename for the header cache - Implements hcache_namer_t.
Definition: util.c:425
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:37
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
header cache structure
Definition: lib.h:85
String manipulation buffer.
Definition: buffer.h:33
struct HeaderCache * hcache
Definition: private.h:242
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:316
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:850
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
char * data
Pointer to data.
Definition: buffer.h:35
char * name
Mailbox name.
Definition: private.h:218
char * path
Path.
Definition: url.h:73
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:598
int url_tobuffer(struct Url *url, struct Buffer *buf, int flags)
Output the URL string for a given Url object.
Definition: url.c:353
#define U_PATH
Definition: url.h:48
struct Connection * conn
Definition: private.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_close()

void imap_hcache_close ( struct ImapMboxData mdata)

Close the header cache.

Parameters
mdataImap Mailbox data

Definition at line 475 of file util.c.

476 {
477  if (!mdata->hcache)
478  return;
479 
480  mutt_hcache_close(mdata->hcache);
481  mdata->hcache = NULL;
482 }
struct HeaderCache * hcache
Definition: private.h:242
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:413
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_get()

struct Email* imap_hcache_get ( struct ImapMboxData mdata,
unsigned int  uid 
)

Get a header cache entry by its UID.

Parameters
mdataImap Mailbox data
uidUID to find
Return values
ptrEmail
NULLFailure

Definition at line 491 of file util.c.

492 {
493  if (!mdata->hcache)
494  return NULL;
495 
496  char key[16];
497 
498  sprintf(key, "/%u", uid);
499  struct HCacheEntry hce =
500  mutt_hcache_fetch(mdata->hcache, key, mutt_str_len(key), mdata->uidvalidity);
501  if (!hce.email && hce.uidvalidity)
502  {
503  mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
504  }
505 
506  return hce.email;
507 }
Wrapper for Email retrieved from the header cache.
Definition: lib.h:96
uint32_t uidvalidity
Definition: private.h:228
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition: lib.h:98
struct HeaderCache * hcache
Definition: private.h:242
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
struct HCacheEntry mutt_hcache_fetch(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition: hcache.c:432
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Email * email
Retrieved email.
Definition: lib.h:100
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_put()

int imap_hcache_put ( struct ImapMboxData mdata,
struct Email e 
)

Add an entry to the header cache.

Parameters
mdataImap Mailbox data
eEmail
Return values
0Success
-1Failure

Definition at line 516 of file util.c.

517 {
518  if (!mdata->hcache)
519  return -1;
520 
521  char key[16];
522 
523  sprintf(key, "/%u", imap_edata_get(e)->uid);
524  return mutt_hcache_store(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
525 }
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:98
uint32_t uidvalidity
Definition: private.h:228
struct HeaderCache * hcache
Definition: private.h:242
int mutt_hcache_store(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:521
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_del()

int imap_hcache_del ( struct ImapMboxData mdata,
unsigned int  uid 
)

Delete an item from the header cache.

Parameters
mdataImap Mailbox data
uidUID of entry to delete
Return values
0Success
-1Failure

Definition at line 534 of file util.c.

535 {
536  if (!mdata->hcache)
537  return -1;
538 
539  char key[16];
540 
541  sprintf(key, "/%u", uid);
542  return mutt_hcache_delete_record(mdata->hcache, key, mutt_str_len(key));
543 }
struct HeaderCache * hcache
Definition: private.h:242
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:598
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_store_uid_seqset()

int imap_hcache_store_uid_seqset ( struct ImapMboxData mdata)

Store a UID Sequence Set in the header cache.

Parameters
mdataImap Mailbox data
Return values
0Success
-1Error

Definition at line 551 of file util.c.

552 {
553  if (!mdata->hcache)
554  return -1;
555 
556  /* The seqset is likely large. Preallocate to reduce reallocs */
557  struct Buffer buf = mutt_buffer_make(8192);
558  imap_msn_index_to_uid_seqset(&buf, mdata);
559 
560  int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
561  mutt_buffer_len(&buf) + 1);
562  mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
563  mutt_buffer_dealloc(&buf);
564  return rc;
565 }
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
String manipulation buffer.
Definition: buffer.h:33
struct HeaderCache * hcache
Definition: private.h:242
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
char * data
Pointer to data.
Definition: buffer.h:35
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:578
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:370
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_clear_uid_seqset()

int imap_hcache_clear_uid_seqset ( struct ImapMboxData mdata)

Delete a UID Sequence Set from the header cache.

Parameters
mdataImap Mailbox data
Return values
0Success
-1Error

Definition at line 573 of file util.c.

574 {
575  if (!mdata->hcache)
576  return -1;
577 
578  return mutt_hcache_delete_record(mdata->hcache, "/UIDSEQSET", 10);
579 }
struct HeaderCache * hcache
Definition: private.h:242
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:598
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_get_uid_seqset()

char* imap_hcache_get_uid_seqset ( struct ImapMboxData mdata)

Get a UID Sequence Set from the header cache.

Parameters
mdataImap Mailbox data
Return values
ptrUID Sequence Set
NULLError

Definition at line 587 of file util.c.

588 {
589  if (!mdata->hcache)
590  return NULL;
591 
592  char *seqset = NULL;
593  size_t dlen = 0;
594  char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10, &dlen);
595  if (hc_seqset)
596  {
597  seqset = strndup(hc_seqset, dlen);
598  mutt_hcache_free_raw(mdata->hcache, (void **) &hc_seqset);
599  }
600  mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
601 
602  return seqset;
603 }
#define NONULL(x)
Definition: string2.h:37
struct HeaderCache * hcache
Definition: private.h:242
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:508
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:490
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_parse_path()

int imap_parse_path ( const char *  path,
struct ConnAccount cac,
char *  mailbox,
size_t  mailboxlen 
)

Parse an IMAP mailbox name into ConnAccount, name.

Parameters
pathMailbox path to parse
cacAccount credentials
mailboxBuffer for mailbox name
mailboxlenLength of buffer
Return values
0Success
-1Failure

Given an IMAP mailbox name, return host, port and a path IMAP servers will recognize.

Definition at line 618 of file util.c.

619 {
620  static unsigned short ImapPort = 0;
621  static unsigned short ImapsPort = 0;
622 
623  if (ImapPort == 0)
624  {
625  struct servent *service = getservbyname("imap", "tcp");
626  if (service)
627  ImapPort = ntohs(service->s_port);
628  else
629  ImapPort = IMAP_PORT;
630  mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
631  }
632 
633  if (ImapsPort == 0)
634  {
635  struct servent *service = getservbyname("imaps", "tcp");
636  if (service)
637  ImapsPort = ntohs(service->s_port);
638  else
639  ImapsPort = IMAP_SSL_PORT;
640  mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
641  }
642 
643  /* Defaults */
644  cac->port = ImapPort;
645  cac->type = MUTT_ACCT_TYPE_IMAP;
646  cac->service = "imap";
647  cac->get_field = imap_get_field;
648 
649  struct Url *url = url_parse(path);
650  if (!url)
651  return -1;
652 
653  if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
654  {
655  url_free(&url);
656  return -1;
657  }
658 
659  if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
660  {
661  url_free(&url);
662  return -1;
663  }
664 
665  if (url->scheme == U_IMAPS)
666  cac->flags |= MUTT_ACCT_SSL;
667 
668  mutt_str_copy(mailbox, url->path, mailboxlen);
669 
670  url_free(&url);
671 
672  if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
673  cac->port = ImapsPort;
674 
675  return 0;
676 }
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:45
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:44
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:68
Url is imaps://.
Definition: url.h:39
Url is imap://.
Definition: url.h:38
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:343
char host[128]
Server to login to.
Definition: connaccount.h:53
unsigned short port
Port to connect to.
Definition: connaccount.h:57
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:42
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
Imap Account.
Definition: mutt_account.h:37
char * path
Path.
Definition: url.h:73
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 3.
Definition: logging.h:42
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_mxcmp()

int imap_mxcmp ( const char *  mx1,
const char *  mx2 
)

Compare mailbox names, giving priority to INBOX.

Parameters
mx1First mailbox name
mx2Second mailbox name
Return values
<0First mailbox precedes Second mailbox
0Mailboxes are the same
>0Second mailbox precedes First mailbox

Like a normal sort function except that "INBOX" will be sorted to the beginning of the list.

Definition at line 689 of file util.c.

690 {
691  char *b1 = NULL;
692  char *b2 = NULL;
693  int rc;
694 
695  if (!mx1 || (*mx1 == '\0'))
696  mx1 = "INBOX";
697  if (!mx2 || (*mx2 == '\0'))
698  mx2 = "INBOX";
699  if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
700  {
701  return 0;
702  }
703 
704  b1 = mutt_mem_malloc(strlen(mx1) + 1);
705  b2 = mutt_mem_malloc(strlen(mx2) + 1);
706 
707  imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
708  imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
709 
710  rc = mutt_str_cmp(b1, b2);
711  FREE(&b1);
712  FREE(&b2);
713 
714  return rc;
715 }
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:572
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_pretty_mailbox()

void imap_pretty_mailbox ( char *  path,
size_t  pathlen,
const char *  folder 
)

Prettify an IMAP mailbox name.

Parameters
pathMailbox name to be tidied
pathlenLength of path
folderPath to use for '+' abbreviations

Called by mutt_pretty_mailbox() to make IMAP paths look nice.

Definition at line 725 of file util.c.

726 {
727  struct ConnAccount cac_target = { { 0 } };
728  struct ConnAccount cac_home = { { 0 } };
729  struct Url url = { 0 };
730  char *delim = NULL;
731  int tlen;
732  int hlen = 0;
733  bool home_match = false;
734  char target_mailbox[1024];
735  char home_mailbox[1024];
736 
737  if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
738  return;
739 
740  if (imap_path_probe(folder, NULL) != MUTT_IMAP)
741  goto fallback;
742 
743  if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
744  goto fallback;
745 
746  tlen = mutt_str_len(target_mailbox);
747  hlen = mutt_str_len(home_mailbox);
748 
749  /* check whether we can do '+' substitution */
750  if (tlen && imap_account_match(&cac_home, &cac_target) &&
751  mutt_strn_equal(home_mailbox, target_mailbox, hlen))
752  {
753  if (hlen == 0)
754  home_match = true;
755  else if (C_ImapDelimChars)
756  {
757  for (delim = C_ImapDelimChars; *delim != '\0'; delim++)
758  if (target_mailbox[hlen] == *delim)
759  home_match = true;
760  }
761  }
762 
763  /* do the '+' substitution */
764  if (home_match)
765  {
766  *path++ = '+';
767  /* copy remaining path, skipping delimiter */
768  if (hlen == 0)
769  hlen = -1;
770  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
771  path[tlen - hlen - 1] = '\0';
772  return;
773  }
774 
775 fallback:
776  mutt_account_tourl(&cac_target, &url);
777  url.path = target_mailbox;
778  url_tostring(&url, path, pathlen, 0);
779 }
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2352
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
Parse an IMAP mailbox name into ConnAccount, name.
Definition: util.c:618
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: config.c:42
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1178
Login details for a remote server.
Definition: connaccount.h:51
char * path
Path.
Definition: url.h:73
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:598
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:418
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_continue()

enum QuadOption imap_continue ( const char *  msg,
const char *  resp 
)

display a message and ask the user if they want to go on

Parameters
msgLocation of the error
respMessage for user
Return values
QuadOptionResult, e.g. MUTT_NO

Definition at line 787 of file util.c.

788 {
789  imap_error(msg, resp);
790  return mutt_yesorno(_("Continue?"), MUTT_NO);
791 }
#define _(a)
Definition: message.h:28
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_error()

void imap_error ( const char *  where,
const char *  msg 
)

show an error and abort

Parameters
whereLocation of the error
msgMessage for user

Definition at line 798 of file util.c.

799 {
800  mutt_error("%s [%s]", where, msg);
801 }
#define mutt_error(...)
Definition: logging.h:84
+ Here is the caller graph for this function:

◆ imap_fix_path()

char* imap_fix_path ( char  delim,
const char *  mailbox,
char *  path,
size_t  plen 
)

Fix up the imap path.

Parameters
delimDelimiter specified by the server, '\0' for C_ImapDelimChars
mailboxMailbox path
pathBuffer for the result
plenLength of buffer
Return values
ptrFixed-up path
Note
if delim is '\0', the first character in mailbox matching any of the characters in C_ImapDelimChars is used as a delimiter.

This is necessary because the rest of neomutt assumes a hierarchy delimiter of '/', which is not necessarily true in IMAP. Additionally, the filesystem converts multiple hierarchy delimiters into a single one, ie "///" is equal to "/". IMAP servers are not required to do this. Moreover, IMAP servers may dislike the path ending with the delimiter.

Definition at line 820 of file util.c.

821 {
822  int i = 0;
823  for (; mailbox && *mailbox && (i < plen - 1); i++)
824  {
825  if (*mailbox == delim || (!delim && strchr(NONULL(C_ImapDelimChars), *mailbox)))
826  {
827  delim = *mailbox;
828  /* Skip multiple occurrences of delim */
829  while (*mailbox && *(mailbox + 1) == delim)
830  mailbox++;
831  }
832  path[i] = *mailbox++;
833  }
834 
835  /* Do not terminate with a delimiter */
836  if (i && path[i - 1] == delim)
837  i--;
838 
839  /* Ensure null termination */
840  path[i] = '\0';
841  return path;
842 }
#define NONULL(x)
Definition: string2.h:37
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: config.c:42
char * path
Path.
Definition: url.h:73
+ Here is the caller graph for this function:

◆ imap_cachepath()

void imap_cachepath ( char  delim,
const char *  mailbox,
struct Buffer dest 
)

Generate a cache path for a mailbox.

Parameters
delimImap server delimiter
mailboxMailbox name
destBuffer to store cache path

Definition at line 850 of file util.c.

851 {
852  const char *p = mailbox;
853  mutt_buffer_reset(dest);
854  if (!p)
855  return;
856 
857  while (*p)
858  {
859  if (p[0] == delim)
860  {
861  mutt_buffer_addch(dest, '/');
862  /* simple way to avoid collisions with UIDs */
863  if ((p[1] >= '0') && (p[1] <= '9'))
864  mutt_buffer_addch(dest, '_');
865  }
866  else
867  mutt_buffer_addch(dest, *p);
868  p++;
869  }
870 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_literal_count()

int imap_get_literal_count ( const char *  buf,
unsigned int *  bytes 
)

write number of bytes in an IMAP literal into bytes

Parameters
[in]bufNumber as a string
[out]bytesResulting number
Return values
0Success
-1Failure

Definition at line 879 of file util.c.

880 {
881  char *pc = NULL;
882  char *pn = NULL;
883 
884  if (!buf || !(pc = strchr(buf, '{')))
885  return -1;
886 
887  pc++;
888  pn = pc;
889  while (isdigit((unsigned char) *pc))
890  pc++;
891  *pc = '\0';
892  if (mutt_str_atoui(pn, bytes) < 0)
893  return -1;
894 
895  return 0;
896 }
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:287
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_qualifier()

char* imap_get_qualifier ( char *  buf)

Get the qualifier from a tagged response.

Parameters
bufCommand string to process
Return values
ptrStart of the qualifier

In a tagged response, skip tag and status for the qualifier message. Used by imap_copy_message for TRYCREATE

Definition at line 906 of file util.c.

907 {
908  char *s = buf;
909 
910  /* skip tag */
911  s = imap_next_word(s);
912  /* skip OK/NO/BAD response */
913  s = imap_next_word(s);
914 
915  return s;
916 }
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_next_word()

char* imap_next_word ( char *  s)

Find where the next IMAP word begins.

Parameters
sCommand string to process
Return values
ptrNext IMAP word

Definition at line 923 of file util.c.

924 {
925  bool quoted = false;
926 
927  while (*s)
928  {
929  if (*s == '\\')
930  {
931  s++;
932  if (*s)
933  s++;
934  continue;
935  }
936  if (*s == '\"')
937  quoted = !quoted;
938  if (!quoted && IS_SPACE(*s))
939  break;
940  s++;
941  }
942 
943  SKIPWS(s);
944  return s;
945 }
#define SKIPWS(ch)
Definition: string2.h:46
#define IS_SPACE(ch)
Definition: string2.h:38
+ Here is the caller graph for this function:

◆ imap_qualify_path()

void imap_qualify_path ( char *  buf,
size_t  buflen,
struct ConnAccount cac,
char *  path 
)

Make an absolute IMAP folder target.

Parameters
bufBuffer for the result
buflenLength of buffer
cacConnAccount of the account
pathPath relative to the mailbox

Definition at line 954 of file util.c.

955 {
956  struct Url url = { 0 };
957  mutt_account_tourl(cac, &url);
958  url.path = path;
959  url_tostring(&url, buf, buflen, 0);
960 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
char * path
Path.
Definition: url.h:73
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:418
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_quote_string()

void imap_quote_string ( char *  dest,
size_t  dlen,
const char *  src,
bool  quote_backtick 
)

quote string according to IMAP rules

Parameters
destBuffer for the result
dlenLength of the buffer
srcString to be quoted
quote_backtickIf true, quote backticks too

Surround string with quotes, escape " and \ with backslash

Definition at line 971 of file util.c.

972 {
973  const char *quote = "`\"\\";
974  if (!quote_backtick)
975  quote++;
976 
977  char *pt = dest;
978  const char *s = src;
979 
980  *pt++ = '"';
981  /* save room for quote-chars */
982  dlen -= 3;
983 
984  for (; *s && dlen; s++)
985  {
986  if (strchr(quote, *s))
987  {
988  if (dlen < 2)
989  break;
990  dlen -= 2;
991  *pt++ = '\\';
992  *pt++ = *s;
993  }
994  else
995  {
996  *pt++ = *s;
997  dlen--;
998  }
999  }
1000  *pt++ = '"';
1001  *pt = '\0';
1002 }
char * src
Raw URL string.
Definition: url.h:75
+ Here is the caller graph for this function:

◆ imap_unquote_string()

void imap_unquote_string ( char *  s)

equally stupid unquoting routine

Parameters
sString to be unquoted

Definition at line 1008 of file util.c.

1009 {
1010  char *d = s;
1011 
1012  if (*s == '\"')
1013  s++;
1014  else
1015  return;
1016 
1017  while (*s)
1018  {
1019  if (*s == '\"')
1020  {
1021  *d = '\0';
1022  return;
1023  }
1024  if (*s == '\\')
1025  {
1026  s++;
1027  }
1028  if (*s)
1029  {
1030  *d = *s;
1031  d++;
1032  s++;
1033  }
1034  }
1035  *d = '\0';
1036 }
+ Here is the caller graph for this function:

◆ imap_munge_mbox_name()

void imap_munge_mbox_name ( bool  unicode,
char *  dest,
size_t  dlen,
const char *  src 
)

Quote awkward characters in a mailbox name.

Parameters
unicodetrue if Unicode is allowed
destBuffer to store safe mailbox name
dlenLength of buffer
srcMailbox name

Definition at line 1045 of file util.c.

1046 {
1047  char *buf = mutt_str_dup(src);
1048  imap_utf_encode(unicode, &buf);
1049 
1050  imap_quote_string(dest, dlen, buf, false);
1051 
1052  FREE(&buf);
1053 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
void imap_utf_encode(bool unicode, char **s)
Encode email from local charset to UTF-8.
Definition: utf7.c:316
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:971
#define FREE(x)
Definition: memory.h:40
char * src
Raw URL string.
Definition: url.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_unmunge_mbox_name()

void imap_unmunge_mbox_name ( bool  unicode,
char *  s 
)

Remove quoting from a mailbox name.

Parameters
unicodetrue if Unicode is allowed
sMailbox name

The string will be altered in-place.

Definition at line 1062 of file util.c.

1063 {
1065 
1066  char *buf = mutt_str_dup(s);
1067  if (buf)
1068  {
1069  imap_utf_decode(unicode, &buf);
1070  strncpy(s, buf, strlen(s));
1071  }
1072 
1073  FREE(&buf);
1074 }
void imap_unquote_string(char *s)
equally stupid unquoting routine
Definition: util.c:1008
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:345
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_keepalive()

void imap_keepalive ( void  )

poll the current folder to keep the connection alive

Definition at line 1079 of file util.c.

1080 {
1081  time_t now = mutt_date_epoch();
1082  struct Account *np = NULL;
1083  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1084  {
1085  if (np->type != MUTT_IMAP)
1086  continue;
1087 
1088  struct ImapAccountData *adata = np->adata;
1089  if (!adata || !adata->mailbox)
1090  continue;
1091 
1092  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + C_ImapKeepalive)))
1093  imap_check_mailbox(adata->mailbox, true);
1094  }
1095 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
Connection is authenticated.
Definition: private.h:108
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:174
A group of associated Mailboxes.
Definition: account.h:36
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:206
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:36
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
time_t lastread
last time we read a command for the server
Definition: private.h:188
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:46
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1061
IMAP-specific Account data -.
Definition: private.h:169
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_wait_keepalive()

int imap_wait_keepalive ( pid_t  pid)

Wait for a process to change state.

Parameters
pidProcess ID to listen to
Return values
num'wstatus' from waitpid()

Definition at line 1102 of file util.c.

1103 {
1104  struct sigaction oldalrm;
1105  struct sigaction act;
1106  sigset_t oldmask;
1107  int rc;
1108 
1109  bool imap_passive = C_ImapPassive;
1110 
1111  C_ImapPassive = true;
1112  OptKeepQuiet = true;
1113 
1114  sigprocmask(SIG_SETMASK, NULL, &oldmask);
1115 
1116  sigemptyset(&act.sa_mask);
1117  act.sa_handler = mutt_sig_empty_handler;
1118 #ifdef SA_INTERRUPT
1119  act.sa_flags = SA_INTERRUPT;
1120 #else
1121  act.sa_flags = 0;
1122 #endif
1123 
1124  sigaction(SIGALRM, &act, &oldalrm);
1125 
1126  alarm(C_ImapKeepalive);
1127  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1128  {
1129  alarm(0); /* cancel a possibly pending alarm */
1130  imap_keepalive();
1131  alarm(C_ImapKeepalive);
1132  }
1133 
1134  alarm(0); /* cancel a possibly pending alarm */
1135 
1136  sigaction(SIGALRM, &oldalrm, NULL);
1137  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1138 
1139  OptKeepQuiet = false;
1140  if (!imap_passive)
1141  C_ImapPassive = false;
1142 
1143  return rc;
1144 }
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:57
bool C_ImapPassive
Config: (imap) Reuse an existing IMAP connection to check for new mail.
Definition: config.c:51
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:46
void imap_keepalive(void)
poll the current folder to keep the connection alive
Definition: util.c:1079
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_allow_reopen()

void imap_allow_reopen ( struct Mailbox m)

Allow re-opening a folder upon expunge.

Parameters
mMailbox

Definition at line 1150 of file util.c.

1151 {
1152  struct ImapAccountData *adata = imap_adata_get(m);
1153  struct ImapMboxData *mdata = imap_mdata_get(m);
1154  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1155  return;
1156  mdata->reopen |= IMAP_REOPEN_ALLOW;
1157 }
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:65
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:222
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:206
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:113
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:245
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:169
IMAP-specific Mailbox data -.
Definition: private.h:216
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_disallow_reopen()

void imap_disallow_reopen ( struct Mailbox m)

Disallow re-opening a folder upon expunge.

Parameters
mMailbox

Definition at line 1163 of file util.c.

1164 {
1165  struct ImapAccountData *adata = imap_adata_get(m);
1166  struct ImapMboxData *mdata = imap_mdata_get(m);
1167  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1168  return;
1169  mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1170 }
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:65
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:222
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:206
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:113
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:245
void * mdata
Driver specific data.
Definition: mailbox.h:136
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
IMAP-specific Account data -.
Definition: private.h:169
IMAP-specific Mailbox data -.
Definition: private.h:216
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_account_match()

bool imap_account_match ( const struct ConnAccount a1,
const struct ConnAccount a2 
)

Compare two Accounts.

Parameters
a1First ConnAccount
a2Second ConnAccount
Return values
trueAccounts match

Definition at line 1178 of file util.c.

1179 {
1180  if (!a1 || !a2)
1181  return false;
1182  if (a1->type != a2->type)
1183  return false;
1184  if (!mutt_istr_equal(a1->host, a2->host))
1185  return false;
1186  if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1187  return false;
1188  if (a1->flags & a2->flags & MUTT_ACCT_USER)
1189  return strcmp(a1->user, a2->user) == 0;
1190 
1191  const char *user = NONULL(Username);
1192 
1193  if ((a1->type == MUTT_ACCT_TYPE_IMAP) && C_ImapUser)
1194  user = C_ImapUser;
1195 
1196  if (a1->flags & MUTT_ACCT_USER)
1197  return strcmp(a1->user, user) == 0;
1198  if (a2->flags & MUTT_ACCT_USER)
1199  return strcmp(a2->user, user) == 0;
1200 
1201  return true;
1202 }
#define NONULL(x)
Definition: string2.h:37
char user[128]
Username.
Definition: connaccount.h:55
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
char host[128]
Server to login to.
Definition: connaccount.h:53
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:52
char * C_ImapUser
Config: (imap) Username for the IMAP server.
Definition: config.c:58
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
unsigned short port
Port to connect to.
Definition: connaccount.h:57
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
Imap Account.
Definition: mutt_account.h:37
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_new()

struct SeqsetIterator* mutt_seqset_iterator_new ( const char *  seqset)

Create a new Sequence Set Iterator.

Parameters
seqsetSource Sequence Set
Return values
ptrNewly allocated Sequence Set Iterator

Definition at line 1209 of file util.c.

1210 {
1211  if (!seqset || (*seqset == '\0'))
1212  return NULL;
1213 
1214  struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1215  iter->full_seqset = mutt_str_dup(seqset);
1216  iter->eostr = strchr(iter->full_seqset, '\0');
1217  iter->substr_cur = iter->substr_end = iter->full_seqset;
1218 
1219  return iter;
1220 }
char * eostr
Definition: private.h:251
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
char * substr_cur
Definition: private.h:256
char * substr_end
Definition: private.h:257
char * full_seqset
Definition: private.h:250
UID Sequence Set Iterator.
Definition: private.h:248
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_next()

int mutt_seqset_iterator_next ( struct SeqsetIterator iter,
unsigned int *  next 
)

Get the next UID from a Sequence Set.

Parameters
[in]iterSequence Set Iterator
[out]nextNext UID in set
Return values
0Next sequence is generated
1Iterator is finished
-1error

Definition at line 1230 of file util.c.

1231 {
1232  if (!iter || !next)
1233  return -1;
1234 
1235  if (iter->in_range)
1236  {
1237  if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1238  (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1239  {
1240  iter->in_range = 0;
1241  }
1242  }
1243 
1244  if (!iter->in_range)
1245  {
1246  iter->substr_cur = iter->substr_end;
1247  if (iter->substr_cur == iter->eostr)
1248  return 1;
1249 
1250  while (!*(iter->substr_cur))
1251  iter->substr_cur++;
1252  iter->substr_end = strchr(iter->substr_cur, ',');
1253  if (!iter->substr_end)
1254  iter->substr_end = iter->eostr;
1255  else
1256  *(iter->substr_end) = '\0';
1257 
1258  char *range_sep = strchr(iter->substr_cur, ':');
1259  if (range_sep)
1260  *range_sep++ = '\0';
1261 
1262  if (mutt_str_atoui(iter->substr_cur, &iter->range_cur) != 0)
1263  return -1;
1264  if (range_sep)
1265  {
1266  if (mutt_str_atoui(range_sep, &iter->range_end) != 0)
1267  return -1;
1268  }
1269  else
1270  iter->range_end = iter->range_cur;
1271 
1272  iter->down = (iter->range_end < iter->range_cur);
1273  iter->in_range = 1;
1274  }
1275 
1276  *next = iter->range_cur;
1277  if (iter->down)
1278  iter->range_cur--;
1279  else
1280  iter->range_cur++;
1281 
1282  return 0;
1283 }
char * eostr
Definition: private.h:251
unsigned int range_end
Definition: private.h:255
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:287
char * substr_cur
Definition: private.h:256
char * substr_end
Definition: private.h:257
unsigned int range_cur
Definition: private.h:254
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_free()

void mutt_seqset_iterator_free ( struct SeqsetIterator **  ptr)

Free a Sequence Set Iterator.

Parameters
[out]ptrIterator to free

Definition at line 1289 of file util.c.

1290 {
1291  if (!ptr || !*ptr)
1292  return;
1293 
1294  struct SeqsetIterator *iter = *ptr;
1295  FREE(&iter->full_seqset);
1296  FREE(ptr);
1297 }
#define FREE(x)
Definition: memory.h:40
char * full_seqset
Definition: private.h:250
UID Sequence Set Iterator.
Definition: private.h:248
+ Here is the caller graph for this function: