NeoMutt  2025-09-05-7-geaa2bd
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
util.c File Reference

IMAP helper functions. More...

#include "config.h"
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.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 "globals.h"
#include "mdata.h"
#include "msn.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.
 
void imap_mdata_cache_reset (struct ImapMboxData *mdata)
 Release and clear cache data of ImapMboxData structure.
 
void imap_get_parent (const char *mbox, char delim, char *buf, size_t buflen)
 Get an IMAP folder's parent.
 
void imap_get_parent_path (const char *path, char *buf, size_t buflen)
 Get the path of the parent folder.
 
void imap_clean_path (char *path, size_t plen)
 Cleans an IMAP path using imap_fix_path.
 
static const char * imap_get_field (enum ConnAccountField field, void *gf_data)
 Get connection login credentials - Implements ConnAccount::get_field() -.
 
static void imap_msn_index_to_uid_seqset (struct Buffer *buf, struct ImapMboxData *mdata)
 Convert MSN index of UIDs to Seqset.
 
static void imap_hcache_namer (const char *path, struct Buffer *dest)
 Generate a filename for the header cache - Implements hcache_namer_t -.
 
void imap_hcache_open (struct ImapAccountData *adata, struct ImapMboxData *mdata, bool create)
 Open a header cache.
 
void imap_hcache_close (struct ImapMboxData *mdata)
 Close the header cache.
 
struct Emailimap_hcache_get (struct ImapMboxData *mdata, unsigned int uid)
 Get a header cache entry by its UID.
 
int imap_hcache_put (struct ImapMboxData *mdata, struct Email *e)
 Add an entry to the header cache.
 
int imap_hcache_del (struct ImapMboxData *mdata, unsigned int uid)
 Delete an item from the header cache.
 
int imap_hcache_store_uid_seqset (struct ImapMboxData *mdata)
 Store a UID Sequence Set in the header cache.
 
int imap_hcache_clear_uid_seqset (struct ImapMboxData *mdata)
 Delete a UID Sequence Set from the header cache.
 
char * imap_hcache_get_uid_seqset (struct ImapMboxData *mdata)
 Get a UID Sequence Set from the header cache.
 
int imap_parse_path (const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
 Parse an IMAP mailbox name into ConnAccount, name.
 
int imap_mxcmp (const char *mx1, const char *mx2)
 Compare mailbox names, giving priority to INBOX.
 
void imap_pretty_mailbox (char *path, size_t pathlen, const char *folder)
 Prettify an IMAP mailbox name.
 
enum QuadOption imap_continue (const char *msg, const char *resp)
 Display a message and ask the user if they want to go on.
 
void imap_error (const char *where, const char *msg)
 Show an error and abort.
 
char * imap_fix_path (const char *mailbox, char *path, size_t plen)
 Fix up the imap path.
 
char * imap_fix_path_with_delim (const char delim, const char *mailbox, char *path, size_t plen)
 Fix up the imap path.
 
void imap_cachepath (char delim, const char *mailbox, struct Buffer *dest)
 Generate a cache path for a mailbox.
 
int imap_get_literal_count (const char *buf, unsigned int *bytes)
 Write number of bytes in an IMAP literal into bytes.
 
char * imap_get_qualifier (char *buf)
 Get the qualifier from a tagged response.
 
char * imap_next_word (char *s)
 Find where the next IMAP word begins.
 
void imap_qualify_path (char *buf, size_t buflen, struct ConnAccount *cac, char *path)
 Make an absolute IMAP folder target.
 
void imap_buf_qualify_path (struct Buffer *buf, struct ConnAccount *cac, char *path)
 Make an absolute IMAP folder target to a buffer.
 
void imap_quote_string (char *dest, size_t dlen, const char *src, bool quote_backtick)
 Quote string according to IMAP rules.
 
void imap_unquote_string (char *s)
 Equally stupid unquoting routine.
 
void imap_munge_mbox_name (bool unicode, char *dest, size_t dlen, const char *src)
 Quote awkward characters in a mailbox name.
 
void imap_unmunge_mbox_name (bool unicode, char *s)
 Remove quoting from a mailbox name.
 
void imap_keep_alive (void)
 Poll the current folder to keep the connection alive.
 
int imap_wait_keep_alive (pid_t pid)
 Wait for a process to change state.
 
void imap_allow_reopen (struct Mailbox *m)
 Allow re-opening a folder upon expunge.
 
void imap_disallow_reopen (struct Mailbox *m)
 Disallow re-opening a folder upon expunge.
 
bool imap_account_match (const struct ConnAccount *a1, const struct ConnAccount *a2)
 Compare two Accounts.
 
struct SeqsetIteratormutt_seqset_iterator_new (const char *seqset)
 Create a new Sequence Set Iterator.
 
int mutt_seqset_iterator_next (struct SeqsetIterator *iter, unsigned int *next)
 Get the next UID from a Sequence Set.
 
void mutt_seqset_iterator_free (struct SeqsetIterator **ptr)
 Free a Sequence Set Iterator.
 

Detailed Description

IMAP helper functions.

Authors
  • Michael R. Elkins
  • Brandon Long
  • Brendan Cully
  • Richard Russon
  • Mehdi Abaakouk
  • Pietro Cerutti

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 71 of file util.c.

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

109{
110 mutt_hash_free(&mdata->uid_hash);
111 imap_msn_free(&mdata->msn);
112 mutt_bcache_close(&mdata->bcache);
113}
void mutt_bcache_close(struct BodyCache **ptr)
Close an Email-Body Cache.
Definition: bcache.c:167
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
void imap_msn_free(struct MSNArray *msn)
Free the cache.
Definition: msn.c:62
struct BodyCache * bcache
Email body cache.
Definition: mdata.h:61
struct HashTable * uid_hash
Hash Table: "uid" -> Email.
Definition: mdata.h:59
+ 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 122 of file util.c.

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

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

191{
192 struct ImapAccountData *adata = NULL;
193 struct ImapMboxData *mdata = NULL;
194
195 if (imap_adata_find(path, &adata, &mdata) < 0)
196 return;
197
198 /* Returns a fully qualified IMAP url */
199 imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
200 imap_mdata_free((void *) &mdata);
201}
+ 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 233 of file util.c.

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

Open a header cache.

Parameters
adataImap Account data
mdataImap Mailbox data
createCreate a new header cache if missing?

Definition at line 301 of file util.c.

302{
303 if (!adata || !mdata)
304 return;
305
306 if (mdata->hcache)
307 return;
308
309 struct HeaderCache *hc = NULL;
310 struct Buffer *mbox = buf_pool_get();
311 struct Buffer *cachepath = buf_pool_get();
312
313 imap_cachepath(adata->delim, mdata->name, mbox);
314
315 if (strstr(buf_string(mbox), "/../") || mutt_str_equal(buf_string(mbox), "..") ||
316 mutt_strn_equal(buf_string(mbox), "../", 3))
317 {
318 goto cleanup;
319 }
320 size_t len = buf_len(mbox);
321 if ((len > 3) && (mutt_str_equal(buf_string(mbox) + len - 3, "/..")))
322 goto cleanup;
323
324 struct Url url = { 0 };
325 account_to_url(&adata->conn->account, &url);
326 url.path = mbox->data;
327 url_tobuffer(&url, cachepath, U_PATH);
328
329 const char *const c_header_cache = cs_subset_path(NeoMutt->sub, "header_cache");
330 hc = hcache_open(c_header_cache, buf_string(cachepath), imap_hcache_namer, create);
331
332cleanup:
333 buf_pool_release(&mbox);
334 buf_pool_release(&cachepath);
335 mdata->hcache = hc;
336}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:491
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:168
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:290
struct HeaderCache * hcache_open(const char *path, const char *folder, hcache_namer_t namer, bool create)
Multiplexor for StoreOps::open.
Definition: hcache.c:471
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:659
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:426
void account_to_url(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:80
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
Header Cache.
Definition: lib.h:86
struct HeaderCache * hcache
Email header cache.
Definition: mdata.h:63
char * name
Mailbox name.
Definition: mdata.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:47
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(const struct Url *url, struct Buffer *buf, uint8_t flags)
Output the URL string for a given Url object.
Definition: url.c:357
#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:748
+ 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 342 of file util.c.

343{
344 if (!mdata->hcache)
345 return;
346
347 hcache_close(&mdata->hcache);
348}
void hcache_close(struct HeaderCache **ptr)
Multiplexor for StoreOps::close.
Definition: hcache.c:542
+ 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 357 of file util.c.

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

383{
384 if (!mdata->hcache)
385 return -1;
386
387 char key[16] = { 0 };
388
389 snprintf(key, sizeof(key), "%u", imap_edata_get(e)->uid);
390 return hcache_store_email(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
391}
int hcache_store_email(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:670
+ 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 400 of file util.c.

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

418{
419 if (!mdata->hcache)
420 return -1;
421
422 struct Buffer *buf = buf_pool_get();
423 buf_alloc(buf, 8192); // The seqset is likely large. Preallocate to reduce reallocs
425
426 int rc = hcache_store_raw(mdata->hcache, "UIDSEQSET", 9, buf->data, buf_len(buf) + 1);
427 mutt_debug(LL_DEBUG3, "Stored UIDSEQSET %s\n", buf_string(buf));
428 buf_pool_release(&buf);
429 return rc;
430}
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:337
int 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:724
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:233
+ 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 hcache_delete_raw(mdata->hcache, "UIDSEQSET", 9);
444}
int hcache_delete_raw(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:752
+ 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 = hcache_fetch_raw_str(mdata->hcache, "UIDSEQSET", 9);
458 mutt_debug(LL_DEBUG3, "Retrieved UIDSEQSET %s\n", NONULL(seqset));
459
460 return seqset;
461}
char * hcache_fetch_raw_str(struct HeaderCache *hc, const char *key, size_t keylen)
Fetch a string from the cache.
Definition: hcache.c:652
#define NONULL(x)
Definition: string2.h:36
+ 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 476 of file util.c.

477{
478 static unsigned short ImapPort = 0;
479 static unsigned short ImapsPort = 0;
480
481 if (ImapPort == 0)
482 {
483 struct servent *service = getservbyname("imap", "tcp");
484 if (service)
485 ImapPort = ntohs(service->s_port);
486 else
487 ImapPort = IMAP_PORT;
488 mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
489 }
490
491 if (ImapsPort == 0)
492 {
493 struct servent *service = getservbyname("imaps", "tcp");
494 if (service)
495 ImapsPort = ntohs(service->s_port);
496 else
497 ImapsPort = IMAP_SSL_PORT;
498 mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
499 }
500
501 /* Defaults */
502 cac->port = ImapPort;
504 cac->service = "imap";
506
507 struct Url *url = url_parse(path);
508 if (!url)
509 return -1;
510
511 if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
512 {
513 url_free(&url);
514 return -1;
515 }
516
517 if ((account_from_url(cac, url) < 0) || (cac->host[0] == '\0'))
518 {
519 url_free(&url);
520 return -1;
521 }
522
523 if (url->scheme == U_IMAPS)
524 cac->flags |= MUTT_ACCT_SSL;
525
526 mutt_str_copy(mailbox, url->path, mailboxlen);
527
528 url_free(&url);
529
530 if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
531 cac->port = ImapsPort;
532
533 return 0;
534}
#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
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field() -.
Definition: util.c:206
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:44
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:45
int account_from_url(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:44
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
Definition: mutt_account.h:36
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)
Definition: connaccount.h:70
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:238
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
+ 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 547 of file util.c.

548{
549 char *b1 = NULL;
550 char *b2 = NULL;
551 int rc;
552
553 if (!mx1 || (*mx1 == '\0'))
554 mx1 = "INBOX";
555 if (!mx2 || (*mx2 == '\0'))
556 mx2 = "INBOX";
557 if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
558 {
559 return 0;
560 }
561
562 b1 = MUTT_MEM_MALLOC(strlen(mx1) + 1, char);
563 b2 = MUTT_MEM_MALLOC(strlen(mx2) + 1, char);
564
565 imap_fix_path(mx1, b1, strlen(mx1) + 1);
566 imap_fix_path(mx2, b2, strlen(mx2) + 1);
567
568 rc = mutt_str_cmp(b1, b2);
569 FREE(&b1);
570 FREE(&b2);
571
572 return rc;
573}
#define FREE(x)
Definition: memory.h:62
#define MUTT_MEM_MALLOC(n, type)
Definition: memory.h:48
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:400
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:671
char * imap_fix_path(const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:680
+ 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 583 of file util.c.

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

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

660{
661 mutt_error("%s [%s]", where, msg);
662}
#define mutt_error(...)
Definition: logging2.h:93
+ Here is the caller graph for this function:

◆ imap_fix_path()

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

Fix up the imap path.

Parameters
mailboxMailbox path
pathBuffer for the result
plenLength of buffer
Return values
ptrFixed-up path
Note
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 680 of file util.c.

681{
682 const char *const c_imap_delim_chars = cs_subset_string(NeoMutt->sub, "imap_delim_chars");
683
684 char *out = path;
685 size_t space_left = plen - 1;
686
687 if (mailbox)
688 {
689 for (const char *c = mailbox; *c && space_left; c++, space_left--)
690 {
691 if (strchr(NONULL(c_imap_delim_chars), *c))
692 {
693 return imap_fix_path_with_delim(*c, mailbox, path, plen);
694 }
695 *out++ = *c;
696 }
697 }
698
699 *out = '\0';
700 return path;
701}
char * imap_fix_path_with_delim(const char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:712
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_fix_path_with_delim()

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

Fix up the imap path.

Parameters
delimDelimiter specified by the server
mailboxMailbox path
pathBuffer for the result
plenLength of buffer
Return values
ptrFixed-up path

Definition at line 712 of file util.c.

713{
714 char *out = path;
715 size_t space_left = plen - 1;
716
717 if (mailbox)
718 {
719 for (const char *c = mailbox; *c && space_left; c++, space_left--)
720 {
721 if (*c == delim || *c == '/')
722 {
723 while (*c && *(c + 1) == *c)
724 c++;
725 *out++ = delim;
726 }
727 else
728 {
729 *out++ = *c;
730 }
731 }
732 }
733
734 if (out != path && *(out - 1) == delim)
735 {
736 out--;
737 }
738 *out = '\0';
739 return path;
740}
+ 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 748 of file util.c.

749{
750 const char *p = mailbox;
751 buf_reset(dest);
752 if (!p)
753 return;
754
755 while (*p)
756 {
757 if (p[0] == delim)
758 {
759 buf_addch(dest, '/');
760 /* simple way to avoid collisions with UIDs */
761 if ((p[1] >= '0') && (p[1] <= '9'))
762 buf_addch(dest, '_');
763 }
764 else
765 {
766 buf_addch(dest, *p);
767 }
768 p++;
769 }
770}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
+ 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 779 of file util.c.

780{
781 char *pc = NULL;
782 char *pn = NULL;
783
784 if (!buf || !(pc = strchr(buf, '{')))
785 return -1;
786
787 pc++;
788 pn = pc;
789 while (mutt_isdigit(*pc))
790 pc++;
791 *pc = '\0';
792 if (!mutt_str_atoui(pn, bytes))
793 return -1;
794
795 return 0;
796}
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: atoi.c:218
bool mutt_isdigit(int arg)
Wrapper for isdigit(3)
Definition: ctype.c:65
+ 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 806 of file util.c.

807{
808 char *s = buf;
809
810 /* skip tag */
811 s = imap_next_word(s);
812 /* skip OK/NO/BAD response */
813 s = imap_next_word(s);
814
815 return s;
816}
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:823
+ 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 823 of file util.c.

824{
825 bool quoted = false;
826
827 while (*s)
828 {
829 if (*s == '\\')
830 {
831 s++;
832 if (*s)
833 s++;
834 continue;
835 }
836 if (*s == '\"')
837 quoted = !quoted;
838 if (!quoted && mutt_isspace(*s))
839 break;
840 s++;
841 }
842
843 SKIPWS(s);
844 return s;
845}
bool mutt_isspace(int arg)
Wrapper for isspace(3)
Definition: ctype.c:95
#define SKIPWS(ch)
Definition: string2.h:44
+ Here is the call graph for this function:
+ 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 854 of file util.c.

855{
856 struct Url url = { 0 };
857 account_to_url(cac, &url);
858 url.path = path;
859 url_tostring(&url, buf, buflen, U_NO_FLAGS);
860}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_buf_qualify_path()

void imap_buf_qualify_path ( struct Buffer buf,
struct ConnAccount cac,
char *  path 
)

Make an absolute IMAP folder target to a buffer.

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

Definition at line 868 of file util.c.

869{
870 struct Url url = { 0 };
871 account_to_url(cac, &url);
872 url.path = path;
873 url_tobuffer(&url, buf, U_NO_FLAGS);
874}
+ 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 885 of file util.c.

886{
887 const char *quote = "`\"\\";
888 if (!quote_backtick)
889 quote++;
890
891 char *pt = dest;
892 const char *s = src;
893
894 *pt++ = '"';
895 /* save room for quote-chars */
896 dlen -= 3;
897
898 for (; *s && dlen; s++)
899 {
900 if (strchr(quote, *s))
901 {
902 if (dlen < 2)
903 break;
904 dlen -= 2;
905 *pt++ = '\\';
906 *pt++ = *s;
907 }
908 else
909 {
910 *pt++ = *s;
911 dlen--;
912 }
913 }
914 *pt++ = '"';
915 *pt = '\0';
916}
+ 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 922 of file util.c.

923{
924 char *d = s;
925
926 if (*s == '\"')
927 s++;
928 else
929 return;
930
931 while (*s)
932 {
933 if (*s == '\"')
934 {
935 *d = '\0';
936 return;
937 }
938 if (*s == '\\')
939 {
940 s++;
941 }
942 if (*s)
943 {
944 *d = *s;
945 d++;
946 s++;
947 }
948 }
949 *d = '\0';
950}
+ 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 959 of file util.c.

960{
961 char *buf = mutt_str_dup(src);
962 imap_utf_encode(unicode, &buf);
963
964 imap_quote_string(dest, dlen, buf, false);
965
966 FREE(&buf);
967}
void imap_utf_encode(bool unicode, char **s)
Encode email from local charset to UTF-8.
Definition: utf7.c:397
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:254
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
Quote string according to IMAP rules.
Definition: util.c:885
+ 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 976 of file util.c.

977{
979
980 char *buf = mutt_str_dup(s);
981 if (buf)
982 {
983 imap_utf_decode(unicode, &buf);
984 strncpy(s, buf, strlen(s));
985 }
986
987 FREE(&buf);
988}
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:430
void imap_unquote_string(char *s)
Equally stupid unquoting routine.
Definition: util.c:922
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_keep_alive()

void imap_keep_alive ( void  )

Poll the current folder to keep the connection alive.

Definition at line 993 of file util.c.

994{
995 time_t now = mutt_date_now();
996 struct Account *np = NULL;
997 const short c_imap_keep_alive = cs_subset_number(NeoMutt->sub, "imap_keep_alive");
998 TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
999 {
1000 if (np->type != MUTT_IMAP)
1001 continue;
1002
1003 struct ImapAccountData *adata = np->adata;
1004 if (!adata || !adata->mailbox)
1005 continue;
1006
1007 if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + c_imap_keep_alive)))
1008 imap_check_mailbox(adata->mailbox, true);
1009 }
1010}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:143
@ IMAP_AUTHENTICATED
Connection is authenticated.
Definition: private.h:107
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
Use the NOOP or IDLE command to poll for new mail.
Definition: imap.c:1034
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:456
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_wait_keep_alive()

int imap_wait_keep_alive ( 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 1017 of file util.c.

1018{
1019 struct sigaction oldalrm = { 0 };
1020 struct sigaction act = { 0 };
1021 sigset_t oldmask = { 0 };
1022 int rc;
1023
1024 const bool c_imap_passive = cs_subset_bool(NeoMutt->sub, "imap_passive");
1025 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", true, NULL);
1026 OptKeepQuiet = true;
1027
1028 sigprocmask(SIG_SETMASK, NULL, &oldmask);
1029
1030 sigemptyset(&act.sa_mask);
1031 act.sa_handler = mutt_sig_empty_handler;
1032#ifdef SA_INTERRUPT
1033 act.sa_flags = SA_INTERRUPT;
1034#else
1035 act.sa_flags = 0;
1036#endif
1037
1038 sigaction(SIGALRM, &act, &oldalrm);
1039
1040 const short c_imap_keep_alive = cs_subset_number(NeoMutt->sub, "imap_keep_alive");
1041 alarm(c_imap_keep_alive);
1042 while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1043 {
1044 alarm(0); /* cancel a possibly pending alarm */
1046 alarm(c_imap_keep_alive);
1047 }
1048
1049 alarm(0); /* cancel a possibly pending alarm */
1050
1051 sigaction(SIGALRM, &oldalrm, NULL);
1052 sigprocmask(SIG_SETMASK, &oldmask, NULL);
1053
1054 OptKeepQuiet = false;
1055 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", c_imap_passive, NULL);
1056
1057 return rc;
1058}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program
Definition: globals.c:59
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:131
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:299
void imap_keep_alive(void)
Poll the current folder to keep the connection alive.
Definition: util.c:993
+ 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 1064 of file util.c.

1065{
1067 struct ImapMboxData *mdata = imap_mdata_get(m);
1068 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1069 return;
1070 mdata->reopen |= IMAP_REOPEN_ALLOW;
1071}
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:123
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:61
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:64
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:76
+ 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 1077 of file util.c.

1078{
1080 struct ImapMboxData *mdata = imap_mdata_get(m);
1081 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1082 return;
1083 mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1084}
+ 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 1092 of file util.c.

1093{
1094 if (!a1 || !a2)
1095 return false;
1096 if (a1->type != a2->type)
1097 return false;
1098 if (!mutt_istr_equal(a1->host, a2->host))
1099 return false;
1100 if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1101 return false;
1102 if (a1->flags & a2->flags & MUTT_ACCT_USER)
1103 return mutt_str_equal(a1->user, a2->user);
1104
1105 const char *user = NONULL(NeoMutt->username);
1106
1107 const char *const c_imap_user = cs_subset_string(NeoMutt->sub, "imap_user");
1108 if ((a1->type == MUTT_ACCT_TYPE_IMAP) && c_imap_user)
1109 user = c_imap_user;
1110
1111 if (a1->flags & MUTT_ACCT_USER)
1112 return mutt_str_equal(a1->user, user);
1113 if (a2->flags & MUTT_ACCT_USER)
1114 return mutt_str_equal(a2->user, user);
1115
1116 return true;
1117}
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:44
char user[128]
Username.
Definition: connaccount.h:56
char * username
User's login name.
Definition: neomutt.h:54
+ 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 1124 of file util.c.

1125{
1126 if (!seqset || (*seqset == '\0'))
1127 return NULL;
1128
1129 struct SeqsetIterator *iter = MUTT_MEM_CALLOC(1, struct SeqsetIterator);
1130 iter->full_seqset = mutt_str_dup(seqset);
1131 iter->eostr = strchr(iter->full_seqset, '\0');
1132 iter->substr_cur = iter->substr_end = iter->full_seqset;
1133
1134 return iter;
1135}
#define MUTT_MEM_CALLOC(n, type)
Definition: memory.h:47
UID Sequence Set Iterator.
Definition: private.h:169
char * eostr
Definition: private.h:171
char * substr_end
Definition: private.h:177
char * substr_cur
Definition: private.h:176
char * full_seqset
Definition: private.h:170
+ 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 1145 of file util.c.

1146{
1147 if (!iter || !next)
1148 return -1;
1149
1150 if (iter->in_range)
1151 {
1152 if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1153 (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1154 {
1155 iter->in_range = 0;
1156 }
1157 }
1158
1159 if (!iter->in_range)
1160 {
1161 iter->substr_cur = iter->substr_end;
1162 if (iter->substr_cur == iter->eostr)
1163 return 1;
1164
1165 iter->substr_end = strchr(iter->substr_cur, ',');
1166 if (!iter->substr_end)
1167 iter->substr_end = iter->eostr;
1168 else
1169 *(iter->substr_end++) = '\0';
1170
1171 char *range_sep = strchr(iter->substr_cur, ':');
1172 if (range_sep)
1173 *range_sep++ = '\0';
1174
1175 if (!mutt_str_atoui_full(iter->substr_cur, &iter->range_cur))
1176 return -1;
1177 if (range_sep)
1178 {
1179 if (!mutt_str_atoui_full(range_sep, &iter->range_end))
1180 return -1;
1181 }
1182 else
1183 {
1184 iter->range_end = iter->range_cur;
1185 }
1186
1187 iter->down = (iter->range_end < iter->range_cur);
1188 iter->in_range = 1;
1189 }
1190
1191 *next = iter->range_cur;
1192 if (iter->down)
1193 iter->range_cur--;
1194 else
1195 iter->range_cur++;
1196
1197 return 0;
1198}
unsigned int range_end
Definition: private.h:175
unsigned int range_cur
Definition: private.h:174
+ 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 1204 of file util.c.

1205{
1206 if (!ptr || !*ptr)
1207 return;
1208
1209 struct SeqsetIterator *iter = *ptr;
1210 FREE(&iter->full_seqset);
1211 FREE(ptr);
1212}
+ Here is the caller graph for this function: