NeoMutt  2020-06-26-89-g172cd3
Teaching an old dog new tricks
DOXYGEN
util.c
Go to the documentation of this file.
1 
32 #include "config.h"
33 #include <ctype.h>
34 #include <errno.h>
35 #include <netdb.h>
36 #include <netinet/in.h>
37 #include <signal.h>
38 #include <stdbool.h>
39 #include <stdint.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <sys/wait.h>
43 #include <time.h>
44 #include <unistd.h>
45 #include "private.h"
46 #include "mutt/lib.h"
47 #include "config/lib.h"
48 #include "email/lib.h"
49 #include "core/lib.h"
50 #include "conn/lib.h"
51 #include "gui/lib.h"
52 #include "mutt_account.h"
53 #include "mutt_globals.h"
54 #include "options.h"
55 #include "bcache/lib.h"
56 #include "imap/lib.h"
57 #ifdef USE_HCACHE
58 #include "message.h"
59 #include "hcache/lib.h"
60 #endif
61 
66 void imap_adata_free(void **ptr)
67 {
68  if (!ptr || !*ptr)
69  return;
70 
71  struct ImapAccountData *adata = *ptr;
72 
73  FREE(&adata->capstr);
74  mutt_buffer_dealloc(&adata->cmdbuf);
75  FREE(&adata->buf);
76  FREE(&adata->cmds);
77 
78  if (adata->conn)
79  {
80  if (adata->conn->close)
81  adata->conn->close(adata->conn);
82  FREE(&adata->conn);
83  }
84 
85  FREE(ptr);
86 }
87 
93 {
94  struct ImapAccountData *adata = mutt_mem_calloc(1, sizeof(struct ImapAccountData));
95  adata->account = a;
96 
97  static unsigned char new_seqid = 'a';
98 
99  adata->seqid = new_seqid;
100  adata->cmdslots = C_ImapPipelineDepth + 2;
101  adata->cmds = mutt_mem_calloc(adata->cmdslots, sizeof(*adata->cmds));
102 
103  if (++new_seqid > 'z')
104  new_seqid = 'a';
105 
106  return adata;
107 }
108 
115 {
116  if (!m || (m->type != MUTT_IMAP) || !m->account)
117  return NULL;
118  return m->account->adata;
119 }
120 
129 int imap_adata_find(const char *path, struct ImapAccountData **adata,
130  struct ImapMboxData **mdata)
131 {
132  struct ConnAccount cac = { { 0 } };
133  struct ImapAccountData *tmp_adata = NULL;
134  char tmp[1024];
135 
136  if (imap_parse_path(path, &cac, tmp, sizeof(tmp)) < 0)
137  return -1;
138 
139  struct Account *np = NULL;
140  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
141  {
142  if (np->type != MUTT_IMAP)
143  continue;
144 
145  tmp_adata = np->adata;
146  if (!tmp_adata)
147  continue;
148  if (imap_account_match(&tmp_adata->conn->account, &cac))
149  {
150  *mdata = imap_mdata_new(tmp_adata, tmp);
151  *adata = tmp_adata;
152  return 0;
153  }
154  }
155  mutt_debug(LL_DEBUG3, "no ImapAccountData found\n");
156  return -1;
157 }
158 
165 struct ImapMboxData *imap_mdata_new(struct ImapAccountData *adata, const char *name)
166 {
167  char buf[1024];
168  struct ImapMboxData *mdata = mutt_mem_calloc(1, sizeof(struct ImapMboxData));
169 
170  mdata->real_name = mutt_str_dup(name);
171 
172  imap_fix_path(adata->delim, name, buf, sizeof(buf));
173  if (buf[0] == '\0')
174  mutt_str_copy(buf, "INBOX", sizeof(buf));
175  mdata->name = mutt_str_dup(buf);
176 
177  imap_munge_mbox_name(adata->unicode, buf, sizeof(buf), mdata->name);
178  mdata->munge_name = mutt_str_dup(buf);
179 
180  mdata->reopen &= IMAP_REOPEN_ALLOW;
181 
182  STAILQ_INIT(&mdata->flags);
183 
184 #ifdef USE_HCACHE
185  imap_hcache_open(adata, mdata);
186  if (mdata->hcache)
187  {
188  size_t dlen = 0;
189  void *uidvalidity = mutt_hcache_fetch_raw(mdata->hcache, "/UIDVALIDITY", 12, &dlen);
190  void *uidnext = mutt_hcache_fetch_raw(mdata->hcache, "/UIDNEXT", 8, &dlen);
191  unsigned long long *modseq =
192  mutt_hcache_fetch_raw(mdata->hcache, "/MODSEQ", 7, &dlen);
193  if (uidvalidity)
194  {
195  mdata->uidvalidity = *(uint32_t *) uidvalidity;
196  mdata->uid_next = uidnext ? *(unsigned int *) uidnext : 0;
197  mdata->modseq = modseq ? *modseq : 0;
198  mutt_debug(LL_DEBUG3, "hcache uidvalidity %u, uidnext %u, modseq %llu\n",
199  mdata->uidvalidity, mdata->uid_next, mdata->modseq);
200  }
201  mutt_hcache_free_raw(mdata->hcache, &uidvalidity);
202  mutt_hcache_free_raw(mdata->hcache, &uidnext);
203  mutt_hcache_free_raw(mdata->hcache, (void **) &modseq);
204  imap_hcache_close(mdata);
205  }
206 #endif
207 
208  return mdata;
209 }
210 
216 {
217  mutt_hash_free(&mdata->uid_hash);
218  FREE(&mdata->msn_index);
219  mdata->msn_index_size = 0;
220  mdata->max_msn = 0;
221  mutt_bcache_close(&mdata->bcache);
222 }
223 
228 void imap_mdata_free(void **ptr)
229 {
230  if (!ptr || !*ptr)
231  return;
232 
233  struct ImapMboxData *mdata = *ptr;
234 
235  imap_mdata_cache_reset(mdata);
236  mutt_list_free(&mdata->flags);
237  FREE(&mdata->name);
238  FREE(&mdata->real_name);
239  FREE(&mdata->munge_name);
240  FREE(ptr);
241 }
242 
248 {
249  if (!m || (m->type != MUTT_IMAP) || !m->mdata)
250  return NULL;
251  return m->mdata;
252 }
253 
261 void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
262 {
263  /* Make a copy of the mailbox name, but only if the pointers are different */
264  if (mbox != buf)
265  mutt_str_copy(buf, mbox, buflen);
266 
267  int n = mutt_str_len(buf);
268 
269  /* Let's go backwards until the next delimiter
270  *
271  * If buf[n] is a '/', the first n-- will allow us
272  * to ignore it. If it isn't, then buf looks like
273  * "/aaaaa/bbbb". There is at least one "b", so we can't skip
274  * the "/" after the 'a's.
275  *
276  * If buf == '/', then n-- => n == 0, so the loop ends
277  * immediately */
278  for (n--; (n >= 0) && (buf[n] != delim); n--)
279  ; // do nothing
280 
281  /* We stopped before the beginning. There is a trailing slash. */
282  if (n > 0)
283  {
284  /* Strip the trailing delimiter. */
285  buf[n] = '\0';
286  }
287  else
288  {
289  buf[0] = (n == 0) ? delim : '\0';
290  }
291 }
292 
302 void imap_get_parent_path(const char *path, char *buf, size_t buflen)
303 {
304  struct ImapAccountData *adata = NULL;
305  struct ImapMboxData *mdata = NULL;
306  char mbox[1024];
307 
308  if (imap_adata_find(path, &adata, &mdata) < 0)
309  {
310  mutt_str_copy(buf, path, buflen);
311  return;
312  }
313 
314  /* Gets the parent mbox in mbox */
315  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
316 
317  /* Returns a fully qualified IMAP url */
318  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
319  imap_mdata_free((void *) &mdata);
320 }
321 
329 void imap_clean_path(char *path, size_t plen)
330 {
331  struct ImapAccountData *adata = NULL;
332  struct ImapMboxData *mdata = NULL;
333 
334  if (imap_adata_find(path, &adata, &mdata) < 0)
335  return;
336 
337  /* Returns a fully qualified IMAP url */
338  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
339  imap_mdata_free((void *) &mdata);
340 }
341 
345 static const char *imap_get_field(enum ConnAccountField field, void *gf_data)
346 {
347  switch (field)
348  {
349  case MUTT_CA_LOGIN:
350  return C_ImapLogin;
351  case MUTT_CA_USER:
352  return C_ImapUser;
353  case MUTT_CA_PASS:
354  return C_ImapPass;
355  case MUTT_CA_OAUTH_CMD:
357  case MUTT_CA_HOST:
358  default:
359  return NULL;
360  }
361 }
362 
363 #ifdef USE_HCACHE
364 
372 static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
373 {
374  int first = 1, state = 0;
375  unsigned int cur_uid = 0, last_uid = 0;
376  unsigned int range_begin = 0, range_end = 0;
377 
378  for (unsigned int msn = 1; msn <= mdata->max_msn + 1; msn++)
379  {
380  bool match = false;
381  if (msn <= mdata->max_msn)
382  {
383  struct Email *e_cur = mdata->msn_index[msn - 1];
384  cur_uid = e_cur ? imap_edata_get(e_cur)->uid : 0;
385  if (!state || (cur_uid && ((cur_uid - 1) == last_uid)))
386  match = true;
387  last_uid = cur_uid;
388  }
389 
390  if (match)
391  {
392  switch (state)
393  {
394  case 1: /* single: convert to a range */
395  state = 2;
396  /* fall through */
397  case 2: /* extend range ending */
398  range_end = cur_uid;
399  break;
400  default:
401  state = 1;
402  range_begin = cur_uid;
403  break;
404  }
405  }
406  else if (state)
407  {
408  if (first)
409  first = 0;
410  else
411  mutt_buffer_addch(buf, ',');
412 
413  if (state == 1)
414  mutt_buffer_add_printf(buf, "%u", range_begin);
415  else if (state == 2)
416  mutt_buffer_add_printf(buf, "%u:%u", range_begin, range_end);
417 
418  state = 1;
419  range_begin = cur_uid;
420  }
421  }
422 }
423 
427 static void imap_hcache_namer(const char *path, struct Buffer *dest)
428 {
429  mutt_buffer_printf(dest, "%s.hcache", path);
430 }
431 
437 void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
438 {
439  if (!adata || !mdata)
440  return;
441 
442  if (mdata->hcache)
443  return;
444 
445  header_cache_t *hc = NULL;
446  struct Buffer *mbox = mutt_buffer_pool_get();
447  struct Buffer *cachepath = mutt_buffer_pool_get();
448 
449  imap_cachepath(adata->delim, mdata->name, mbox);
450 
451  if (strstr(mutt_b2s(mbox), "/../") || mutt_str_equal(mutt_b2s(mbox), "..") ||
452  mutt_strn_equal(mutt_b2s(mbox), "../", 3))
453  {
454  goto cleanup;
455  }
456  size_t len = mutt_buffer_len(mbox);
457  if ((len > 3) && (strcmp(mutt_b2s(mbox) + len - 3, "/..") == 0))
458  goto cleanup;
459 
460  struct Url url = { 0 };
461  mutt_account_tourl(&adata->conn->account, &url);
462  url.path = mbox->data;
463  url_tobuffer(&url, cachepath, U_PATH);
464 
466 
467 cleanup:
469  mutt_buffer_pool_release(&cachepath);
470  mdata->hcache = hc;
471 }
472 
477 void imap_hcache_close(struct ImapMboxData *mdata)
478 {
479  if (!mdata->hcache)
480  return;
481 
482  mutt_hcache_close(mdata->hcache);
483  mdata->hcache = NULL;
484 }
485 
493 struct Email *imap_hcache_get(struct ImapMboxData *mdata, unsigned int uid)
494 {
495  if (!mdata->hcache)
496  return NULL;
497 
498  char key[16];
499 
500  sprintf(key, "/%u", uid);
501  struct HCacheEntry hce =
502  mutt_hcache_fetch(mdata->hcache, key, mutt_str_len(key), mdata->uidvalidity);
503  if (!hce.email && hce.uidvalidity)
504  {
505  mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
506  }
507 
508  return hce.email;
509 }
510 
518 int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
519 {
520  if (!mdata->hcache)
521  return -1;
522 
523  char key[16];
524 
525  sprintf(key, "/%u", imap_edata_get(e)->uid);
526  return mutt_hcache_store(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
527 }
528 
536 int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
537 {
538  if (!mdata->hcache)
539  return -1;
540 
541  char key[16];
542 
543  sprintf(key, "/%u", uid);
544  return mutt_hcache_delete_header(mdata->hcache, key, mutt_str_len(key));
545 }
546 
554 {
555  if (!mdata->hcache)
556  return -1;
557 
558  /* The seqset is likely large. Preallocate to reduce reallocs */
559  struct Buffer buf = mutt_buffer_make(8192);
560  imap_msn_index_to_uid_seqset(&buf, mdata);
561 
562  int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
563  mutt_buffer_len(&buf) + 1);
564  mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
565  mutt_buffer_dealloc(&buf);
566  return rc;
567 }
568 
576 {
577  if (!mdata->hcache)
578  return -1;
579 
580  return mutt_hcache_delete_header(mdata->hcache, "/UIDSEQSET", 10);
581 }
582 
590 {
591  if (!mdata->hcache)
592  return NULL;
593 
594  char *seqset = NULL;
595  size_t dlen = 0;
596  char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10, &dlen);
597  if (hc_seqset)
598  {
599  seqset = strndup(hc_seqset, dlen);
600  mutt_hcache_free_raw(mdata->hcache, (void **) &hc_seqset);
601  }
602  mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
603 
604  return seqset;
605 }
606 #endif
607 
620 int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
621 {
622  static unsigned short ImapPort = 0;
623  static unsigned short ImapsPort = 0;
624 
625  if (ImapPort == 0)
626  {
627  struct servent *service = getservbyname("imap", "tcp");
628  if (service)
629  ImapPort = ntohs(service->s_port);
630  else
631  ImapPort = IMAP_PORT;
632  mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
633  }
634 
635  if (ImapsPort == 0)
636  {
637  struct servent *service = getservbyname("imaps", "tcp");
638  if (service)
639  ImapsPort = ntohs(service->s_port);
640  else
641  ImapsPort = IMAP_SSL_PORT;
642  mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
643  }
644 
645  /* Defaults */
646  cac->port = ImapPort;
647  cac->type = MUTT_ACCT_TYPE_IMAP;
648  cac->service = "imap";
649  cac->get_field = imap_get_field;
650 
651  struct Url *url = url_parse(path);
652  if (!url)
653  return -1;
654 
655  if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
656  {
657  url_free(&url);
658  return -1;
659  }
660 
661  if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
662  {
663  url_free(&url);
664  return -1;
665  }
666 
667  if (url->scheme == U_IMAPS)
668  cac->flags |= MUTT_ACCT_SSL;
669 
670  mutt_str_copy(mailbox, url->path, mailboxlen);
671 
672  url_free(&url);
673 
674  if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
675  cac->port = ImapsPort;
676 
677  return 0;
678 }
679 
691 int imap_mxcmp(const char *mx1, const char *mx2)
692 {
693  char *b1 = NULL;
694  char *b2 = NULL;
695  int rc;
696 
697  if (!mx1 || (*mx1 == '\0'))
698  mx1 = "INBOX";
699  if (!mx2 || (*mx2 == '\0'))
700  mx2 = "INBOX";
701  if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
702  {
703  return 0;
704  }
705 
706  b1 = mutt_mem_malloc(strlen(mx1) + 1);
707  b2 = mutt_mem_malloc(strlen(mx2) + 1);
708 
709  imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
710  imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
711 
712  rc = mutt_str_cmp(b1, b2);
713  FREE(&b1);
714  FREE(&b2);
715 
716  return rc;
717 }
718 
727 void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
728 {
729  struct ConnAccount cac_target = { { 0 } };
730  struct ConnAccount cac_home = { { 0 } };
731  struct Url url = { 0 };
732  char *delim = NULL;
733  int tlen;
734  int hlen = 0;
735  bool home_match = false;
736  char target_mailbox[1024];
737  char home_mailbox[1024];
738 
739  if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
740  return;
741 
742  if (imap_path_probe(folder, NULL) != MUTT_IMAP)
743  goto fallback;
744 
745  if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
746  goto fallback;
747 
748  tlen = mutt_str_len(target_mailbox);
749  hlen = mutt_str_len(home_mailbox);
750 
751  /* check whether we can do '+' substitution */
752  if (tlen && imap_account_match(&cac_home, &cac_target) &&
753  mutt_strn_equal(home_mailbox, target_mailbox, hlen))
754  {
755  if (hlen == 0)
756  home_match = true;
757  else if (C_ImapDelimChars)
758  {
759  for (delim = C_ImapDelimChars; *delim != '\0'; delim++)
760  if (target_mailbox[hlen] == *delim)
761  home_match = true;
762  }
763  }
764 
765  /* do the '+' substitution */
766  if (home_match)
767  {
768  *path++ = '+';
769  /* copy remaining path, skipping delimiter */
770  if (hlen == 0)
771  hlen = -1;
772  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
773  path[tlen - hlen - 1] = '\0';
774  return;
775  }
776 
777 fallback:
778  mutt_account_tourl(&cac_target, &url);
779  url.path = target_mailbox;
780  url_tostring(&url, path, pathlen, 0);
781 }
782 
789 enum QuadOption imap_continue(const char *msg, const char *resp)
790 {
791  imap_error(msg, resp);
792  return mutt_yesorno(_("Continue?"), MUTT_NO);
793 }
794 
800 void imap_error(const char *where, const char *msg)
801 {
802  mutt_error("%s [%s]", where, msg);
803 }
804 
822 char *imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
823 {
824  int i = 0;
825  for (; mailbox && *mailbox && (i < plen - 1); i++)
826  {
827  if (*mailbox == delim || (!delim && strchr(NONULL(C_ImapDelimChars), *mailbox)))
828  {
829  delim = *mailbox;
830  /* Skip multiple occurrences of delim */
831  while (*mailbox && *(mailbox + 1) == delim)
832  mailbox++;
833  }
834  path[i] = *mailbox++;
835  }
836 
837  /* Do not terminate with a delimiter */
838  if (i && path[i - 1] == delim)
839  i--;
840 
841  /* Ensure null termination */
842  path[i] = '\0';
843  return path;
844 }
845 
852 void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
853 {
854  const char *p = mailbox;
855  mutt_buffer_reset(dest);
856  if (!p)
857  return;
858 
859  while (*p)
860  {
861  if (p[0] == delim)
862  {
863  mutt_buffer_addch(dest, '/');
864  /* simple way to avoid collisions with UIDs */
865  if ((p[1] >= '0') && (p[1] <= '9'))
866  mutt_buffer_addch(dest, '_');
867  }
868  else
869  mutt_buffer_addch(dest, *p);
870  p++;
871  }
872 }
873 
881 int imap_get_literal_count(const char *buf, unsigned int *bytes)
882 {
883  char *pc = NULL;
884  char *pn = NULL;
885 
886  if (!buf || !(pc = strchr(buf, '{')))
887  return -1;
888 
889  pc++;
890  pn = pc;
891  while (isdigit((unsigned char) *pc))
892  pc++;
893  *pc = '\0';
894  if (mutt_str_atoui(pn, bytes) < 0)
895  return -1;
896 
897  return 0;
898 }
899 
908 char *imap_get_qualifier(char *buf)
909 {
910  char *s = buf;
911 
912  /* skip tag */
913  s = imap_next_word(s);
914  /* skip OK/NO/BAD response */
915  s = imap_next_word(s);
916 
917  return s;
918 }
919 
925 char *imap_next_word(char *s)
926 {
927  bool quoted = false;
928 
929  while (*s)
930  {
931  if (*s == '\\')
932  {
933  s++;
934  if (*s)
935  s++;
936  continue;
937  }
938  if (*s == '\"')
939  quoted = !quoted;
940  if (!quoted && IS_SPACE(*s))
941  break;
942  s++;
943  }
944 
945  SKIPWS(s);
946  return s;
947 }
948 
956 void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
957 {
958  struct Url url = { 0 };
959  mutt_account_tourl(cac, &url);
960  url.path = path;
961  url_tostring(&url, buf, buflen, 0);
962 }
963 
973 void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
974 {
975  const char *quote = "`\"\\";
976  if (!quote_backtick)
977  quote++;
978 
979  char *pt = dest;
980  const char *s = src;
981 
982  *pt++ = '"';
983  /* save room for quote-chars */
984  dlen -= 3;
985 
986  for (; *s && dlen; s++)
987  {
988  if (strchr(quote, *s))
989  {
990  if (dlen < 2)
991  break;
992  dlen -= 2;
993  *pt++ = '\\';
994  *pt++ = *s;
995  }
996  else
997  {
998  *pt++ = *s;
999  dlen--;
1000  }
1001  }
1002  *pt++ = '"';
1003  *pt = '\0';
1004 }
1005 
1010 void imap_unquote_string(char *s)
1011 {
1012  char *d = s;
1013 
1014  if (*s == '\"')
1015  s++;
1016  else
1017  return;
1018 
1019  while (*s)
1020  {
1021  if (*s == '\"')
1022  {
1023  *d = '\0';
1024  return;
1025  }
1026  if (*s == '\\')
1027  {
1028  s++;
1029  }
1030  if (*s)
1031  {
1032  *d = *s;
1033  d++;
1034  s++;
1035  }
1036  }
1037  *d = '\0';
1038 }
1039 
1047 void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
1048 {
1049  char *buf = mutt_str_dup(src);
1050  imap_utf_encode(unicode, &buf);
1051 
1052  imap_quote_string(dest, dlen, buf, false);
1053 
1054  FREE(&buf);
1055 }
1056 
1064 void imap_unmunge_mbox_name(bool unicode, char *s)
1065 {
1067 
1068  char *buf = mutt_str_dup(s);
1069  if (buf)
1070  {
1071  imap_utf_decode(unicode, &buf);
1072  strncpy(s, buf, strlen(s));
1073  }
1074 
1075  FREE(&buf);
1076 }
1077 
1081 void imap_keepalive(void)
1082 {
1083  time_t now = mutt_date_epoch();
1084  struct Account *np = NULL;
1085  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1086  {
1087  if (np->type != MUTT_IMAP)
1088  continue;
1089 
1090  struct ImapAccountData *adata = np->adata;
1091  if (!adata || !adata->mailbox)
1092  continue;
1093 
1094  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + C_ImapKeepalive)))
1095  imap_check_mailbox(adata->mailbox, true);
1096  }
1097 }
1098 
1104 int imap_wait_keepalive(pid_t pid)
1105 {
1106  struct sigaction oldalrm;
1107  struct sigaction act;
1108  sigset_t oldmask;
1109  int rc;
1110 
1111  bool imap_passive = C_ImapPassive;
1112 
1113  C_ImapPassive = true;
1114  OptKeepQuiet = true;
1115 
1116  sigprocmask(SIG_SETMASK, NULL, &oldmask);
1117 
1118  sigemptyset(&act.sa_mask);
1119  act.sa_handler = mutt_sig_empty_handler;
1120 #ifdef SA_INTERRUPT
1121  act.sa_flags = SA_INTERRUPT;
1122 #else
1123  act.sa_flags = 0;
1124 #endif
1125 
1126  sigaction(SIGALRM, &act, &oldalrm);
1127 
1128  alarm(C_ImapKeepalive);
1129  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1130  {
1131  alarm(0); /* cancel a possibly pending alarm */
1132  imap_keepalive();
1133  alarm(C_ImapKeepalive);
1134  }
1135 
1136  alarm(0); /* cancel a possibly pending alarm */
1137 
1138  sigaction(SIGALRM, &oldalrm, NULL);
1139  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1140 
1141  OptKeepQuiet = false;
1142  if (!imap_passive)
1143  C_ImapPassive = false;
1144 
1145  return rc;
1146 }
1147 
1153 {
1154  struct ImapAccountData *adata = imap_adata_get(m);
1155  struct ImapMboxData *mdata = imap_mdata_get(m);
1156  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1157  return;
1158  mdata->reopen |= IMAP_REOPEN_ALLOW;
1159 }
1160 
1166 {
1167  struct ImapAccountData *adata = imap_adata_get(m);
1168  struct ImapMboxData *mdata = imap_mdata_get(m);
1169  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1170  return;
1171  mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1172 }
1173 
1180 bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
1181 {
1182  if (!a1 || !a2)
1183  return false;
1184  if (a1->type != a2->type)
1185  return false;
1186  if (!mutt_istr_equal(a1->host, a2->host))
1187  return false;
1188  if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1189  return false;
1190  if (a1->flags & a2->flags & MUTT_ACCT_USER)
1191  return strcmp(a1->user, a2->user) == 0;
1192 
1193  const char *user = NONULL(Username);
1194 
1195  if ((a1->type == MUTT_ACCT_TYPE_IMAP) && C_ImapUser)
1196  user = C_ImapUser;
1197 
1198  if (a1->flags & MUTT_ACCT_USER)
1199  return strcmp(a1->user, user) == 0;
1200  if (a2->flags & MUTT_ACCT_USER)
1201  return strcmp(a2->user, user) == 0;
1202 
1203  return true;
1204 }
1205 
1211 struct SeqsetIterator *mutt_seqset_iterator_new(const char *seqset)
1212 {
1213  if (!seqset || (*seqset == '\0'))
1214  return NULL;
1215 
1216  struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1217  iter->full_seqset = mutt_str_dup(seqset);
1218  iter->eostr = strchr(iter->full_seqset, '\0');
1219  iter->substr_cur = iter->substr_end = iter->full_seqset;
1220 
1221  return iter;
1222 }
1223 
1232 int mutt_seqset_iterator_next(struct SeqsetIterator *iter, unsigned int *next)
1233 {
1234  if (!iter || !next)
1235  return -1;
1236 
1237  if (iter->in_range)
1238  {
1239  if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1240  (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1241  {
1242  iter->in_range = 0;
1243  }
1244  }
1245 
1246  if (!iter->in_range)
1247  {
1248  iter->substr_cur = iter->substr_end;
1249  if (iter->substr_cur == iter->eostr)
1250  return 1;
1251 
1252  while (!*(iter->substr_cur))
1253  iter->substr_cur++;
1254  iter->substr_end = strchr(iter->substr_cur, ',');
1255  if (!iter->substr_end)
1256  iter->substr_end = iter->eostr;
1257  else
1258  *(iter->substr_end) = '\0';
1259 
1260  char *range_sep = strchr(iter->substr_cur, ':');
1261  if (range_sep)
1262  *range_sep++ = '\0';
1263 
1264  if (mutt_str_atoui(iter->substr_cur, &iter->range_cur) != 0)
1265  return -1;
1266  if (range_sep)
1267  {
1268  if (mutt_str_atoui(range_sep, &iter->range_end) != 0)
1269  return -1;
1270  }
1271  else
1272  iter->range_end = iter->range_cur;
1273 
1274  iter->down = (iter->range_end < iter->range_cur);
1275  iter->in_range = 1;
1276  }
1277 
1278  *next = iter->range_cur;
1279  if (iter->down)
1280  iter->range_cur--;
1281  else
1282  iter->range_cur++;
1283 
1284  return 0;
1285 }
1286 
1292 {
1293  if (!ptr || !*ptr)
1294  return;
1295 
1296  struct SeqsetIterator *iter = *ptr;
1297  FREE(&iter->full_seqset);
1298  FREE(ptr);
1299 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:876
Convenience wrapper for the gui headers.
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:414
char * eostr
Definition: private.h:251
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:572
int mutt_account_fromurl(struct ConnAccount *cac, const struct Url *url)
Fill ConnAccount with information from url.
Definition: mutt_account.c:43
struct ImapEmailData * imap_edata_get(struct Email *e)
Get the private data for this Email.
Definition: message.c:97
struct ImapCommand * cmds
Definition: private.h:199
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
void imap_unquote_string(char *s)
equally stupid unquoting routine
Definition: util.c:1010
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:727
IMAP network mailbox.
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
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:427
struct Email ** msn_index
look up headers by (MSN-1)
Definition: private.h:237
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2344
Wrapper for Email retrieved from the header cache.
Definition: lib.h:98
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
uint32_t uidvalidity
Definition: private.h:228
Structs that make up an email.
Connection is authenticated.
Definition: private.h:108
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:45
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:447
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
void imap_hcache_close(struct ImapMboxData *mdata)
Close the header cache.
Definition: util.c:477
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:44
void mutt_sig_empty_handler(int sig)
Dummy signal handler.
Definition: signal.c:57
void imap_get_parent_path(const char *path, char *buf, size_t buflen)
Get the path of the parent folder.
Definition: util.c:302
enum UrlScheme scheme
Scheme, e.g. U_SMTPS.
Definition: url.h:68
#define IMAP_REOPEN_ALLOW
Allow re-opening a folder upon expunge.
Definition: private.h:65
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void imap_mdata_free(void **ptr)
Release and clear storage in an ImapMboxData structure.
Definition: util.c:228
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:37
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:174
struct Email * imap_hcache_get(struct ImapMboxData *mdata, unsigned int uid)
Get a header cache entry by its UID.
Definition: util.c:493
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
uint32_t uidvalidity
IMAP-specific UIDVALIDITY.
Definition: lib.h:100
Url is imaps://.
Definition: url.h:39
size_t msn_index_size
allocation size
Definition: private.h:238
void imap_utf_decode(bool unicode, char **s)
Decode email from UTF-8 to local charset.
Definition: utf7.c:345
ImapOpenFlags reopen
Flags, e.g. IMAP_REOPEN_ALLOW.
Definition: private.h:222
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
A group of associated Mailboxes.
Definition: account.h:36
struct HCacheEntry mutt_hcache_fetch(header_cache_t *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition: hcache.c:437
String manipulation buffer.
Definition: buffer.h:33
void * mutt_hcache_fetch_raw(header_cache_t *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:495
char user[128]
Username.
Definition: connaccount.h:55
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:206
char * C_ImapOauthRefreshCommand
Config: (imap) External command to generate OAUTH refresh token.
Definition: config.c:49
char * capstr
Definition: private.h:184
Url is imap://.
Definition: url.h:38
Password.
Definition: connaccount.h:36
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:329
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:822
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
int mutt_hcache_store_raw(header_cache_t *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:582
ConnAccountField
Login credentials.
Definition: connaccount.h:31
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
int imap_adata_find(const char *path, struct ImapAccountData **adata, struct ImapMboxData **mdata)
Find the Account data for this path.
Definition: util.c:129
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:345
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_ACCT_USER
User field has been set.
Definition: connaccount.h:43
void imap_unmunge_mbox_name(bool unicode, char *s)
Remove quoting from a mailbox name.
Definition: util.c:1064
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:800
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
unsigned int max_msn
the largest MSN fetched so far
Definition: private.h:239
Convenience wrapper for the config headers.
void mutt_account_tourl(struct ConnAccount *cac, struct Url *url)
Fill URL with info from account.
Definition: mutt_account.c:79
void mutt_hcache_close(header_cache_t *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:418
unsigned char seqid
tag sequence prefix
Definition: private.h:186
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder&#39;s parent.
Definition: util.c:261
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:247
struct BodyCache * bcache
Definition: private.h:240
char host[128]
Server to login to.
Definition: connaccount.h:53
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:53
Manage IMAP messages.
header_cache_t * hcache
Definition: private.h:242
int mutt_hcache_store(header_cache_t *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:525
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:620
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:377
Header cache multiplexor.
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:852
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: config.c:42
#define STAILQ_INIT(head)
Definition: queue.h:369
void imap_allow_reopen(struct Mailbox *m)
Allow re-opening a folder upon expunge.
Definition: util.c:1152
int imap_hcache_store_uid_seqset(struct ImapMboxData *mdata)
Store a UID Sequence Set in the header cache.
Definition: util.c:553
unsigned int range_end
Definition: private.h:255
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:536
struct Buffer cmdbuf
Definition: private.h:203
Convenience wrapper for the core headers.
#define SKIPWS(ch)
Definition: string2.h:46
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
char * C_ImapUser
Config: (imap) Username for the IMAP server.
Definition: config.c:58
int mutt_buffer_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition: buffer.c:203
Shared constants/structs that are private to IMAP.
void * mdata
Driver specific data.
Definition: mailbox.h:136
header_cache_t * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:321
unsigned long long modseq
Definition: private.h:230
Body Caching - local copies of email bodies.
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1104
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
struct HashTable * uid_hash
Definition: private.h:236
#define mutt_b2s(buf)
Definition: buffer.h:41
unsigned short port
Port to connect to.
Definition: connaccount.h:57
void imap_adata_free(void **ptr)
Release and clear storage in an ImapAccountData structure.
Definition: util.c:66
void imap_utf_encode(bool unicode, char **s)
Encode email from local charset to UTF-8.
Definition: utf7.c:316
void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
Open a header cache.
Definition: util.c:437
int mutt_hcache_delete_header(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_header.
Definition: hcache.c:602
int(* close)(struct Connection *conn)
Close a socket Connection.
Definition: connection.h:100
bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
Compare two Accounts.
Definition: util.c:1180
const char *(* get_field)(enum ConnAccountField field, void *gf_data)
Function to get some login credentials.
Definition: connaccount.h:67
bool C_ImapPassive
Config: (imap) Reuse an existing IMAP connection to check for new mail.
Definition: config.c:51
struct Account * account
Parent Account.
Definition: private.h:208
#define MUTT_ACCT_PORT
Port field has been set.
Definition: connaccount.h:42
ConnAccount object used by POP and IMAP.
unsigned int uid
32-bit Message UID
Definition: message.h:44
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
A mailbox.
Definition: mailbox.h:81
void imap_disallow_reopen(struct Mailbox *m)
Disallow re-opening a folder upon expunge.
Definition: util.c:1165
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
struct ListHead flags
Definition: private.h:227
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
short C_ImapPipelineDepth
Config: (imap) Number of IMAP commands that may be queued up.
Definition: config.c:53
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
User name.
Definition: connaccount.h:35
char * data
Pointer to data.
Definition: buffer.h:35
void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
quote string according to IMAP rules
Definition: util.c:973
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
char * name
Mailbox name.
Definition: private.h:218
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:287
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:908
struct ImapMboxData * imap_mdata_new(struct ImapAccountData *adata, const char *name)
Allocate and initialise a new ImapMboxData structure.
Definition: util.c:165
char * imap_hcache_get_uid_seqset(struct ImapMboxData *mdata)
Get a UID Sequence Set from the header cache.
Definition: util.c:589
const char * service
Name of the service, e.g. "imap".
Definition: connaccount.h:60
OAuth refresh command.
Definition: connaccount.h:37
void imap_mdata_cache_reset(struct ImapMboxData *mdata)
Release and clear cache data of ImapMboxData structure.
Definition: util.c:215
time_t lastread
last time we read a command for the server
Definition: private.h:188
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
Login details for a remote server.
Definition: connaccount.h:51
Imap Account.
Definition: mutt_account.h:37
char * path
Path.
Definition: url.h:73
char * real_name
Original Mailbox name, e.g.: INBOX can be just \0.
Definition: private.h:220
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:46
bool mutt_strn_equal(const char *a, const char *b, size_t l)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:598
char * substr_cur
Definition: private.h:256
#define IS_SPACE(ch)
Definition: string2.h:38
int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
Add an entry to the header cache.
Definition: util.c:518
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1061
int imap_get_literal_count(const char *buf, unsigned int *bytes)
write number of bytes in an IMAP literal into bytes
Definition: util.c:881
IMAP-specific Account data -.
Definition: private.h:169
unsigned int uid_next
Definition: private.h:229
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
int n
Definition: acutest.h:492
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:691
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:721
IMAP-specific Mailbox data -.
Definition: private.h:216
char * buf
Definition: private.h:189
int imap_hcache_clear_uid_seqset(struct ImapMboxData *mdata)
Delete a UID Sequence Set from the header cache.
Definition: util.c:575
void mutt_hcache_free_raw(header_cache_t *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:512
#define mutt_error(...)
Definition: logging.h:84
struct SeqsetIterator * mutt_seqset_iterator_new(const char *seqset)
Create a new Sequence Set Iterator.
Definition: util.c:1211
Connection Library.
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
#define FREE(x)
Definition: memory.h:40
int url_tostring(struct Url *url, char *dest, size_t len, int flags)
Output the URL string for a given Url object.
Definition: url.c:418
struct ImapAccountData * imap_adata_new(struct Account *a)
Allocate and initialise a new ImapAccountData structure.
Definition: util.c:92
void imap_keepalive(void)
poll the current folder to keep the connection alive
Definition: util.c:1081
void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
Quote awkward characters in a mailbox name.
Definition: util.c:1047
int mutt_seqset_iterator_next(struct SeqsetIterator *iter, unsigned int *next)
Get the next UID from a Sequence Set.
Definition: util.c:1232
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:956
Hundreds of global variables to back the user variables.
Handling of global boolean variables.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
enum QuadOption imap_continue(const char *msg, const char *resp)
display a message and ask the user if they want to go on
Definition: util.c:789
struct Email * email
Retrieved email.
Definition: lib.h:102
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:372
Login name.
Definition: connaccount.h:34
header cache structure
Definition: lib.h:85
void mutt_seqset_iterator_free(struct SeqsetIterator **ptr)
Free a Sequence Set Iterator.
Definition: util.c:1291
Convenience wrapper for the library headers.
char * substr_end
Definition: private.h:257
WHERE bool OptKeepQuiet
(pseudo) shut up the message and refresh functions while we are executing an external program ...
Definition: options.h:39
char * munge_name
Munged version of the mailbox name.
Definition: private.h:219
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
char * full_seqset
Definition: private.h:250
char * C_ImapPass
Config: (imap) Password for the IMAP server.
Definition: config.c:50
unsigned int range_cur
Definition: private.h:254
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:157
Log at debug level 3.
Definition: logging.h:42
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
int url_tobuffer(struct Url *url, struct Buffer *buf, int flags)
Output the URL string for a given Url object.
Definition: url.c:353
char * src
Raw URL string.
Definition: url.h:75
#define MUTT_ACCT_SSL
Account uses SSL/TLS.
Definition: connaccount.h:46
bool unicode
If true, we can send UTF-8, and the server will use UTF8 rather than mUTF7.
Definition: private.h:192
UID Sequence Set Iterator.
Definition: private.h:248
#define U_PATH
Definition: url.h:48
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:925
Server name.
Definition: connaccount.h:33
char * C_ImapLogin
Config: (imap) Login name for the IMAP server (defaults to C_ImapUser)
Definition: config.c:48
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Connection * conn
Definition: private.h:171
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234