NeoMutt
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 <ctype.h>
#include <errno.h>
#include <netdb.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 "globals.h"
#include "mdata.h"
#include "msn.h"
#include "mutt_account.h"
#include "hcache/lib.h"
+ Include dependency graph for util.c:

Go to the source code of this file.

Functions

int imap_adata_find (const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
 Find the Account data for this path.
 
void imap_mdata_cache_reset (struct ImapMboxData *mdata)
 Release and clear cache data of ImapMboxData structure.
 
void imap_get_parent (const char *mbox, char delim, char *buf, size_t buflen)
 Get an IMAP folder's parent.
 
void imap_get_parent_path (const char *path, char *buf, size_t buflen)
 Get the path of the parent folder.
 
void imap_clean_path (char *path, size_t plen)
 Cleans an IMAP path using imap_fix_path.
 
static const char * imap_get_field (enum ConnAccountField field, void *gf_data)
 Get connection login credentials - Implements ConnAccount::get_field()
 
static void imap_msn_index_to_uid_seqset (struct Buffer *buf, struct ImapMboxData *mdata)
 Convert MSN index of UIDs to Seqset.
 
static void imap_hcache_namer (const char *path, struct Buffer *dest)
 Generate a filename for the header cache - Implements hcache_namer_t -.
 
void imap_hcache_open (struct ImapAccountData *adata, struct ImapMboxData *mdata)
 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 (char delim, const char *mailbox, char *path, size_t plen)
 Fix up the imap path.
 
void imap_cachepath (char delim, const char *mailbox, struct Buffer *dest)
 Generate a cache path for a mailbox.
 
int imap_get_literal_count (const char *buf, unsigned int *bytes)
 Write number of bytes in an IMAP literal into bytes.
 
char * imap_get_qualifier (char *buf)
 Get the qualifier from a tagged response.
 
char * imap_next_word (char *s)
 Find where the next IMAP word begins.
 
void imap_qualify_path (char *buf, size_t buflen, struct ConnAccount *cac, char *path)
 Make an absolute IMAP folder target.
 
void imap_buf_qualify_path (struct Buffer *buf, struct ConnAccount *cac, char *path)
 Make an absolute IMAP folder target to a buffer.
 
void imap_quote_string (char *dest, size_t dlen, const char *src, bool quote_backtick)
 Quote string according to IMAP rules.
 
void imap_unquote_string (char *s)
 Equally stupid unquoting routine.
 
void imap_munge_mbox_name (bool unicode, char *dest, size_t dlen, const char *src)
 Quote awkward characters in a mailbox name.
 
void imap_unmunge_mbox_name (bool unicode, char *s)
 Remove quoting from a mailbox name.
 
void imap_keep_alive (void)
 Poll the current folder to keep the connection alive.
 
int imap_wait_keep_alive (pid_t pid)
 Wait for a process to change state.
 
void imap_allow_reopen (struct Mailbox *m)
 Allow re-opening a folder upon expunge.
 
void imap_disallow_reopen (struct Mailbox *m)
 Disallow re-opening a folder upon expunge.
 
bool imap_account_match (const struct ConnAccount *a1, const struct ConnAccount *a2)
 Compare two Accounts.
 
struct SeqsetIteratormutt_seqset_iterator_new (const char *seqset)
 Create a new Sequence Set Iterator.
 
int mutt_seqset_iterator_next (struct SeqsetIterator *iter, unsigned int *next)
 Get the next UID from a Sequence Set.
 
void mutt_seqset_iterator_free (struct SeqsetIterator **ptr)
 Free a Sequence Set Iterator.
 

Detailed Description

IMAP helper functions.

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

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

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

Definition in file util.c.

Function Documentation

◆ imap_adata_find()

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

Find the Account data for this path.

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

Definition at line 71 of file util.c.

73{
74 struct ConnAccount cac = { { 0 } };
75 struct ImapAccountData *tmp_adata = NULL;
76 char tmp[1024] = { 0 };
77
78 if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
79 return -1;
80
81 struct Account *np = NULL;
82 TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
83 {
84 if (np->type != MUTT_IMAP)
85 continue;
86
87 tmp_adata = np->adata;
88 if (!tmp_adata)
89 continue;
90 if (imap_account_match(&tmp_adata->conn->account, &cac))
91 {
92 *mdata = imap_mdata_new(tmp_adata, tmp);
93 *adata = tmp_adata;
94 return 0;
95 }
96 }
97 mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
98 return -1;
99}
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
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: logging2.h:45
@ 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:41
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:46
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:471
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1051
+ 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 105 of file util.c.

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

◆ imap_get_parent()

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

Get an IMAP folder's parent.

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

Definition at line 119 of file util.c.

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

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

◆ imap_clean_path()

void imap_clean_path ( char *  path,
size_t  plen 
)

Cleans an IMAP path using imap_fix_path.

Parameters
pathPath to be cleaned
plenLength of the buffer

Does it in place.

Definition at line 187 of file util.c.

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

204{
205 switch (field)
206 {
207 case MUTT_CA_LOGIN:
208 return cs_subset_string(NeoMutt->sub, "imap_login");
209 case MUTT_CA_USER:
210 return cs_subset_string(NeoMutt->sub, "imap_user");
211 case MUTT_CA_PASS:
212 return cs_subset_string(NeoMutt->sub, "imap_pass");
214 return cs_subset_string(NeoMutt->sub, "imap_oauth_refresh_command");
215 case MUTT_CA_HOST:
216 default:
217 return NULL;
218 }
219}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
@ 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:45
+ 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 230 of file util.c.

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

297{
298 if (!adata || !mdata)
299 return;
300
301 if (mdata->hcache)
302 return;
303
304 struct HeaderCache *hc = NULL;
305 struct Buffer *mbox = buf_pool_get();
306 struct Buffer *cachepath = buf_pool_get();
307
308 imap_cachepath(adata->delim, mdata->name, mbox);
309
310 if (strstr(buf_string(mbox), "/../") || mutt_str_equal(buf_string(mbox), "..") ||
311 mutt_strn_equal(buf_string(mbox), "../", 3))
312 {
313 goto cleanup;
314 }
315 size_t len = buf_len(mbox);
316 if ((len > 3) && (mutt_str_equal(buf_string(mbox) + len - 3, "/..")))
317 goto cleanup;
318
319 struct Url url = { 0 };
320 mutt_account_tourl(&adata->conn->account, &url);
321 url.path = mbox->data;
322 url_tobuffer(&url, cachepath, U_PATH);
323
324 const char *const c_header_cache = cs_subset_path(NeoMutt->sub, "header_cache");
325 hc = hcache_open(c_header_cache, buf_string(cachepath), imap_hcache_namer);
326
327cleanup:
328 buf_pool_release(&mbox);
329 buf_pool_release(&cachepath);
330 mdata->hcache = hc;
331}
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:466
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
Definition: helpers.c:169
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:286
struct HeaderCache * hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:494
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
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:497
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:34
char * data
Pointer to data.
Definition: buffer.h:35
Header Cache.
Definition: lib.h:88
struct HeaderCache * hcache
Email header cache.
Definition: mdata.h:63
char * name
Mailbox name.
Definition: mdata.h:41
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:357
#define U_PATH
Definition: url.h:50
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:707
+ 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 337 of file util.c.

338{
339 if (!mdata->hcache)
340 return;
341
342 hcache_close(&mdata->hcache);
343}
void hcache_close(struct HeaderCache **ptr)
Multiplexor for StoreOps::close.
Definition: hcache.c:563
+ 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 352 of file util.c.

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

◆ imap_hcache_put()

int imap_hcache_put ( struct ImapMboxData mdata,
struct Email e 
)

Add an entry to the header cache.

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

Definition at line 377 of file util.c.

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

396{
397 if (!mdata->hcache)
398 return -1;
399
400 char key[16] = { 0 };
401
402 snprintf(key, sizeof(key), "/%u", uid);
403 return hcache_delete_record(mdata->hcache, key, mutt_str_len(key));
404}
int hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:759
+ 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 412 of file util.c.

413{
414 if (!mdata->hcache)
415 return -1;
416
417 /* The seqset is likely large. Preallocate to reduce reallocs */
418 struct Buffer buf = buf_make(8192);
419 imap_msn_index_to_uid_seqset(&buf, mdata);
420
421 int rc = hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data, buf_len(&buf) + 1);
422 mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
423 buf_dealloc(&buf);
424 return rc;
425}
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:389
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:70
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:741
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:230
+ 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 433 of file util.c.

434{
435 if (!mdata->hcache)
436 return -1;
437
438 return hcache_delete_record(mdata->hcache, "/UIDSEQSET", 10);
439}
+ 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 447 of file util.c.

448{
449 if (!mdata->hcache)
450 return NULL;
451
452 char *seqset = hcache_fetch_str(mdata->hcache, "/UIDSEQSET", 10);
453 mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
454
455 return seqset;
456}
char * hcache_fetch_str(struct HeaderCache *hc, const char *key, size_t keylen)
Fetch a string from the cache.
Definition: hcache.c:670
#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 471 of file util.c.

472{
473 static unsigned short ImapPort = 0;
474 static unsigned short ImapsPort = 0;
475
476 if (ImapPort == 0)
477 {
478 struct servent *service = getservbyname("imap", "tcp");
479 if (service)
480 ImapPort = ntohs(service->s_port);
481 else
482 ImapPort = IMAP_PORT;
483 mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
484 }
485
486 if (ImapsPort == 0)
487 {
488 struct servent *service = getservbyname("imaps", "tcp");
489 if (service)
490 ImapsPort = ntohs(service->s_port);
491 else
492 ImapsPort = IMAP_SSL_PORT;
493 mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
494 }
495
496 /* Defaults */
497 cac->port = ImapPort;
499 cac->service = "imap";
501
502 struct Url *url = url_parse(path);
503 if (!url)
504 return -1;
505
506 if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
507 {
508 url_free(&url);
509 return -1;
510 }
511
512 if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
513 {
514 url_free(&url);
515 return -1;
516 }
517
518 if (url->scheme == U_IMAPS)
519 cac->flags |= MUTT_ACCT_SSL;
520
521 mutt_str_copy(mailbox, url->path, mailboxlen);
522
523 url_free(&url);
524
525 if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
526 cac->port = ImapsPort;
527
528 return 0;
529}
#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:44
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:45
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:238
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
@ U_IMAP
Url is imap://.
Definition: url.h:39
@ U_IMAPS
Url is imaps://.
Definition: url.h:40
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:203
+ 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 542 of file util.c.

543{
544 char *b1 = NULL;
545 char *b2 = NULL;
546 int rc;
547
548 if (!mx1 || (*mx1 == '\0'))
549 mx1 = "INBOX";
550 if (!mx2 || (*mx2 == '\0'))
551 mx2 = "INBOX";
552 if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
553 {
554 return 0;
555 }
556
557 b1 = mutt_mem_malloc(strlen(mx1) + 1);
558 b2 = mutt_mem_malloc(strlen(mx2) + 1);
559
560 imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
561 imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
562
563 rc = mutt_str_cmp(b1, b2);
564 FREE(&b1);
565 FREE(&b2);
566
567 return rc;
568}
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:45
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:471
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:676
+ 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 578 of file util.c.

579{
580 struct ConnAccount cac_target = { { 0 } };
581 struct ConnAccount cac_home = { { 0 } };
582 struct Url url = { 0 };
583 const char *delim = NULL;
584 int tlen;
585 int hlen = 0;
586 bool home_match = false;
587 char target_mailbox[1024] = { 0 };
588 char home_mailbox[1024] = { 0 };
589
590 if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
591 return;
592
593 if (imap_path_probe(folder, NULL) != MUTT_IMAP)
594 goto fallback;
595
596 if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
597 goto fallback;
598
599 tlen = mutt_str_len(target_mailbox);
600 hlen = mutt_str_len(home_mailbox);
601
602 /* check whether we can do '+' substitution */
603 if (tlen && imap_account_match(&cac_home, &cac_target) &&
604 mutt_strn_equal(home_mailbox, target_mailbox, hlen))
605 {
606 const char *const c_imap_delim_chars = cs_subset_string(NeoMutt->sub, "imap_delim_chars");
607 if (hlen == 0)
608 {
609 home_match = true;
610 }
611 else if (c_imap_delim_chars)
612 {
613 for (delim = c_imap_delim_chars; *delim != '\0'; delim++)
614 if (target_mailbox[hlen] == *delim)
615 home_match = true;
616 }
617 }
618
619 /* do the '+' substitution */
620 if (home_match)
621 {
622 *path++ = '+';
623 /* copy remaining path, skipping delimiter */
624 if (hlen != 0)
625 ++hlen;
626 memcpy(path, target_mailbox + hlen, tlen - hlen);
627 path[tlen - hlen] = '\0';
628 return;
629 }
630
631fallback:
632 mutt_account_tourl(&cac_target, &url);
633 url.path = target_mailbox;
634 url_tostring(&url, path, pathlen, U_NO_FLAGS);
635}
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2329
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:422
#define U_NO_FLAGS
Definition: url.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_continue()

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

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

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

Definition at line 643 of file util.c.

644{
645 imap_error(msg, resp);
646 return query_yesorno(_("Continue?"), MUTT_NO);
647}
#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:330
void imap_error(const char *where, const char *msg)
Show an error and abort.
Definition: util.c:654
+ 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 654 of file util.c.

655{
656 mutt_error("%s [%s]", where, msg);
657}
#define mutt_error(...)
Definition: logging2.h:92
+ 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 676 of file util.c.

677{
678 int i = 0;
679 const char *const c_imap_delim_chars = cs_subset_string(NeoMutt->sub, "imap_delim_chars");
680 for (; mailbox && *mailbox && (i < (plen - 1)); i++)
681 {
682 if ((*mailbox == delim) || (!delim && strchr(NONULL(c_imap_delim_chars), *mailbox)))
683 {
684 delim = *mailbox;
685 /* Skip multiple occurrences of delim */
686 while (*mailbox && *(mailbox + 1) == delim)
687 mailbox++;
688 }
689 path[i] = *mailbox++;
690 }
691
692 /* Do not terminate with a delimiter */
693 if ((i != 0) && (path[i - 1] == delim))
694 i--;
695
696 /* Ensure null termination */
697 path[i] = '\0';
698 return path;
699}
+ 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 707 of file util.c.

708{
709 const char *p = mailbox;
710 buf_reset(dest);
711 if (!p)
712 return;
713
714 while (*p)
715 {
716 if (p[0] == delim)
717 {
718 buf_addch(dest, '/');
719 /* simple way to avoid collisions with UIDs */
720 if ((p[1] >= '0') && (p[1] <= '9'))
721 buf_addch(dest, '_');
722 }
723 else
724 {
725 buf_addch(dest, *p);
726 }
727 p++;
728 }
729}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
+ 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 738 of file util.c.

739{
740 char *pc = NULL;
741 char *pn = NULL;
742
743 if (!buf || !(pc = strchr(buf, '{')))
744 return -1;
745
746 pc++;
747 pn = pc;
748 while (isdigit((unsigned char) *pc))
749 pc++;
750 *pc = '\0';
751 if (!mutt_str_atoui(pn, bytes))
752 return -1;
753
754 return 0;
755}
const char * mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: atoi.c:213
+ 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 765 of file util.c.

766{
767 char *s = buf;
768
769 /* skip tag */
770 s = imap_next_word(s);
771 /* skip OK/NO/BAD response */
772 s = imap_next_word(s);
773
774 return s;
775}
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:782
+ 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 782 of file util.c.

783{
784 bool quoted = false;
785
786 while (*s)
787 {
788 if (*s == '\\')
789 {
790 s++;
791 if (*s)
792 s++;
793 continue;
794 }
795 if (*s == '\"')
796 quoted = !quoted;
797 if (!quoted && isspace(*s))
798 break;
799 s++;
800 }
801
802 SKIPWS(s);
803 return s;
804}
#define SKIPWS(ch)
Definition: string2.h:45
+ 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 813 of file util.c.

814{
815 struct Url url = { 0 };
816 mutt_account_tourl(cac, &url);
817 url.path = path;
818 url_tostring(&url, buf, buflen, U_NO_FLAGS);
819}
+ 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 827 of file util.c.

828{
829 struct Url url = { 0 };
830 mutt_account_tourl(cac, &url);
831 url.path = path;
832 url_tobuffer(&url, buf, U_NO_FLAGS);
833}
+ 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 844 of file util.c.

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

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

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

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

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

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

1024{
1026 struct ImapMboxData *mdata = imap_mdata_get(m);
1027 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1028 return;
1029 mdata->reopen |= IMAP_REOPEN_ALLOW;
1030}
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: adata.c:123
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: mdata.c:60
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:64
struct Mailbox * mailbox
Current selected mailbox.
Definition: adata.h:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_disallow_reopen()

void imap_disallow_reopen ( struct Mailbox m)

Disallow re-opening a folder upon expunge.

Parameters
mMailbox

Definition at line 1036 of file util.c.

1037{
1039 struct ImapMboxData *mdata = imap_mdata_get(m);
1040 if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1041 return;
1042 mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1043}
+ 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 1051 of file util.c.

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

1084{
1085 if (!seqset || (*seqset == '\0'))
1086 return NULL;
1087
1088 struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1089 iter->full_seqset = mutt_str_dup(seqset);
1090 iter->eostr = strchr(iter->full_seqset, '\0');
1091 iter->substr_cur = iter->substr_end = iter->full_seqset;
1092
1093 return iter;
1094}
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:169
char * eostr
Definition: private.h:171
char * substr_end
Definition: private.h:177
char * substr_cur
Definition: private.h:176
char * full_seqset
Definition: private.h:170
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_seqset_iterator_next()

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

Get the next UID from a Sequence Set.

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

Definition at line 1104 of file util.c.

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

◆ mutt_seqset_iterator_free()

void mutt_seqset_iterator_free ( struct SeqsetIterator **  ptr)

Free a Sequence Set Iterator.

Parameters
[out]ptrIterator to free

Definition at line 1163 of file util.c.

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