NeoMutt  2025-12-11-1039-g550ac6
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 "store/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 struct StoreOps *store_ops, 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 (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
  • Thomas Klausner

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

75{
76 struct ConnAccount cac = { { 0 } };
77 struct ImapAccountData *tmp_adata = NULL;
78 char tmp[1024] = { 0 };
79
80 if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
81 return -1;
82
83 struct Account **ap = NULL;
85 {
86 struct Account *a = *ap;
87 if (a->type != MUTT_IMAP)
88 continue;
89
90 tmp_adata = a->adata;
91 if (!tmp_adata)
92 continue;
93 if (imap_account_match(&tmp_adata->conn->account, &cac))
94 {
95 if (mdata)
96 {
97 *mdata = imap_mdata_new(tmp_adata, tmp);
98 }
99 *adata = tmp_adata;
100 return 0;
101 }
102 }
103 mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
104 return -1;
105}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
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:47
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:59
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:41
struct AccountArray accounts
All Accounts.
Definition neomutt.h:50
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:485
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition util.c:1108
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 111 of file util.c.

112{
114 mdata->reopen = IMAP_OPEN_NONE;
115 mutt_hash_free(&mdata->uid_hash);
116 imap_msn_free(&mdata->msn);
117 mutt_bcache_close(&mdata->bcache);
118}
void mutt_bcache_close(struct BodyCache **ptr)
Close an Email-Body Cache.
Definition bcache.c:183
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition hash.c:460
@ IMAP_OPEN_NONE
No flags are set.
Definition private.h:67
void imap_msn_free(struct MSNArray *msn)
Free the cache.
Definition msn.c:62
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition mdata.h:45
struct BodyCache * bcache
Email body cache.
Definition mdata.h:61
struct HashTable * uid_hash
Hash Table: "uid" -> Email.
Definition mdata.h:59
ImapOpenFlags check_status
Flags, e.g. IMAP_NEWMAIL_PENDING.
Definition mdata.h:46
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 127 of file util.c.

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

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

196{
197 struct ImapAccountData *adata = NULL;
198 struct ImapMboxData *mdata = NULL;
199
200 if (imap_adata_find(path, &adata, &mdata) < 0)
201 return;
202
203 /* Returns a fully qualified IMAP url */
204 imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
205 imap_mdata_free((void *) &mdata);
206}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ imap_msn_index_to_uid_seqset()

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

239{
240 int first = 1;
241 int state = 0;
242 unsigned int cur_uid = 0;
243 unsigned int last_uid = 0;
244 unsigned int range_begin = 0;
245 unsigned int range_end = 0;
246 const size_t max_msn = imap_msn_highest(&mdata->msn);
247
248 for (unsigned int msn = 1; msn <= max_msn + 1; msn++)
249 {
250 bool match = false;
251 if (msn <= max_msn)
252 {
253 struct Email *e_cur = imap_msn_get(&mdata->msn, msn - 1);
254 cur_uid = e_cur ? imap_edata_get(e_cur)->uid : 0;
255 if (!state || (cur_uid && ((cur_uid - 1) == last_uid)))
256 match = true;
257 last_uid = cur_uid;
258 }
259
260 if (match)
261 {
262 switch (state)
263 {
264 case 1: /* single: convert to a range */
265 state = 2;
267
268 case 2: /* extend range ending */
269 range_end = cur_uid;
270 break;
271 default:
272 state = 1;
273 range_begin = cur_uid;
274 break;
275 }
276 }
277 else if (state)
278 {
279 if (first)
280 first = 0;
281 else
282 buf_addch(buf, ',');
283
284 if (state == 1)
285 buf_add_printf(buf, "%u", range_begin);
286 else if (state == 2)
287 buf_add_printf(buf, "%u:%u", range_begin, range_end);
288
289 state = 1;
290 range_begin = cur_uid;
291 }
292 }
293}
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:211
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:248
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition edata.c:66
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:117
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 310 of file util.c.

311{
312 if (!adata || !mdata)
313 return;
314
315 if (mdata->hcache)
316 return;
317
318 struct HeaderCache *hc = NULL;
319 struct Buffer *mbox = buf_pool_get();
320 struct Buffer *cachepath = buf_pool_get();
321
322 imap_cachepath(adata->delim, mdata->name, mbox);
323
324 if (strstr(buf_string(mbox), "/../") || mutt_str_equal(buf_string(mbox), "..") ||
325 mutt_strn_equal(buf_string(mbox), "../", 3))
326 {
327 goto cleanup;
328 }
329 size_t len = buf_len(mbox);
330 if ((len > 3) && (mutt_str_equal(buf_string(mbox) + len - 3, "/..")))
331 goto cleanup;
332
333 struct Url url = { 0 };
334 account_to_url(&adata->conn->account, &url);
335 url.path = mbox->data;
336 url_tobuffer(&url, cachepath, U_PATH);
337
338 const char *const c_header_cache = cs_subset_path(NeoMutt->sub, "header_cache");
339 hc = hcache_open(c_header_cache, buf_string(cachepath), imap_hcache_namer, create);
340
341cleanup:
342 buf_pool_release(&mbox);
343 buf_pool_release(&cachepath);
344 mdata->hcache = hc;
345}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:497
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 struct StoreOps *store_ops, const char *path, struct Buffer *dest)
Generate a filename for the header cache - Implements hcache_namer_t -.
Definition util.c:298
struct HeaderCache * hcache_open(const char *path, const char *folder, hcache_namer_t namer, bool create)
Multiplexor for StoreOps::open.
Definition hcache.c:492
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
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:429
void account_to_url(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
char * data
Pointer to data.
Definition buffer.h:37
Header Cache.
Definition lib.h:87
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:49
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:361
#define U_PATH
Path is included in URL.
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:756
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 351 of file util.c.

352{
353 if (!mdata->hcache)
354 return;
355
356 hcache_close(&mdata->hcache);
357}
void hcache_close(struct HeaderCache **ptr)
Multiplexor for StoreOps::close.
Definition hcache.c:564
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 366 of file util.c.

367{
368 if (!mdata->hcache)
369 return NULL;
370
371 char key[16] = { 0 };
372
373 snprintf(key, sizeof(key), "%u", uid);
374 struct HCacheEntry hce = hcache_fetch_email(mdata->hcache, key, mutt_str_len(key),
375 mdata->uidvalidity);
376 if (!hce.email && hce.uidvalidity)
377 {
378 mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
379 }
380
381 return hce.email;
382}
struct HCacheEntry hcache_fetch_email(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition hcache.c:584
Wrapper for Email retrieved from the header cache.
Definition lib.h:100
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition lib.h:101
struct Email * email
Retrieved email.
Definition lib.h:103
uint32_t uidvalidity
UID validity.
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 391 of file util.c.

392{
393 if (!mdata->hcache)
394 return -1;
395
396 char key[16] = { 0 };
397
398 snprintf(key, sizeof(key), "%u", imap_edata_get(e)->uid);
399 return hcache_store_email(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
400}
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:703
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 409 of file util.c.

410{
411 if (!mdata->hcache)
412 return -1;
413
414 char key[16] = { 0 };
415
416 snprintf(key, sizeof(key), "%u", uid);
417 return hcache_delete_email(mdata->hcache, key, mutt_str_len(key));
418}
int hcache_delete_email(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition hcache.c:772
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 426 of file util.c.

427{
428 if (!mdata->hcache)
429 return -1;
430
431 struct Buffer *buf = buf_pool_get();
432 buf_alloc(buf, 8192); // The seqset is likely large. Preallocate to reduce reallocs
434
435 int rc = hcache_store_raw(mdata->hcache, "UIDSEQSET", 9, buf->data, buf_len(buf) + 1);
436 mutt_debug(LL_DEBUG3, "Stored UIDSEQSET %s\n", buf_string(buf));
437 buf_pool_release(&buf);
438 return rc;
439}
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition buffer.c:342
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:757
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition util.c:238
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 447 of file util.c.

448{
449 if (!mdata->hcache)
450 return -1;
451
452 return hcache_delete_raw(mdata->hcache, "UIDSEQSET", 9);
453}
int hcache_delete_raw(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition hcache.c:785
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 461 of file util.c.

462{
463 if (!mdata->hcache)
464 return NULL;
465
466 char *seqset = hcache_fetch_raw_str(mdata->hcache, "UIDSEQSET", 9);
467 mutt_debug(LL_DEBUG3, "Retrieved UIDSEQSET %s\n", NONULL(seqset));
468
469 return seqset;
470}
char * hcache_fetch_raw_str(struct HeaderCache *hc, const char *key, size_t keylen)
Fetch a string from the cache.
Definition hcache.c:682
#define NONULL(x)
Definition string2.h:44
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 485 of file util.c.

486{
487 static unsigned short ImapPort = 0;
488 static unsigned short ImapsPort = 0;
489
490 if (ImapPort == 0)
491 {
492 struct servent *service = getservbyname("imap", "tcp");
493 if (service)
494 ImapPort = ntohs(service->s_port);
495 else
496 ImapPort = IMAP_PORT;
497 mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
498 }
499
500 if (ImapsPort == 0)
501 {
502 struct servent *service = getservbyname("imaps", "tcp");
503 if (service)
504 ImapsPort = ntohs(service->s_port);
505 else
506 ImapsPort = IMAP_SSL_PORT;
507 mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
508 }
509
510 /* Defaults */
511 cac->port = ImapPort;
513 cac->service = "imap";
515
516 struct Url *url = url_parse(path);
517 if (!url)
518 return -1;
519
520 if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
521 {
522 url_free(&url);
523 return -1;
524 }
525
526 if ((account_from_url(cac, url) < 0) || (cac->host[0] == '\0'))
527 {
528 url_free(&url);
529 return -1;
530 }
531
532 if (url->scheme == U_IMAPS)
533 cac->flags |= MUTT_ACCT_SSL;
534
535 mutt_str_copy(mailbox, url->path, mailboxlen);
536
537 url_free(&url);
538
539 if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
540 cac->port = ImapsPort;
541
542 return 0;
543}
@ MUTT_ACCT_PORT
Port field has been set.
Definition connaccount.h:47
@ MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition connaccount.h:51
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field() -.
Definition util.c:211
#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.
@ MUTT_ACCT_TYPE_IMAP
Imap Account.
const char * service
Name of the service, e.g. "imap".
Definition connaccount.h:67
char host[128]
Server to login to.
Definition connaccount.h:60
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Definition connaccount.h:76
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition connaccount.h:65
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition connaccount.h:66
unsigned short port
Port to connect to.
Definition connaccount.h:64
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:242
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition url.c:124
@ 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 556 of file util.c.

557{
558 char *b1 = NULL;
559 char *b2 = NULL;
560 int rc;
561
562 if (!mx1 || (*mx1 == '\0'))
563 mx1 = "INBOX";
564 if (!mx2 || (*mx2 == '\0'))
565 mx2 = "INBOX";
566 if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
567 {
568 return 0;
569 }
570
571 b1 = MUTT_MEM_MALLOC(strlen(mx1) + 1, char);
572 b2 = MUTT_MEM_MALLOC(strlen(mx2) + 1, char);
573
574 imap_fix_path(mx1, b1, strlen(mx1) + 1);
575 imap_fix_path(mx2, b2, strlen(mx2) + 1);
576
577 rc = mutt_str_cmp(b1, b2);
578 FREE(&b1);
579 FREE(&b2);
580
581 return rc;
582}
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition string.c:403
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
char * imap_fix_path(const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition util.c:689
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 592 of file util.c.

593{
594 struct ConnAccount cac_target = { { 0 } };
595 struct ConnAccount cac_home = { { 0 } };
596 struct Url url = { 0 };
597 const char *delim = NULL;
598 int tlen;
599 int hlen = 0;
600 bool home_match = false;
601 char target_mailbox[1024] = { 0 };
602 char home_mailbox[1024] = { 0 };
603
604 if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
605 return;
606
607 if (imap_path_probe(folder, NULL) != MUTT_IMAP)
608 goto fallback;
609
610 if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
611 goto fallback;
612
613 tlen = mutt_str_len(target_mailbox);
614 hlen = mutt_str_len(home_mailbox);
615
616 /* check whether we can do '+' substitution */
617 if (tlen && imap_account_match(&cac_home, &cac_target) &&
618 mutt_strn_equal(home_mailbox, target_mailbox, hlen))
619 {
620 const char *const c_imap_delim_chars = cs_subset_string(NeoMutt->sub, "imap_delim_chars");
621 if (hlen == 0)
622 {
623 home_match = true;
624 }
625 else if (c_imap_delim_chars)
626 {
627 for (delim = c_imap_delim_chars; *delim != '\0'; delim++)
628 if (target_mailbox[hlen] == *delim)
629 home_match = true;
630 }
631 }
632
633 /* do the '+' substitution */
634 if (home_match)
635 {
636 *path++ = '+';
637 /* copy remaining path, skipping delimiter */
638 if (hlen != 0)
639 hlen++;
640 memcpy(path, target_mailbox + hlen, tlen - hlen);
641 path[tlen - hlen] = '\0';
642 return;
643 }
644
645fallback:
646 account_to_url(&cac_target, &url);
647 url.path = target_mailbox;
648 url_tostring(&url, path, pathlen, U_NONE);
649}
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?
Definition imap.c:2683
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:426
#define U_NONE
No flags are set for URL parsing.
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 657 of file util.c.

658{
659 imap_error(msg, resp);
660 return query_yesorno(_("Continue?"), MUTT_NO);
661}
#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:329
void imap_error(const char *where, const char *msg)
Show an error and abort.
Definition util.c:668
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 668 of file util.c.

669{
670 mutt_error("%s [%s]", where, msg);
671}
#define mutt_error(...)
Definition logging2.h:94
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 689 of file util.c.

690{
691 const char *const c_imap_delim_chars = cs_subset_string(NeoMutt->sub, "imap_delim_chars");
692
693 char *out = path;
694 size_t space_left = plen - 1;
695
696 if (mailbox)
697 {
698 for (const char *c = mailbox; *c && space_left; c++, space_left--)
699 {
700 if (strchr(NONULL(c_imap_delim_chars), *c))
701 {
702 return imap_fix_path_with_delim(*c, mailbox, path, plen);
703 }
704 *out++ = *c;
705 }
706 }
707
708 *out = '\0';
709 return path;
710}
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:720
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 720 of file util.c.

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

757{
758 const char *p = mailbox;
759 buf_reset(dest);
760 if (!p)
761 return;
762
763 while (*p)
764 {
765 if (p[0] == delim)
766 {
767 buf_addch(dest, '/');
768 /* simple way to avoid collisions with UIDs */
769 if ((p[1] >= '0') && (p[1] <= '9'))
770 buf_addch(dest, '_');
771 }
772 else
773 {
774 buf_addch(dest, *p);
775 }
776 p++;
777 }
778}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
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 ( 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 787 of file util.c.

788{
789 char *pc = NULL;
790 char *pn = NULL;
791
792 if (!buf || !(pc = strchr(buf, '{')))
793 return -1;
794
795 pc++;
796 pn = pc;
797 while (mutt_isdigit(*pc))
798 pc++;
799 *pc = '\0';
800 if (!mutt_str_atoui(pn, bytes))
801 return -1;
802
803 return 0;
804}
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition atoi.c:217
bool mutt_isdigit(int arg)
Wrapper for isdigit(3).
Definition ctype.c:66
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 814 of file util.c.

815{
816 char *s = buf;
817
818 /* skip tag */
819 s = imap_next_word(s);
820 /* skip OK/NO/BAD response */
821 s = imap_next_word(s);
822
823 return s;
824}
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition util.c:831
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 831 of file util.c.

832{
833 bool quoted = false;
834
835 while (*s)
836 {
837 if (*s == '\\')
838 {
839 s++;
840 if (*s)
841 s++;
842 continue;
843 }
844 if (*s == '\"')
845 quoted = !quoted;
846 if (!quoted && mutt_isspace(*s))
847 break;
848 s++;
849 }
850
851 SKIPWS(s);
852 return s;
853}
bool mutt_isspace(int arg)
Wrapper for isspace(3).
Definition ctype.c:96
#define SKIPWS(ch)
Definition string2.h:52
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 862 of file util.c.

863{
864 struct Url url = { 0 };
865 account_to_url(cac, &url);
866 url.path = path;
867 url_tostring(&url, buf, buflen, U_NONE);
868}
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 876 of file util.c.

877{
878 struct Url url = { 0 };
879 account_to_url(cac, &url);
880 url.path = path;
881 url_tobuffer(&url, buf, U_NONE);
882}
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 893 of file util.c.

894{
895 const char *quote = "`\"\\";
896 if (!quote_backtick)
897 quote++;
898
899 char *pt = dest;
900 const char *s = src;
901
902 if (dlen < 3)
903 {
904 *dest = '\0';
905 return;
906 }
907
908 *pt++ = '"';
909 /* save room for quote-chars */
910 dlen -= 3;
911
912 for (; *s && dlen; s++)
913 {
914 if (strchr(quote, *s))
915 {
916 if (dlen < 2)
917 break;
918 dlen -= 2;
919 *pt++ = '\\';
920 *pt++ = *s;
921 }
922 else
923 {
924 *pt++ = *s;
925 dlen--;
926 }
927 }
928 *pt++ = '"';
929 *pt = '\0';
930}
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 936 of file util.c.

937{
938 char *d = s;
939
940 if (*s == '\"')
941 s++;
942 else
943 return;
944
945 while (*s)
946 {
947 if (*s == '\"')
948 {
949 *d = '\0';
950 return;
951 }
952 if (*s == '\\')
953 {
954 s++;
955 }
956 if (*s)
957 {
958 *d = *s;
959 d++;
960 s++;
961 }
962 }
963 *d = '\0';
964}
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 973 of file util.c.

974{
975 char *buf = mutt_str_dup(src);
976 imap_utf_encode(unicode, &buf);
977
978 imap_quote_string(dest, dlen, buf, false);
979
980 FREE(&buf);
981}
void imap_utf_encode(bool unicode, char **s)
Encode email from local charset to UTF-8.
Definition utf7.c:401
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
Quote string according to IMAP rules.
Definition util.c:893
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 990 of file util.c.

991{
993
994 char *buf = mutt_str_dup(s);
995 if (buf)
996 {
997 imap_utf_decode(unicode, &buf);
998 strncpy(s, buf, strlen(s));
999 }
1000
1001 FREE(&buf);
1002}
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition utf7.c:434
void imap_unquote_string(char *s)
Equally stupid unquoting routine.
Definition util.c:936
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 1007 of file util.c.

1008{
1009 time_t now = mutt_date_now();
1010 const short c_imap_keep_alive = cs_subset_number(NeoMutt->sub, "imap_keep_alive");
1011
1012 struct Account **ap = NULL;
1014 {
1015 struct Account *a = *ap;
1016 if (a->type != MUTT_IMAP)
1017 continue;
1018
1019 struct ImapAccountData *adata = a->adata;
1020 if (!adata || !adata->mailbox)
1021 continue;
1022
1023 if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + c_imap_keep_alive)))
1024 imap_check_mailbox(adata->mailbox, true);
1025 }
1026}
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:120
enum MxStatus imap_check_mailbox(struct Mailbox *m, bool force)
Use the NOOP or IDLE command to poll for new mail.
Definition imap.c:1220
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition date.c:459
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 1033 of file util.c.

1034{
1035 struct sigaction oldalrm = { 0 };
1036 struct sigaction act = { 0 };
1037 sigset_t oldmask = { 0 };
1038 int rc = 0;
1039
1040 const bool c_imap_passive = cs_subset_bool(NeoMutt->sub, "imap_passive");
1041 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", true, NULL);
1042 OptKeepQuiet = true;
1043
1044 sigprocmask(SIG_SETMASK, NULL, &oldmask);
1045
1046 sigemptyset(&act.sa_mask);
1047 act.sa_handler = mutt_sig_empty_handler;
1048#ifdef SA_INTERRUPT
1049 act.sa_flags = SA_INTERRUPT;
1050#else
1051 act.sa_flags = 0;
1052#endif
1053
1054 sigaction(SIGALRM, &act, &oldalrm);
1055
1056 const short c_imap_keep_alive = cs_subset_number(NeoMutt->sub, "imap_keep_alive");
1057 alarm(c_imap_keep_alive);
1058 while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1059 {
1060 alarm(0); /* cancel a possibly pending alarm */
1062 alarm(c_imap_keep_alive);
1063 }
1064
1065 alarm(0); /* cancel a possibly pending alarm */
1066
1067 sigaction(SIGALRM, &oldalrm, NULL);
1068 sigprocmask(SIG_SETMASK, &oldmask, NULL);
1069
1070 OptKeepQuiet = false;
1071 cs_subset_str_native_set(NeoMutt->sub, "imap_passive", c_imap_passive, NULL);
1072
1073 return rc;
1074}
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:49
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition signal.c:130
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:303
void imap_keep_alive(void)
Poll the current folder to keep the connection alive.
Definition util.c:1007
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 1080 of file util.c.

1081{
1083 struct ImapMboxData *mdata = imap_mdata_get(m);
1084 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1085 return;
1086 mdata->reopen |= IMAP_REOPEN_ALLOW;
1087}
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition adata.c:162
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition mdata.c:61
@ IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition private.h:68
struct Mailbox * mailbox
Current selected mailbox.
Definition adata.h:80
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 1093 of file util.c.

1094{
1096 struct ImapMboxData *mdata = imap_mdata_get(m);
1097 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1098 return;
1099 mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1100}
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 1108 of file util.c.

1109{
1110 if (!a1 || !a2)
1111 return false;
1112 if (a1->type != a2->type)
1113 return false;
1114 if (!mutt_istr_equal(a1->host, a2->host))
1115 return false;
1116 if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1117 return false;
1118 if (a1->flags & a2->flags & MUTT_ACCT_USER)
1119 return mutt_str_equal(a1->user, a2->user);
1120
1121 const char *user = NONULL(NeoMutt->username);
1122
1123 const char *const c_imap_user = cs_subset_string(NeoMutt->sub, "imap_user");
1124 if ((a1->type == MUTT_ACCT_TYPE_IMAP) && c_imap_user)
1125 user = c_imap_user;
1126
1127 if (a1->flags & MUTT_ACCT_USER)
1128 return mutt_str_equal(a1->user, user);
1129 if (a2->flags & MUTT_ACCT_USER)
1130 return mutt_str_equal(a2->user, user);
1131
1132 return true;
1133}
@ MUTT_ACCT_USER
User field has been set.
Definition connaccount.h:48
char user[128]
Username.
Definition connaccount.h:62
char * username
User's login name.
Definition neomutt.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 1140 of file util.c.

1141{
1142 if (!seqset || (*seqset == '\0'))
1143 return NULL;
1144
1145 struct SeqsetIterator *iter = MUTT_MEM_CALLOC(1, struct SeqsetIterator);
1146 iter->full_seqset = mutt_str_dup(seqset);
1147 iter->eostr = strchr(iter->full_seqset, '\0');
1148 iter->substr_cur = iter->substr_end = iter->full_seqset;
1149
1150 return iter;
1151}
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
UID Sequence Set Iterator.
Definition private.h:185
char * eostr
End of string.
Definition private.h:187
char * substr_end
End of substring.
Definition private.h:193
char * substr_cur
Current position in substring.
Definition private.h:192
char * full_seqset
Full sequence set string.
Definition private.h:186
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 1161 of file util.c.

1162{
1163 if (!iter || !next)
1164 return -1;
1165
1166 if (iter->in_range)
1167 {
1168 if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1169 (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1170 {
1171 iter->in_range = 0;
1172 }
1173 }
1174
1175 if (!iter->in_range)
1176 {
1177 iter->substr_cur = iter->substr_end;
1178 if (iter->substr_cur == iter->eostr)
1179 return 1;
1180
1181 iter->substr_end = strchr(iter->substr_cur, ',');
1182 if (!iter->substr_end)
1183 iter->substr_end = iter->eostr;
1184 else
1185 *(iter->substr_end++) = '\0';
1186
1187 char *range_sep = strchr(iter->substr_cur, ':');
1188 if (range_sep)
1189 *range_sep++ = '\0';
1190
1191 if (!mutt_str_atoui_full(iter->substr_cur, &iter->range_cur))
1192 return -1;
1193 if (range_sep)
1194 {
1195 if (!mutt_str_atoui_full(range_sep, &iter->range_end))
1196 return -1;
1197 }
1198 else
1199 {
1200 iter->range_end = iter->range_cur;
1201 }
1202
1203 iter->down = (iter->range_end < iter->range_cur);
1204 iter->in_range = 1;
1205 }
1206
1207 *next = iter->range_cur;
1208 if (iter->down)
1209 iter->range_cur--;
1210 else
1211 iter->range_cur++;
1212
1213 return 0;
1214}
unsigned int range_end
End of range.
Definition private.h:191
int down
Counting down.
Definition private.h:189
int in_range
Currently in a range.
Definition private.h:188
unsigned int range_cur
Current range value.
Definition private.h:190
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 1220 of file util.c.

1221{
1222 if (!ptr || !*ptr)
1223 return;
1224
1225 struct SeqsetIterator *iter = *ptr;
1226 FREE(&iter->full_seqset);
1227 FREE(ptr);
1228}
Here is the caller graph for this function: