NeoMutt  2022-04-29-249-gaae397
Teaching an old dog new tricks
DOXYGEN
util.c File Reference

IMAP helper functions. More...

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

Go to the source code of this file.

Functions

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

Detailed Description

IMAP helper functions.

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

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file util.c.

Function Documentation

◆ imap_adata_find()

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

Find the Account data for this path.

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

Definition at line 72 of file util.c.

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

◆ imap_mdata_cache_reset()

void imap_mdata_cache_reset ( struct ImapMboxData mdata)

Release and clear cache data of ImapMboxData structure.

Parameters
mdataImap Mailbox data

Definition at line 106 of file util.c.

107{
108 mutt_hash_free(&mdata->uid_hash);
109 imap_msn_free(&mdata->msn);
110 mutt_bcache_close(&mdata->bcache);
111}
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:165
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
void imap_msn_free(struct MSN *msn)
Free the cache.
Definition: msn.c:59
struct BodyCache * bcache
Email body cache.
Definition: mdata.h:60
struct HashTable * uid_hash
Definition: mdata.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_parent()

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

Get an IMAP folder's parent.

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

Definition at line 120 of file util.c.

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

◆ imap_get_parent_path()

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

Get the path of the parent folder.

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

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

Definition at line 161 of file util.c.

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

◆ imap_clean_path()

void imap_clean_path ( char *  path,
size_t  plen 
)

Cleans an IMAP path using imap_fix_path.

Parameters
pathPath to be cleaned
plenLength of the buffer

Does it in place.

Definition at line 188 of file util.c.

189{
190 struct ImapAccountData *adata = NULL;
191 struct ImapMboxData *mdata = NULL;
192
193 if (imap_adata_find(path, &adata, &mdata) < 0)
194 return;
195
196 /* Returns a fully qualified IMAP url */
197 imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
198 imap_mdata_free((void *) &mdata);
199}
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_field()

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

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

Definition at line 204 of file util.c.

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

◆ imap_msn_index_to_uid_seqset()

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

Convert MSN index of UIDs to Seqset.

Parameters
bufBuffer for the result
mdataImap Mailbox data

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

Definition at line 231 of file util.c.

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

◆ imap_hcache_open()

void imap_hcache_open ( struct ImapAccountData adata,
struct ImapMboxData mdata 
)

Open a header cache.

Parameters
adataImap Account data
mdataImap Mailbox data

Definition at line 297 of file util.c.

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

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

356{
357 if (!mdata->hcache)
358 return NULL;
359
360 char key[16] = { 0 };
361
362 sprintf(key, "/%u", uid);
363 struct HCacheEntry hce = mutt_hcache_fetch(mdata->hcache, key, mutt_str_len(key),
364 mdata->uidvalidity);
365 if (!hce.email && hce.uidvalidity)
366 {
367 mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
368 }
369
370 return hce.email;
371}
struct HCacheEntry mutt_hcache_fetch(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition: hcache.c:466
Wrapper for Email retrieved from the header cache.
Definition: lib.h:98
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition: lib.h:99
struct Email * email
Retrieved email.
Definition: lib.h:101
uint32_t uidvalidity
Definition: mdata.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_put()

int imap_hcache_put ( struct ImapMboxData mdata,
struct Email e 
)

Add an entry to the header cache.

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

Definition at line 380 of file util.c.

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

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

416{
417 if (!mdata->hcache)
418 return -1;
419
420 /* The seqset is likely large. Preallocate to reduce reallocs */
421 struct Buffer buf = mutt_buffer_make(8192);
422 imap_msn_index_to_uid_seqset(&buf, mdata);
423
424 int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
425 mutt_buffer_len(&buf) + 1);
426 mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
428 return rc;
429}
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
int mutt_hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
Store a key / data pair.
Definition: hcache.c:620
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:231
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_hcache_clear_uid_seqset()

int imap_hcache_clear_uid_seqset ( struct ImapMboxData mdata)

Delete a UID Sequence Set from the header cache.

Parameters
mdataImap Mailbox data
Return values
0Success
-1Error

Definition at line 437 of file util.c.

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

452{
453 if (!mdata->hcache)
454 return NULL;
455
456 char *seqset = NULL;
457 size_t dlen = 0;
458 char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10, &dlen);
459 if (hc_seqset)
460 {
461 seqset = mutt_strn_dup(hc_seqset, dlen);
462 mutt_hcache_free_raw(mdata->hcache, (void **) &hc_seqset);
463 }
464 mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
465
466 return seqset;
467}
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message's header from the cache.
Definition: hcache.c:529
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:548
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:451
#define NONULL(x)
Definition: string2.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_parse_path()

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

Parse an IMAP mailbox name into ConnAccount, name.

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

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

Definition at line 482 of file util.c.

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

◆ imap_mxcmp()

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

Compare mailbox names, giving priority to INBOX.

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

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

Definition at line 553 of file util.c.

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

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

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

664{
665 mutt_error("%s [%s]", where, msg);
666}
#define mutt_error(...)
Definition: logging.h:87
+ Here is the caller graph for this function:

◆ imap_fix_path()

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

Fix up the imap path.

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

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

Definition at line 685 of file util.c.

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

◆ imap_cachepath()

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

Generate a cache path for a mailbox.

Parameters
delimImap server delimiter
mailboxMailbox name
destBuffer to store cache path

Definition at line 716 of file util.c.

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

746{
747 char *pc = NULL;
748 char *pn = NULL;
749
750 if (!buf || !(pc = strchr(buf, '{')))
751 return -1;
752
753 pc++;
754 pn = pc;
755 while (isdigit((unsigned char) *pc))
756 pc++;
757 *pc = '\0';
758 if (!mutt_str_atoui(pn, bytes))
759 return -1;
760
761 return 0;
762}
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: atoi.c:202
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_get_qualifier()

char * imap_get_qualifier ( char *  buf)

Get the qualifier from a tagged response.

Parameters
bufCommand string to process
Return values
ptrStart of the qualifier

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

Definition at line 772 of file util.c.

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

790{
791 bool quoted = false;
792
793 while (*s)
794 {
795 if (*s == '\\')
796 {
797 s++;
798 if (*s)
799 s++;
800 continue;
801 }
802 if (*s == '\"')
803 quoted = !quoted;
804 if (!quoted && IS_SPACE(*s))
805 break;
806 s++;
807 }
808
809 SKIPWS(s);
810 return s;
811}
#define IS_SPACE(ch)
Definition: string2.h:38
#define SKIPWS(ch)
Definition: string2.h:46
+ Here is the caller graph for this function:

◆ imap_qualify_path()

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

Make an absolute IMAP folder target.

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

Definition at line 820 of file util.c.

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

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

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

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

929{
931
932 char *buf = mutt_str_dup(s);
933 if (buf)
934 {
935 imap_utf_decode(unicode, &buf);
936 strncpy(s, buf, strlen(s));
937 }
938
939 FREE(&buf);
940}
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:420
void imap_unquote_string(char *s)
Equally stupid unquoting routine.
Definition: util.c:874
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_keepalive()

void imap_keepalive ( void  )

Poll the current folder to keep the connection alive.

Definition at line 945 of file util.c.

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

◆ imap_wait_keepalive()

int imap_wait_keepalive ( pid_t  pid)

Wait for a process to change state.

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

Definition at line 969 of file util.c.

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

1017{
1019 struct ImapMboxData *mdata = imap_mdata_get(m);
1020 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1021 return;
1022 mdata->reopen |= IMAP_REOPEN_ALLOW;
1023}
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:89
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:60
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:66
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:76
+ Here is the call graph for this function:
+ 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 1029 of file util.c.

1030{
1032 struct ImapMboxData *mdata = imap_mdata_get(m);
1033 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1034 return;
1035 mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1036}
+ 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 1044 of file util.c.

1045{
1046 if (!a1 || !a2)
1047 return false;
1048 if (a1->type != a2->type)
1049 return false;
1050 if (!mutt_istr_equal(a1->host, a2->host))
1051 return false;
1052 if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1053 return false;
1054 if (a1->flags & a2->flags & MUTT_ACCT_USER)
1055 return strcmp(a1->user, a2->user) == 0;
1056
1057 const char *user = NONULL(Username);
1058
1059 const char *const c_imap_user = cs_subset_string(NeoMutt->sub, "imap_user");
1060 if ((a1->type == MUTT_ACCT_TYPE_IMAP) && c_imap_user)
1061 user = c_imap_user;
1062
1063 if (a1->flags & MUTT_ACCT_USER)
1064 return strcmp(a1->user, user) == 0;
1065 if (a2->flags & MUTT_ACCT_USER)
1066 return strcmp(a2->user, user) == 0;
1067
1068 return true;
1069}
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:44
char * Username
User's login name.
Definition: mutt_globals.h:52
char user[128]
Username.
Definition: connaccount.h:56
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_new()

struct SeqsetIterator * mutt_seqset_iterator_new ( const char *  seqset)

Create a new Sequence Set Iterator.

Parameters
seqsetSource Sequence Set
Return values
ptrNewly allocated Sequence Set Iterator

Definition at line 1076 of file util.c.

1077{
1078 if (!seqset || (*seqset == '\0'))
1079 return NULL;
1080
1081 struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1082 iter->full_seqset = mutt_str_dup(seqset);
1083 iter->eostr = strchr(iter->full_seqset, '\0');
1084 iter->substr_cur = iter->substr_end = iter->full_seqset;
1085
1086 return iter;
1087}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
UID Sequence Set Iterator.
Definition: private.h:170
char * eostr
Definition: private.h:172
char * substr_end
Definition: private.h:178
char * substr_cur
Definition: private.h:177
char * full_seqset
Definition: private.h:171
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_next()

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

Get the next UID from a Sequence Set.

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

Definition at line 1097 of file util.c.

1098{
1099 if (!iter || !next)
1100 return -1;
1101
1102 if (iter->in_range)
1103 {
1104 if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1105 (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1106 {
1107 iter->in_range = 0;
1108 }
1109 }
1110
1111 if (!iter->in_range)
1112 {
1113 iter->substr_cur = iter->substr_end;
1114 if (iter->substr_cur == iter->eostr)
1115 return 1;
1116
1117 iter->substr_end = strchr(iter->substr_cur, ',');
1118 if (!iter->substr_end)
1119 iter->substr_end = iter->eostr;
1120 else
1121 *(iter->substr_end++) = '\0';
1122
1123 char *range_sep = strchr(iter->substr_cur, ':');
1124 if (range_sep)
1125 *range_sep++ = '\0';
1126
1127 if (!mutt_str_atoui_full(iter->substr_cur, &iter->range_cur))
1128 return -1;
1129 if (range_sep)
1130 {
1131 if (!mutt_str_atoui_full(range_sep, &iter->range_end))
1132 return -1;
1133 }
1134 else
1135 iter->range_end = iter->range_cur;
1136
1137 iter->down = (iter->range_end < iter->range_cur);
1138 iter->in_range = 1;
1139 }
1140
1141 *next = iter->range_cur;
1142 if (iter->down)
1143 iter->range_cur--;
1144 else
1145 iter->range_cur++;
1146
1147 return 0;
1148}
unsigned int range_end
Definition: private.h:176
unsigned int range_cur
Definition: private.h:175
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_free()

void mutt_seqset_iterator_free ( struct SeqsetIterator **  ptr)

Free a Sequence Set Iterator.

Parameters
[out]ptrIterator to free

Definition at line 1154 of file util.c.

1155{
1156 if (!ptr || !*ptr)
1157 return;
1158
1159 struct SeqsetIterator *iter = *ptr;
1160 FREE(&iter->full_seqset);
1161 FREE(ptr);
1162}
+ Here is the caller graph for this function: