NeoMutt  2021-10-29-43-g6b8931
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 <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 "lib.h"
#include "bcache/lib.h"
#include "question/lib.h"
#include "adata.h"
#include "edata.h"
#include "mdata.h"
#include "msn.h"
#include "mutt_account.h"
#include "mutt_globals.h"
#include "options.h"
#include "hcache/lib.h"
+ Include dependency graph for util.c:

Go to the source code of this file.

Functions

int imap_adata_find (const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
 Find the Account data for this path. More...
 
void imap_mdata_cache_reset (struct ImapMboxData *mdata)
 Release and clear cache data of ImapMboxData structure. 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_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 72 of file util.c.

74 {
75  struct ConnAccount cac = { { 0 } };
76  struct ImapAccountData *tmp_adata = NULL;
77  char tmp[1024];
78 
79  if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
80  return -1;
81 
82  struct Account *np = NULL;
83  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
84  {
85  if (np->type != MUTT_IMAP)
86  continue;
87 
88  tmp_adata = np->adata;
89  if (!tmp_adata)
90  continue;
91  if (imap_account_match(&tmp_adata->conn->account, &cac))
92  {
93  *mdata = imap_mdata_new(tmp_adata, tmp);
94  *adata = tmp_adata;
95  return 0;
96  }
97  }
98  mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
99  return -1;
100 }
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: mdata.c:72
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:53
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
A group of associated Mailboxes.
Definition: account.h:37
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Login details for a remote server.
Definition: connaccount.h:53
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
IMAP-specific Account data -.
Definition: adata.h:40
struct Connection * conn
Connection to IMAP server.
Definition: adata.h:41
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
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:483
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1049
+ 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 106 of file util.c.

107 {
108  mutt_hash_free(&mdata->uid_hash);
109  imap_msn_free(&mdata->msn);
110  mutt_bcache_close(&mdata->bcache);
111 }
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:164
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
void imap_msn_free(struct MSN *msn)
Free the cache.
Definition: msn.c:58
struct BodyCache * bcache
Email body cache.
Definition: mdata.h:60
struct HashTable * uid_hash
Definition: mdata.h:58
+ Here is the call graph for this function:
+ 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 120 of file util.c.

121 {
122  /* Make a copy of the mailbox name, but only if the pointers are different */
123  if (mbox != buf)
124  mutt_str_copy(buf, mbox, buflen);
125 
126  int n = mutt_str_len(buf);
127 
128  /* Let's go backwards until the next delimiter
129  *
130  * If buf[n] is a '/', the first n-- will allow us
131  * to ignore it. If it isn't, then buf looks like
132  * "/aaaaa/bbbb". There is at least one "b", so we can't skip
133  * the "/" after the 'a's.
134  *
135  * If buf == '/', then n-- => n == 0, so the loop ends
136  * immediately */
137  for (n--; (n >= 0) && (buf[n] != delim); n--)
138  ; // do nothing
139 
140  /* We stopped before the beginning. There is a trailing slash. */
141  if (n > 0)
142  {
143  /* Strip the trailing delimiter. */
144  buf[n] = '\0';
145  }
146  else
147  {
148  buf[0] = (n == 0) ? delim : '\0';
149  }
150 }
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:475
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:560
+ 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 161 of file util.c.

162 {
163  struct ImapAccountData *adata = NULL;
164  struct ImapMboxData *mdata = NULL;
165  char mbox[1024];
166 
167  if (imap_adata_find(path, &adata, &mdata) < 0)
168  {
169  mutt_str_copy(buf, path, buflen);
170  return;
171  }
172 
173  /* Gets the parent mbox in mbox */
174  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
175 
176  /* Returns a fully qualified IMAP url */
177  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
178  imap_mdata_free((void *) &mdata);
179 }
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: mdata.c:40
char delim
Path delimiter.
Definition: adata.h:75
IMAP-specific Mailbox data -.
Definition: mdata.h:39
void * mdata
Driver specific data.
Definition: mailbox.h:136
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:823
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder's parent.
Definition: util.c:120
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:72
+ 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 188 of file util.c.

189 {
190  struct ImapAccountData *adata = NULL;
191  struct ImapMboxData *mdata = NULL;
192 
193  if (imap_adata_find(path, &adata, &mdata) < 0)
194  return;
195 
196  /* Returns a fully qualified IMAP url */
197  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
198  imap_mdata_free((void *) &mdata);
199 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
+ 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 204 of file util.c.

205 {
206  switch (field)
207  {
208  case MUTT_CA_LOGIN:
209  return cs_subset_string(NeoMutt->sub, "imap_login");
210  case MUTT_CA_USER:
211  return cs_subset_string(NeoMutt->sub, "imap_user");
212  case MUTT_CA_PASS:
213  return cs_subset_string(NeoMutt->sub, "imap_pass");
214  case MUTT_CA_OAUTH_CMD:
215  return cs_subset_string(NeoMutt->sub, "imap_oauth_refresh_command");
216  case MUTT_CA_HOST:
217  default:
218  return NULL;
219  }
220 }
@ MUTT_CA_OAUTH_CMD
OAuth refresh command.
Definition: connaccount.h:38
@ MUTT_CA_USER
User name.
Definition: connaccount.h:36
@ MUTT_CA_LOGIN
Login name.
Definition: connaccount.h:35
@ MUTT_CA_HOST
Server name.
Definition: connaccount.h:34
@ MUTT_CA_PASS
Password.
Definition: connaccount.h:37
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ 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 231 of file util.c.

232 {
233  int first = 1, state = 0;
234  unsigned int cur_uid = 0, last_uid = 0;
235  unsigned int range_begin = 0, range_end = 0;
236  const size_t max_msn = imap_msn_highest(&mdata->msn);
237 
238  for (unsigned int msn = 1; msn <= max_msn + 1; msn++)
239  {
240  bool match = false;
241  if (msn <= max_msn)
242  {
243  struct Email *e_cur = imap_msn_get(&mdata->msn, msn - 1);
244  cur_uid = e_cur ? imap_edata_get(e_cur)->uid : 0;
245  if (!state || (cur_uid && ((cur_uid - 1) == last_uid)))
246  match = true;
247  last_uid = cur_uid;
248  }
249 
250  if (match)
251  {
252  switch (state)
253  {
254  case 1: /* single: convert to a range */
255  state = 2;
256  /* fall through */
257  case 2: /* extend range ending */
258  range_end = cur_uid;
259  break;
260  default:
261  state = 1;
262  range_begin = cur_uid;
263  break;
264  }
265  }
266  else if (state)
267  {
268  if (first)
269  first = 0;
270  else
271  mutt_buffer_addch(buf, ',');
272 
273  if (state == 1)
274  mutt_buffer_add_printf(buf, "%u", range_begin);
275  else if (state == 2)
276  mutt_buffer_add_printf(buf, "%u:%u", range_begin, range_end);
277 
278  state = 1;
279  range_begin = cur_uid;
280  }
281  }
282 }
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: edata.c:64
struct Email * imap_msn_get(const struct MSN *msn, size_t idx)
Return the Email associated with an msn.
Definition: msn.c:79
size_t imap_msn_highest(const struct MSN *msn)
Return the highest MSN in use.
Definition: msn.c:68
The envelope/body of an email.
Definition: email.h:37
unsigned int uid
32-bit Message UID
Definition: edata.h:44
+ 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 297 of file util.c.

298 {
299  if (!adata || !mdata)
300  return;
301 
302  if (mdata->hcache)
303  return;
304 
305  struct HeaderCache *hc = NULL;
306  struct Buffer *mbox = mutt_buffer_pool_get();
307  struct Buffer *cachepath = mutt_buffer_pool_get();
308 
309  imap_cachepath(adata->delim, mdata->name, mbox);
310 
311  if (strstr(mutt_buffer_string(mbox), "/../") ||
312  mutt_str_equal(mutt_buffer_string(mbox), "..") ||
313  mutt_strn_equal(mutt_buffer_string(mbox), "../", 3))
314  {
315  goto cleanup;
316  }
317  size_t len = mutt_buffer_len(mbox);
318  if ((len > 3) && (strcmp(mutt_buffer_string(mbox) + len - 3, "/..") == 0))
319  goto cleanup;
320 
321  struct Url url = { 0 };
322  mutt_account_tourl(&adata->conn->account, &url);
323  url.path = mbox->data;
324  url_tobuffer(&url, cachepath, U_PATH);
325 
326  const char *const c_header_cache =
327  cs_subset_path(NeoMutt->sub, "header_cache");
328  hc = mutt_hcache_open(c_header_cache, mutt_buffer_string(cachepath), imap_hcache_namer);
329 
330 cleanup:
332  mutt_buffer_pool_release(&cachepath);
333  mdata->hcache = hc;
334 }
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
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:287
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:334
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:194
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:715
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:404
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
String manipulation buffer.
Definition: buffer.h:34
char * data
Pointer to data.
Definition: buffer.h:35
Header cache structure.
Definition: lib.h:87
struct HeaderCache * hcache
Email header cache.
Definition: mdata.h:62
char * name
Mailbox name.
Definition: mdata.h:40
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:69
char * path
Path.
Definition: url.h:75
int url_tobuffer(struct Url *url, struct Buffer *buf, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:353
#define U_PATH
Definition: url.h:50
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:719
+ 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 340 of file util.c.

341 {
342  if (!mdata->hcache)
343  return;
344 
345  mutt_hcache_close(mdata->hcache);
346  mdata->hcache = NULL;
347 }
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:437
+ 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 356 of file util.c.

357 {
358  if (!mdata->hcache)
359  return NULL;
360 
361  char key[16];
362 
363  sprintf(key, "/%u", uid);
364  struct HCacheEntry hce =
365  mutt_hcache_fetch(mdata->hcache, key, mutt_str_len(key), mdata->uidvalidity);
366  if (!hce.email && hce.uidvalidity)
367  {
368  mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
369  }
370 
371  return hce.email;
372 }
struct HCacheEntry mutt_hcache_fetch(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition: hcache.c:463
Wrapper for Email retrieved from the header cache.
Definition: lib.h:98
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition: lib.h:99
struct Email * email
Retrieved email.
Definition: lib.h:101
uint32_t uidvalidity
Definition: mdata.h:50
+ 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 381 of file util.c.

382 {
383  if (!mdata->hcache)
384  return -1;
385 
386  char key[16];
387 
388  sprintf(key, "/%u", imap_edata_get(e)->uid);
389  return mutt_hcache_store(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
390 }
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:558
+ 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 399 of file util.c.

400 {
401  if (!mdata->hcache)
402  return -1;
403 
404  char key[16];
405 
406  sprintf(key, "/%u", uid);
407  return mutt_hcache_delete_record(mdata->hcache, key, mutt_str_len(key));
408 }
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:639
+ 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 416 of file util.c.

417 {
418  if (!mdata->hcache)
419  return -1;
420 
421  /* The seqset is likely large. Preallocate to reduce reallocs */
422  struct Buffer buf = mutt_buffer_make(8192);
423  imap_msn_index_to_uid_seqset(&buf, mdata);
424 
425  int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
426  mutt_buffer_len(&buf) + 1);
427  mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
428  mutt_buffer_dealloc(&buf);
429  return rc;
430 }
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
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:617
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:231
+ 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 438 of file util.c.

439 {
440  if (!mdata->hcache)
441  return -1;
442 
443  return mutt_hcache_delete_record(mdata->hcache, "/UIDSEQSET", 10);
444 }
+ 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 452 of file util.c.

453 {
454  if (!mdata->hcache)
455  return NULL;
456 
457  char *seqset = NULL;
458  size_t dlen = 0;
459  char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10, &dlen);
460  if (hc_seqset)
461  {
462  seqset = mutt_strn_dup(hc_seqset, dlen);
463  mutt_hcache_free_raw(mdata->hcache, (void **) &hc_seqset);
464  }
465  mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
466 
467  return seqset;
468 }
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:543
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message's header from the cache.
Definition: hcache.c:523
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:359
#define NONULL(x)
Definition: string2.h:37
+ 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 483 of file util.c.

484 {
485  static unsigned short ImapPort = 0;
486  static unsigned short ImapsPort = 0;
487 
488  if (ImapPort == 0)
489  {
490  struct servent *service = getservbyname("imap", "tcp");
491  if (service)
492  ImapPort = ntohs(service->s_port);
493  else
494  ImapPort = IMAP_PORT;
495  mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
496  }
497 
498  if (ImapsPort == 0)
499  {
500  struct servent *service = getservbyname("imaps", "tcp");
501  if (service)
502  ImapsPort = ntohs(service->s_port);
503  else
504  ImapsPort = IMAP_SSL_PORT;
505  mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
506  }
507 
508  /* Defaults */
509  cac->port = ImapPort;
510  cac->type = MUTT_ACCT_TYPE_IMAP;
511  cac->service = "imap";
512  cac->get_field = imap_get_field;
513 
514  struct Url *url = url_parse(path);
515  if (!url)
516  return -1;
517 
518  if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
519  {
520  url_free(&url);
521  return -1;
522  }
523 
524  if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
525  {
526  url_free(&url);
527  return -1;
528  }
529 
530  if (url->scheme == U_IMAPS)
531  cac->flags |= MUTT_ACCT_SSL;
532 
533  mutt_str_copy(mailbox, url->path, mailboxlen);
534 
535  url_free(&url);
536 
537  if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
538  cac->port = ImapsPort;
539 
540  return 0;
541 }
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:47
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:43
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:45
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:46
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
Definition: mutt_account.h:37
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:61
char host[128]
Server to login to.
Definition: connaccount.h:54
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:68
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:59
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:60
unsigned short port
Port to connect to.
Definition: connaccount.h:58
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:70
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
@ U_IMAP
Url is imap://.
Definition: url.h:39
@ U_IMAPS
Url is imaps://.
Definition: url.h:40
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:204
+ 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 554 of file util.c.

555 {
556  char *b1 = NULL;
557  char *b2 = NULL;
558  int rc;
559 
560  if (!mx1 || (*mx1 == '\0'))
561  mx1 = "INBOX";
562  if (!mx2 || (*mx2 == '\0'))
563  mx2 = "INBOX";
564  if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
565  {
566  return 0;
567  }
568 
569  b1 = mutt_mem_malloc(strlen(mx1) + 1);
570  b2 = mutt_mem_malloc(strlen(mx2) + 1);
571 
572  imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
573  imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
574 
575  rc = mutt_str_cmp(b1, b2);
576  FREE(&b1);
577  FREE(&b2);
578 
579  return rc;
580 }
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:40
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:378
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:727
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:687
+ 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 590 of file util.c.

591 {
592  struct ConnAccount cac_target = { { 0 } };
593  struct ConnAccount cac_home = { { 0 } };
594  struct Url url = { 0 };
595  const char *delim = NULL;
596  int tlen;
597  int hlen = 0;
598  bool home_match = false;
599  char target_mailbox[1024];
600  char home_mailbox[1024];
601 
602  if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
603  return;
604 
605  if (imap_path_probe(folder, NULL) != MUTT_IMAP)
606  goto fallback;
607 
608  if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
609  goto fallback;
610 
611  tlen = mutt_str_len(target_mailbox);
612  hlen = mutt_str_len(home_mailbox);
613 
614  /* check whether we can do '+' substitution */
615  if (tlen && imap_account_match(&cac_home, &cac_target) &&
616  mutt_strn_equal(home_mailbox, target_mailbox, hlen))
617  {
618  const char *const c_imap_delim_chars =
619  cs_subset_string(NeoMutt->sub, "imap_delim_chars");
620  if (hlen == 0)
621  home_match = true;
622  else if (c_imap_delim_chars)
623  {
624  for (delim = c_imap_delim_chars; *delim != '\0'; delim++)
625  if (target_mailbox[hlen] == *delim)
626  home_match = true;
627  }
628  }
629 
630  /* do the '+' substitution */
631  if (home_match)
632  {
633  *path++ = '+';
634  /* copy remaining path, skipping delimiter */
635  if (hlen == 0)
636  hlen = -1;
637  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
638  path[tlen - hlen - 1] = '\0';
639  return;
640  }
641 
642 fallback:
643  mutt_account_tourl(&cac_target, &url);
644  url.path = target_mailbox;
645  url_tostring(&url, path, pathlen, U_NO_FLAGS);
646 }
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2402
int url_tostring(struct Url *url, char *dest, size_t len, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:418
#define U_NO_FLAGS
Definition: url.h:49
+ 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 590 of file util.c.

655 {
656  imap_error(msg, resp);
657  return mutt_yesorno(_("Continue?"), MUTT_NO);
658 }
#define _(a)
Definition: message.h:28
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:38
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: question.c:182
void imap_error(const char *where, const char *msg)
Show an error and abort.
Definition: util.c:665
+ 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 665 of file util.c.

666 {
667  mutt_error("%s [%s]", where, msg);
668 }
#define mutt_error(...)
Definition: logging.h:87
+ 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 $imap_delim_chars
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 $imap_delim_chars 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 687 of file util.c.

688 {
689  int i = 0;
690  for (; mailbox && *mailbox && (i < plen - 1); i++)
691  {
692  const char *const c_imap_delim_chars =
693  cs_subset_string(NeoMutt->sub, "imap_delim_chars");
694  if (*mailbox == delim || (!delim && strchr(NONULL(c_imap_delim_chars), *mailbox)))
695  {
696  delim = *mailbox;
697  /* Skip multiple occurrences of delim */
698  while (*mailbox && *(mailbox + 1) == delim)
699  mailbox++;
700  }
701  path[i] = *mailbox++;
702  }
703 
704  /* Do not terminate with a delimiter */
705  if (i && path[i - 1] == delim)
706  i--;
707 
708  /* Ensure null termination */
709  path[i] = '\0';
710  return path;
711 }
+ Here is the call graph for this function:
+ 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 719 of file util.c.

720 {
721  const char *p = mailbox;
722  mutt_buffer_reset(dest);
723  if (!p)
724  return;
725 
726  while (*p)
727  {
728  if (p[0] == delim)
729  {
730  mutt_buffer_addch(dest, '/');
731  /* simple way to avoid collisions with UIDs */
732  if ((p[1] >= '0') && (p[1] <= '9'))
733  mutt_buffer_addch(dest, '_');
734  }
735  else
736  mutt_buffer_addch(dest, *p);
737  p++;
738  }
739 }
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
+ 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 748 of file util.c.

749 {
750  char *pc = NULL;
751  char *pn = NULL;
752 
753  if (!buf || !(pc = strchr(buf, '{')))
754  return -1;
755 
756  pc++;
757  pn = pc;
758  while (isdigit((unsigned char) *pc))
759  pc++;
760  *pc = '\0';
761  if (!mutt_str_atoui(pn, bytes))
762  return -1;
763 
764  return 0;
765 }
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: atoi.c:202
+ 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 775 of file util.c.

776 {
777  char *s = buf;
778 
779  /* skip tag */
780  s = imap_next_word(s);
781  /* skip OK/NO/BAD response */
782  s = imap_next_word(s);
783 
784  return s;
785 }
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:792
+ 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 792 of file util.c.

793 {
794  bool quoted = false;
795 
796  while (*s)
797  {
798  if (*s == '\\')
799  {
800  s++;
801  if (*s)
802  s++;
803  continue;
804  }
805  if (*s == '\"')
806  quoted = !quoted;
807  if (!quoted && IS_SPACE(*s))
808  break;
809  s++;
810  }
811 
812  SKIPWS(s);
813  return s;
814 }
#define IS_SPACE(ch)
Definition: string2.h:38
#define SKIPWS(ch)
Definition: string2.h:46
+ 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 823 of file util.c.

824 {
825  struct Url url = { 0 };
826  mutt_account_tourl(cac, &url);
827  url.path = path;
828  url_tostring(&url, buf, buflen, U_NO_FLAGS);
829 }
+ 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 840 of file util.c.

841 {
842  const char *quote = "`\"\\";
843  if (!quote_backtick)
844  quote++;
845 
846  char *pt = dest;
847  const char *s = src;
848 
849  *pt++ = '"';
850  /* save room for quote-chars */
851  dlen -= 3;
852 
853  for (; *s && dlen; s++)
854  {
855  if (strchr(quote, *s))
856  {
857  if (dlen < 2)
858  break;
859  dlen -= 2;
860  *pt++ = '\\';
861  *pt++ = *s;
862  }
863  else
864  {
865  *pt++ = *s;
866  dlen--;
867  }
868  }
869  *pt++ = '"';
870  *pt = '\0';
871 }
+ 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 877 of file util.c.

878 {
879  char *d = s;
880 
881  if (*s == '\"')
882  s++;
883  else
884  return;
885 
886  while (*s)
887  {
888  if (*s == '\"')
889  {
890  *d = '\0';
891  return;
892  }
893  if (*s == '\\')
894  {
895  s++;
896  }
897  if (*s)
898  {
899  *d = *s;
900  d++;
901  s++;
902  }
903  }
904  *d = '\0';
905 }
+ 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 914 of file util.c.

915 {
916  char *buf = mutt_str_dup(src);
917  imap_utf_encode(unicode, &buf);
918 
919  imap_quote_string(dest, dlen, buf, false);
920 
921  FREE(&buf);
922 }
void imap_utf_encode(bool unicode, char **s)
Encode email from local charset to UTF-8.
Definition: utf7.c:318
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:181
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
Quote string according to IMAP rules.
Definition: util.c:840
+ 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 931 of file util.c.

932 {
934 
935  char *buf = mutt_str_dup(s);
936  if (buf)
937  {
938  imap_utf_decode(unicode, &buf);
939  strncpy(s, buf, strlen(s));
940  }
941 
942  FREE(&buf);
943 }
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:348
void imap_unquote_string(char *s)
Equally stupid unquoting routine.
Definition: util.c:877
+ 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 948 of file util.c.

949 {
950  time_t now = mutt_date_epoch();
951  struct Account *np = NULL;
952  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
953  {
954  if (np->type != MUTT_IMAP)
955  continue;
956 
957  struct ImapAccountData *adata = np->adata;
958  if (!adata || !adata->mailbox)
959  continue;
960 
961  const short c_imap_keepalive =
962  cs_subset_number(NeoMutt->sub, "imap_keepalive");
963  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + c_imap_keepalive)))
964  imap_check_mailbox(adata->mailbox, true);
965  }
966 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:427
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
@ IMAP_AUTHENTICATED
Connection is authenticated.
Definition: private.h:109
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
Use the NOOP or IDLE command to poll for new mail.
Definition: imap.c:1103
+ 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 973 of file util.c.

974 {
975  struct sigaction oldalrm;
976  struct sigaction act;
977  sigset_t oldmask;
978  int rc;
979 
980  const bool c_imap_passive = cs_subset_bool(NeoMutt->sub, "imap_passive");
981  cs_subset_str_native_set(NeoMutt->sub, "imap_passive", true, NULL);
982  OptKeepQuiet = true;
983 
984  sigprocmask(SIG_SETMASK, NULL, &oldmask);
985 
986  sigemptyset(&act.sa_mask);
987  act.sa_handler = mutt_sig_empty_handler;
988 #ifdef SA_INTERRUPT
989  act.sa_flags = SA_INTERRUPT;
990 #else
991  act.sa_flags = 0;
992 #endif
993 
994  sigaction(SIGALRM, &act, &oldalrm);
995 
996  const short c_imap_keepalive =
997  cs_subset_number(NeoMutt->sub, "imap_keepalive");
998  alarm(c_imap_keepalive);
999  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1000  {
1001  alarm(0); /* cancel a possibly pending alarm */
1002  imap_keepalive();
1003  alarm(c_imap_keepalive);
1004  }
1005 
1006  alarm(0); /* cancel a possibly pending alarm */
1007 
1008  sigaction(SIGALRM, &oldalrm, NULL);
1009  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1010 
1011  OptKeepQuiet = false;
1012  cs_subset_str_native_set(NeoMutt->sub, "imap_passive", c_imap_passive, NULL);
1013 
1014  return rc;
1015 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program
Definition: options.h:44
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:57
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:305
void imap_keepalive(void)
Poll the current folder to keep the connection alive.
Definition: util.c:948
+ 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 1021 of file util.c.

1022 {
1023  struct ImapAccountData *adata = imap_adata_get(m);
1024  struct ImapMboxData *mdata = imap_mdata_get(m);
1025  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1026  return;
1027  mdata->reopen |= IMAP_REOPEN_ALLOW;
1028 }
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:90
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:59
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:76
+ Here is the call 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 1034 of file util.c.

1035 {
1036  struct ImapAccountData *adata = imap_adata_get(m);
1037  struct ImapMboxData *mdata = imap_mdata_get(m);
1038  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1039  return;
1040  mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1041 }
+ Here is the call 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 1049 of file util.c.

1050 {
1051  if (!a1 || !a2)
1052  return false;
1053  if (a1->type != a2->type)
1054  return false;
1055  if (!mutt_istr_equal(a1->host, a2->host))
1056  return false;
1057  if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1058  return false;
1059  if (a1->flags & a2->flags & MUTT_ACCT_USER)
1060  return strcmp(a1->user, a2->user) == 0;
1061 
1062  const char *user = NONULL(Username);
1063 
1064  const char *const c_imap_user = cs_subset_string(NeoMutt->sub, "imap_user");
1065  if ((a1->type == MUTT_ACCT_TYPE_IMAP) && c_imap_user)
1066  user = c_imap_user;
1067 
1068  if (a1->flags & MUTT_ACCT_USER)
1069  return strcmp(a1->user, user) == 0;
1070  if (a2->flags & MUTT_ACCT_USER)
1071  return strcmp(a2->user, user) == 0;
1072 
1073  return true;
1074 }
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:44
char * Username
User's login name.
Definition: mutt_globals.h:54
char user[128]
Username.
Definition: connaccount.h:56
+ 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 1081 of file util.c.

1082 {
1083  if (!seqset || (*seqset == '\0'))
1084  return NULL;
1085 
1086  struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1087  iter->full_seqset = mutt_str_dup(seqset);
1088  iter->eostr = strchr(iter->full_seqset, '\0');
1089  iter->substr_cur = iter->substr_end = iter->full_seqset;
1090 
1091  return iter;
1092 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
UID Sequence Set Iterator.
Definition: private.h:170
char * eostr
Definition: private.h:172
char * substr_end
Definition: private.h:178
char * substr_cur
Definition: private.h:177
char * full_seqset
Definition: private.h:171
+ 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 1102 of file util.c.

1103 {
1104  if (!iter || !next)
1105  return -1;
1106 
1107  if (iter->in_range)
1108  {
1109  if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1110  (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1111  {
1112  iter->in_range = 0;
1113  }
1114  }
1115 
1116  if (!iter->in_range)
1117  {
1118  iter->substr_cur = iter->substr_end;
1119  if (iter->substr_cur == iter->eostr)
1120  return 1;
1121 
1122  iter->substr_end = strchr(iter->substr_cur, ',');
1123  if (!iter->substr_end)
1124  iter->substr_end = iter->eostr;
1125  else
1126  *(iter->substr_end++) = '\0';
1127 
1128  char *range_sep = strchr(iter->substr_cur, ':');
1129  if (range_sep)
1130  *range_sep++ = '\0';
1131 
1132  if (!mutt_str_atoui_full(iter->substr_cur, &iter->range_cur))
1133  return -1;
1134  if (range_sep)
1135  {
1136  if (!mutt_str_atoui_full(range_sep, &iter->range_end))
1137  return -1;
1138  }
1139  else
1140  iter->range_end = iter->range_cur;
1141 
1142  iter->down = (iter->range_end < iter->range_cur);
1143  iter->in_range = 1;
1144  }
1145 
1146  *next = iter->range_cur;
1147  if (iter->down)
1148  iter->range_cur--;
1149  else
1150  iter->range_cur++;
1151 
1152  return 0;
1153 }
unsigned int range_end
Definition: private.h:176
unsigned int range_cur
Definition: private.h:175
+ 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 1159 of file util.c.

1160 {
1161  if (!ptr || !*ptr)
1162  return;
1163 
1164  struct SeqsetIterator *iter = *ptr;
1165  FREE(&iter->full_seqset);
1166  FREE(ptr);
1167 }
+ Here is the caller graph for this function: