NeoMutt  2020-11-20
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 "bcache/lib.h"
53 #include "imap/lib.h"
54 #include "msn.h"
55 #include "mutt_account.h"
56 #include "mutt_globals.h"
57 #include "options.h"
58 #ifdef USE_HCACHE
59 #include "hcache/lib.h"
60 #include "message.h"
61 #endif
62 
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  imap_msn_free(&mdata->msn);
219  mutt_bcache_close(&mdata->bcache);
220 }
221 
225 void imap_mdata_free(void **ptr)
226 {
227  if (!ptr || !*ptr)
228  return;
229 
230  struct ImapMboxData *mdata = *ptr;
231 
232  imap_mdata_cache_reset(mdata);
233  mutt_list_free(&mdata->flags);
234  FREE(&mdata->name);
235  FREE(&mdata->real_name);
236  FREE(&mdata->munge_name);
237  FREE(ptr);
238 }
239 
245 {
246  if (!m || (m->type != MUTT_IMAP) || !m->mdata)
247  return NULL;
248  return m->mdata;
249 }
250 
258 void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
259 {
260  /* Make a copy of the mailbox name, but only if the pointers are different */
261  if (mbox != buf)
262  mutt_str_copy(buf, mbox, buflen);
263 
264  int n = mutt_str_len(buf);
265 
266  /* Let's go backwards until the next delimiter
267  *
268  * If buf[n] is a '/', the first n-- will allow us
269  * to ignore it. If it isn't, then buf looks like
270  * "/aaaaa/bbbb". There is at least one "b", so we can't skip
271  * the "/" after the 'a's.
272  *
273  * If buf == '/', then n-- => n == 0, so the loop ends
274  * immediately */
275  for (n--; (n >= 0) && (buf[n] != delim); n--)
276  ; // do nothing
277 
278  /* We stopped before the beginning. There is a trailing slash. */
279  if (n > 0)
280  {
281  /* Strip the trailing delimiter. */
282  buf[n] = '\0';
283  }
284  else
285  {
286  buf[0] = (n == 0) ? delim : '\0';
287  }
288 }
289 
299 void imap_get_parent_path(const char *path, char *buf, size_t buflen)
300 {
301  struct ImapAccountData *adata = NULL;
302  struct ImapMboxData *mdata = NULL;
303  char mbox[1024];
304 
305  if (imap_adata_find(path, &adata, &mdata) < 0)
306  {
307  mutt_str_copy(buf, path, buflen);
308  return;
309  }
310 
311  /* Gets the parent mbox in mbox */
312  imap_get_parent(mdata->name, adata->delim, mbox, sizeof(mbox));
313 
314  /* Returns a fully qualified IMAP url */
315  imap_qualify_path(buf, buflen, &adata->conn->account, mbox);
316  imap_mdata_free((void *) &mdata);
317 }
318 
326 void imap_clean_path(char *path, size_t plen)
327 {
328  struct ImapAccountData *adata = NULL;
329  struct ImapMboxData *mdata = NULL;
330 
331  if (imap_adata_find(path, &adata, &mdata) < 0)
332  return;
333 
334  /* Returns a fully qualified IMAP url */
335  imap_qualify_path(path, plen, &adata->conn->account, mdata->name);
336  imap_mdata_free((void *) &mdata);
337 }
338 
342 static const char *imap_get_field(enum ConnAccountField field, void *gf_data)
343 {
344  switch (field)
345  {
346  case MUTT_CA_LOGIN:
347  return C_ImapLogin;
348  case MUTT_CA_USER:
349  return C_ImapUser;
350  case MUTT_CA_PASS:
351  return C_ImapPass;
352  case MUTT_CA_OAUTH_CMD:
354  case MUTT_CA_HOST:
355  default:
356  return NULL;
357  }
358 }
359 
360 #ifdef USE_HCACHE
361 
369 static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
370 {
371  int first = 1, state = 0;
372  unsigned int cur_uid = 0, last_uid = 0;
373  unsigned int range_begin = 0, range_end = 0;
374  const size_t max_msn = imap_msn_highest(&mdata->msn);
375 
376  for (unsigned int msn = 1; msn <= max_msn + 1; msn++)
377  {
378  bool match = false;
379  if (msn <= max_msn)
380  {
381  struct Email *e_cur = imap_msn_get(&mdata->msn, msn - 1);
382  cur_uid = e_cur ? imap_edata_get(e_cur)->uid : 0;
383  if (!state || (cur_uid && ((cur_uid - 1) == last_uid)))
384  match = true;
385  last_uid = cur_uid;
386  }
387 
388  if (match)
389  {
390  switch (state)
391  {
392  case 1: /* single: convert to a range */
393  state = 2;
394  /* fall through */
395  case 2: /* extend range ending */
396  range_end = cur_uid;
397  break;
398  default:
399  state = 1;
400  range_begin = cur_uid;
401  break;
402  }
403  }
404  else if (state)
405  {
406  if (first)
407  first = 0;
408  else
409  mutt_buffer_addch(buf, ',');
410 
411  if (state == 1)
412  mutt_buffer_add_printf(buf, "%u", range_begin);
413  else if (state == 2)
414  mutt_buffer_add_printf(buf, "%u:%u", range_begin, range_end);
415 
416  state = 1;
417  range_begin = cur_uid;
418  }
419  }
420 }
421 
425 static void imap_hcache_namer(const char *path, struct Buffer *dest)
426 {
427  mutt_buffer_printf(dest, "%s.hcache", path);
428 }
429 
435 void imap_hcache_open(struct ImapAccountData *adata, struct ImapMboxData *mdata)
436 {
437  if (!adata || !mdata)
438  return;
439 
440  if (mdata->hcache)
441  return;
442 
443  struct HeaderCache *hc = NULL;
444  struct Buffer *mbox = mutt_buffer_pool_get();
445  struct Buffer *cachepath = mutt_buffer_pool_get();
446 
447  imap_cachepath(adata->delim, mdata->name, mbox);
448 
449  if (strstr(mutt_b2s(mbox), "/../") || mutt_str_equal(mutt_b2s(mbox), "..") ||
450  mutt_strn_equal(mutt_b2s(mbox), "../", 3))
451  {
452  goto cleanup;
453  }
454  size_t len = mutt_buffer_len(mbox);
455  if ((len > 3) && (strcmp(mutt_b2s(mbox) + len - 3, "/..") == 0))
456  goto cleanup;
457 
458  struct Url url = { 0 };
459  mutt_account_tourl(&adata->conn->account, &url);
460  url.path = mbox->data;
461  url_tobuffer(&url, cachepath, U_PATH);
462 
464 
465 cleanup:
467  mutt_buffer_pool_release(&cachepath);
468  mdata->hcache = hc;
469 }
470 
475 void imap_hcache_close(struct ImapMboxData *mdata)
476 {
477  if (!mdata->hcache)
478  return;
479 
480  mutt_hcache_close(mdata->hcache);
481  mdata->hcache = NULL;
482 }
483 
491 struct Email *imap_hcache_get(struct ImapMboxData *mdata, unsigned int uid)
492 {
493  if (!mdata->hcache)
494  return NULL;
495 
496  char key[16];
497 
498  sprintf(key, "/%u", uid);
499  struct HCacheEntry hce =
500  mutt_hcache_fetch(mdata->hcache, key, mutt_str_len(key), mdata->uidvalidity);
501  if (!hce.email && hce.uidvalidity)
502  {
503  mutt_debug(LL_DEBUG3, "hcache uidvalidity mismatch: %u\n", hce.uidvalidity);
504  }
505 
506  return hce.email;
507 }
508 
516 int imap_hcache_put(struct ImapMboxData *mdata, struct Email *e)
517 {
518  if (!mdata->hcache)
519  return -1;
520 
521  char key[16];
522 
523  sprintf(key, "/%u", imap_edata_get(e)->uid);
524  return mutt_hcache_store(mdata->hcache, key, mutt_str_len(key), e, mdata->uidvalidity);
525 }
526 
534 int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
535 {
536  if (!mdata->hcache)
537  return -1;
538 
539  char key[16];
540 
541  sprintf(key, "/%u", uid);
542  return mutt_hcache_delete_record(mdata->hcache, key, mutt_str_len(key));
543 }
544 
552 {
553  if (!mdata->hcache)
554  return -1;
555 
556  /* The seqset is likely large. Preallocate to reduce reallocs */
557  struct Buffer buf = mutt_buffer_make(8192);
558  imap_msn_index_to_uid_seqset(&buf, mdata);
559 
560  int rc = mutt_hcache_store_raw(mdata->hcache, "/UIDSEQSET", 10, buf.data,
561  mutt_buffer_len(&buf) + 1);
562  mutt_debug(LL_DEBUG3, "Stored /UIDSEQSET %s\n", buf.data);
563  mutt_buffer_dealloc(&buf);
564  return rc;
565 }
566 
574 {
575  if (!mdata->hcache)
576  return -1;
577 
578  return mutt_hcache_delete_record(mdata->hcache, "/UIDSEQSET", 10);
579 }
580 
588 {
589  if (!mdata->hcache)
590  return NULL;
591 
592  char *seqset = NULL;
593  size_t dlen = 0;
594  char *hc_seqset = mutt_hcache_fetch_raw(mdata->hcache, "/UIDSEQSET", 10, &dlen);
595  if (hc_seqset)
596  {
597  seqset = mutt_strn_dup(hc_seqset, dlen);
598  mutt_hcache_free_raw(mdata->hcache, (void **) &hc_seqset);
599  }
600  mutt_debug(LL_DEBUG3, "Retrieved /UIDSEQSET %s\n", NONULL(seqset));
601 
602  return seqset;
603 }
604 #endif
605 
618 int imap_parse_path(const char *path, struct ConnAccount *cac, char *mailbox, size_t mailboxlen)
619 {
620  static unsigned short ImapPort = 0;
621  static unsigned short ImapsPort = 0;
622 
623  if (ImapPort == 0)
624  {
625  struct servent *service = getservbyname("imap", "tcp");
626  if (service)
627  ImapPort = ntohs(service->s_port);
628  else
629  ImapPort = IMAP_PORT;
630  mutt_debug(LL_DEBUG3, "Using default IMAP port %d\n", ImapPort);
631  }
632 
633  if (ImapsPort == 0)
634  {
635  struct servent *service = getservbyname("imaps", "tcp");
636  if (service)
637  ImapsPort = ntohs(service->s_port);
638  else
639  ImapsPort = IMAP_SSL_PORT;
640  mutt_debug(LL_DEBUG3, "Using default IMAPS port %d\n", ImapsPort);
641  }
642 
643  /* Defaults */
644  cac->port = ImapPort;
645  cac->type = MUTT_ACCT_TYPE_IMAP;
646  cac->service = "imap";
647  cac->get_field = imap_get_field;
648 
649  struct Url *url = url_parse(path);
650  if (!url)
651  return -1;
652 
653  if ((url->scheme != U_IMAP) && (url->scheme != U_IMAPS))
654  {
655  url_free(&url);
656  return -1;
657  }
658 
659  if ((mutt_account_fromurl(cac, url) < 0) || (cac->host[0] == '\0'))
660  {
661  url_free(&url);
662  return -1;
663  }
664 
665  if (url->scheme == U_IMAPS)
666  cac->flags |= MUTT_ACCT_SSL;
667 
668  mutt_str_copy(mailbox, url->path, mailboxlen);
669 
670  url_free(&url);
671 
672  if ((cac->flags & MUTT_ACCT_SSL) && !(cac->flags & MUTT_ACCT_PORT))
673  cac->port = ImapsPort;
674 
675  return 0;
676 }
677 
689 int imap_mxcmp(const char *mx1, const char *mx2)
690 {
691  char *b1 = NULL;
692  char *b2 = NULL;
693  int rc;
694 
695  if (!mx1 || (*mx1 == '\0'))
696  mx1 = "INBOX";
697  if (!mx2 || (*mx2 == '\0'))
698  mx2 = "INBOX";
699  if (mutt_istr_equal(mx1, "INBOX") && mutt_istr_equal(mx2, "INBOX"))
700  {
701  return 0;
702  }
703 
704  b1 = mutt_mem_malloc(strlen(mx1) + 1);
705  b2 = mutt_mem_malloc(strlen(mx2) + 1);
706 
707  imap_fix_path('\0', mx1, b1, strlen(mx1) + 1);
708  imap_fix_path('\0', mx2, b2, strlen(mx2) + 1);
709 
710  rc = mutt_str_cmp(b1, b2);
711  FREE(&b1);
712  FREE(&b2);
713 
714  return rc;
715 }
716 
725 void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
726 {
727  struct ConnAccount cac_target = { { 0 } };
728  struct ConnAccount cac_home = { { 0 } };
729  struct Url url = { 0 };
730  char *delim = NULL;
731  int tlen;
732  int hlen = 0;
733  bool home_match = false;
734  char target_mailbox[1024];
735  char home_mailbox[1024];
736 
737  if (imap_parse_path(path, &cac_target, target_mailbox, sizeof(target_mailbox)) < 0)
738  return;
739 
740  if (imap_path_probe(folder, NULL) != MUTT_IMAP)
741  goto fallback;
742 
743  if (imap_parse_path(folder, &cac_home, home_mailbox, sizeof(home_mailbox)) < 0)
744  goto fallback;
745 
746  tlen = mutt_str_len(target_mailbox);
747  hlen = mutt_str_len(home_mailbox);
748 
749  /* check whether we can do '+' substitution */
750  if (tlen && imap_account_match(&cac_home, &cac_target) &&
751  mutt_strn_equal(home_mailbox, target_mailbox, hlen))
752  {
753  if (hlen == 0)
754  home_match = true;
755  else if (C_ImapDelimChars)
756  {
757  for (delim = C_ImapDelimChars; *delim != '\0'; delim++)
758  if (target_mailbox[hlen] == *delim)
759  home_match = true;
760  }
761  }
762 
763  /* do the '+' substitution */
764  if (home_match)
765  {
766  *path++ = '+';
767  /* copy remaining path, skipping delimiter */
768  if (hlen == 0)
769  hlen = -1;
770  memcpy(path, target_mailbox + hlen + 1, tlen - hlen - 1);
771  path[tlen - hlen - 1] = '\0';
772  return;
773  }
774 
775 fallback:
776  mutt_account_tourl(&cac_target, &url);
777  url.path = target_mailbox;
778  url_tostring(&url, path, pathlen, 0);
779 }
780 
787 enum QuadOption imap_continue(const char *msg, const char *resp)
788 {
789  imap_error(msg, resp);
790  return mutt_yesorno(_("Continue?"), MUTT_NO);
791 }
792 
798 void imap_error(const char *where, const char *msg)
799 {
800  mutt_error("%s [%s]", where, msg);
801 }
802 
820 char *imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
821 {
822  int i = 0;
823  for (; mailbox && *mailbox && (i < plen - 1); i++)
824  {
825  if (*mailbox == delim || (!delim && strchr(NONULL(C_ImapDelimChars), *mailbox)))
826  {
827  delim = *mailbox;
828  /* Skip multiple occurrences of delim */
829  while (*mailbox && *(mailbox + 1) == delim)
830  mailbox++;
831  }
832  path[i] = *mailbox++;
833  }
834 
835  /* Do not terminate with a delimiter */
836  if (i && path[i - 1] == delim)
837  i--;
838 
839  /* Ensure null termination */
840  path[i] = '\0';
841  return path;
842 }
843 
850 void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
851 {
852  const char *p = mailbox;
853  mutt_buffer_reset(dest);
854  if (!p)
855  return;
856 
857  while (*p)
858  {
859  if (p[0] == delim)
860  {
861  mutt_buffer_addch(dest, '/');
862  /* simple way to avoid collisions with UIDs */
863  if ((p[1] >= '0') && (p[1] <= '9'))
864  mutt_buffer_addch(dest, '_');
865  }
866  else
867  mutt_buffer_addch(dest, *p);
868  p++;
869  }
870 }
871 
879 int imap_get_literal_count(const char *buf, unsigned int *bytes)
880 {
881  char *pc = NULL;
882  char *pn = NULL;
883 
884  if (!buf || !(pc = strchr(buf, '{')))
885  return -1;
886 
887  pc++;
888  pn = pc;
889  while (isdigit((unsigned char) *pc))
890  pc++;
891  *pc = '\0';
892  if (mutt_str_atoui(pn, bytes) < 0)
893  return -1;
894 
895  return 0;
896 }
897 
906 char *imap_get_qualifier(char *buf)
907 {
908  char *s = buf;
909 
910  /* skip tag */
911  s = imap_next_word(s);
912  /* skip OK/NO/BAD response */
913  s = imap_next_word(s);
914 
915  return s;
916 }
917 
923 char *imap_next_word(char *s)
924 {
925  bool quoted = false;
926 
927  while (*s)
928  {
929  if (*s == '\\')
930  {
931  s++;
932  if (*s)
933  s++;
934  continue;
935  }
936  if (*s == '\"')
937  quoted = !quoted;
938  if (!quoted && IS_SPACE(*s))
939  break;
940  s++;
941  }
942 
943  SKIPWS(s);
944  return s;
945 }
946 
954 void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
955 {
956  struct Url url = { 0 };
957  mutt_account_tourl(cac, &url);
958  url.path = path;
959  url_tostring(&url, buf, buflen, 0);
960 }
961 
971 void imap_quote_string(char *dest, size_t dlen, const char *src, bool quote_backtick)
972 {
973  const char *quote = "`\"\\";
974  if (!quote_backtick)
975  quote++;
976 
977  char *pt = dest;
978  const char *s = src;
979 
980  *pt++ = '"';
981  /* save room for quote-chars */
982  dlen -= 3;
983 
984  for (; *s && dlen; s++)
985  {
986  if (strchr(quote, *s))
987  {
988  if (dlen < 2)
989  break;
990  dlen -= 2;
991  *pt++ = '\\';
992  *pt++ = *s;
993  }
994  else
995  {
996  *pt++ = *s;
997  dlen--;
998  }
999  }
1000  *pt++ = '"';
1001  *pt = '\0';
1002 }
1003 
1008 void imap_unquote_string(char *s)
1009 {
1010  char *d = s;
1011 
1012  if (*s == '\"')
1013  s++;
1014  else
1015  return;
1016 
1017  while (*s)
1018  {
1019  if (*s == '\"')
1020  {
1021  *d = '\0';
1022  return;
1023  }
1024  if (*s == '\\')
1025  {
1026  s++;
1027  }
1028  if (*s)
1029  {
1030  *d = *s;
1031  d++;
1032  s++;
1033  }
1034  }
1035  *d = '\0';
1036 }
1037 
1045 void imap_munge_mbox_name(bool unicode, char *dest, size_t dlen, const char *src)
1046 {
1047  char *buf = mutt_str_dup(src);
1048  imap_utf_encode(unicode, &buf);
1049 
1050  imap_quote_string(dest, dlen, buf, false);
1051 
1052  FREE(&buf);
1053 }
1054 
1062 void imap_unmunge_mbox_name(bool unicode, char *s)
1063 {
1065 
1066  char *buf = mutt_str_dup(s);
1067  if (buf)
1068  {
1069  imap_utf_decode(unicode, &buf);
1070  strncpy(s, buf, strlen(s));
1071  }
1072 
1073  FREE(&buf);
1074 }
1075 
1079 void imap_keepalive(void)
1080 {
1081  time_t now = mutt_date_epoch();
1082  struct Account *np = NULL;
1083  TAILQ_FOREACH(np, &NeoMutt->accounts, entries)
1084  {
1085  if (np->type != MUTT_IMAP)
1086  continue;
1087 
1088  struct ImapAccountData *adata = np->adata;
1089  if (!adata || !adata->mailbox)
1090  continue;
1091 
1092  if ((adata->state >= IMAP_AUTHENTICATED) && (now >= (adata->lastread + C_ImapKeepalive)))
1093  imap_check_mailbox(adata->mailbox, true);
1094  }
1095 }
1096 
1102 int imap_wait_keepalive(pid_t pid)
1103 {
1104  struct sigaction oldalrm;
1105  struct sigaction act;
1106  sigset_t oldmask;
1107  int rc;
1108 
1109  bool imap_passive = C_ImapPassive;
1110 
1111  C_ImapPassive = true;
1112  OptKeepQuiet = true;
1113 
1114  sigprocmask(SIG_SETMASK, NULL, &oldmask);
1115 
1116  sigemptyset(&act.sa_mask);
1117  act.sa_handler = mutt_sig_empty_handler;
1118 #ifdef SA_INTERRUPT
1119  act.sa_flags = SA_INTERRUPT;
1120 #else
1121  act.sa_flags = 0;
1122 #endif
1123 
1124  sigaction(SIGALRM, &act, &oldalrm);
1125 
1126  alarm(C_ImapKeepalive);
1127  while ((waitpid(pid, &rc, 0) < 0) && (errno == EINTR))
1128  {
1129  alarm(0); /* cancel a possibly pending alarm */
1130  imap_keepalive();
1131  alarm(C_ImapKeepalive);
1132  }
1133 
1134  alarm(0); /* cancel a possibly pending alarm */
1135 
1136  sigaction(SIGALRM, &oldalrm, NULL);
1137  sigprocmask(SIG_SETMASK, &oldmask, NULL);
1138 
1139  OptKeepQuiet = false;
1140  if (!imap_passive)
1141  C_ImapPassive = false;
1142 
1143  return rc;
1144 }
1145 
1151 {
1152  struct ImapAccountData *adata = imap_adata_get(m);
1153  struct ImapMboxData *mdata = imap_mdata_get(m);
1154  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1155  return;
1156  mdata->reopen |= IMAP_REOPEN_ALLOW;
1157 }
1158 
1164 {
1165  struct ImapAccountData *adata = imap_adata_get(m);
1166  struct ImapMboxData *mdata = imap_mdata_get(m);
1167  if (!adata || !adata->mailbox || (adata->mailbox != m) || !mdata)
1168  return;
1169  mdata->reopen &= ~IMAP_REOPEN_ALLOW;
1170 }
1171 
1178 bool imap_account_match(const struct ConnAccount *a1, const struct ConnAccount *a2)
1179 {
1180  if (!a1 || !a2)
1181  return false;
1182  if (a1->type != a2->type)
1183  return false;
1184  if (!mutt_istr_equal(a1->host, a2->host))
1185  return false;
1186  if ((a1->port != 0) && (a2->port != 0) && (a1->port != a2->port))
1187  return false;
1188  if (a1->flags & a2->flags & MUTT_ACCT_USER)
1189  return strcmp(a1->user, a2->user) == 0;
1190 
1191  const char *user = NONULL(Username);
1192 
1193  if ((a1->type == MUTT_ACCT_TYPE_IMAP) && C_ImapUser)
1194  user = C_ImapUser;
1195 
1196  if (a1->flags & MUTT_ACCT_USER)
1197  return strcmp(a1->user, user) == 0;
1198  if (a2->flags & MUTT_ACCT_USER)
1199  return strcmp(a2->user, user) == 0;
1200 
1201  return true;
1202 }
1203 
1209 struct SeqsetIterator *mutt_seqset_iterator_new(const char *seqset)
1210 {
1211  if (!seqset || (*seqset == '\0'))
1212  return NULL;
1213 
1214  struct SeqsetIterator *iter = mutt_mem_calloc(1, sizeof(struct SeqsetIterator));
1215  iter->full_seqset = mutt_str_dup(seqset);
1216  iter->eostr = strchr(iter->full_seqset, '\0');
1217  iter->substr_cur = iter->substr_end = iter->full_seqset;
1218 
1219  return iter;
1220 }
1221 
1230 int mutt_seqset_iterator_next(struct SeqsetIterator *iter, unsigned int *next)
1231 {
1232  if (!iter || !next)
1233  return -1;
1234 
1235  if (iter->in_range)
1236  {
1237  if ((iter->down && (iter->range_cur == (iter->range_end - 1))) ||
1238  (!iter->down && (iter->range_cur == (iter->range_end + 1))))
1239  {
1240  iter->in_range = 0;
1241  }
1242  }
1243 
1244  if (!iter->in_range)
1245  {
1246  iter->substr_cur = iter->substr_end;
1247  if (iter->substr_cur == iter->eostr)
1248  return 1;
1249 
1250  while (!*(iter->substr_cur))
1251  iter->substr_cur++;
1252  iter->substr_end = strchr(iter->substr_cur, ',');
1253  if (!iter->substr_end)
1254  iter->substr_end = iter->eostr;
1255  else
1256  *(iter->substr_end) = '\0';
1257 
1258  char *range_sep = strchr(iter->substr_cur, ':');
1259  if (range_sep)
1260  *range_sep++ = '\0';
1261 
1262  if (mutt_str_atoui(iter->substr_cur, &iter->range_cur) != 0)
1263  return -1;
1264  if (range_sep)
1265  {
1266  if (mutt_str_atoui(range_sep, &iter->range_end) != 0)
1267  return -1;
1268  }
1269  else
1270  iter->range_end = iter->range_cur;
1271 
1272  iter->down = (iter->range_end < iter->range_cur);
1273  iter->in_range = 1;
1274  }
1275 
1276  *next = iter->range_cur;
1277  if (iter->down)
1278  iter->range_cur--;
1279  else
1280  iter->range_cur++;
1281 
1282  return 0;
1283 }
1284 
1290 {
1291  if (!ptr || !*ptr)
1292  return;
1293 
1294  struct SeqsetIterator *iter = *ptr;
1295  FREE(&iter->full_seqset);
1296  FREE(ptr);
1297 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
Convenience wrapper for the gui headers.
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
char * eostr
Definition: private.h:250
int mutt_str_cmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:567
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:98
struct ImapCommand * cmds
Definition: private.h:200
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:1008
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:725
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:425
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2367
Wrapper for Email retrieved from the header cache.
Definition: lib.h:96
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:229
Structs that make up an email.
Connection is authenticated.
Definition: private.h:109
#define IMAP_SSL_PORT
Port for IMAP over SSL/TLS.
Definition: private.h:46
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:475
#define IMAP_PORT
Default port for IMAP.
Definition: private.h:45
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:299
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:66
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void imap_mdata_free(void **ptr)
Free the private Mailbox data - Implements Mailbox::mdata_free()
Definition: util.c:225
char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: config.c:40
unsigned char state
ImapState, e.g. IMAP_AUTHENTICATED.
Definition: private.h:175
struct Email * imap_hcache_get(struct ImapMboxData *mdata, unsigned int uid)
Get a header cache entry by its UID.
Definition: util.c:491
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:98
Url is imaps://.
Definition: url.h:39
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:223
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
header cache structure
Definition: lib.h:85
String manipulation buffer.
Definition: buffer.h:33
char user[128]
Username.
Definition: connaccount.h:55
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define _(a)
Definition: message.h:28
struct Mailbox * mailbox
Current selected mailbox.
Definition: private.h:207
char * C_ImapOauthRefreshCommand
Config: (imap) External command to generate OAUTH refresh token.
Definition: config.c:52
char * capstr
Definition: private.h:185
Url is imap://.
Definition: url.h:38
Password.
Definition: connaccount.h:36
struct HeaderCache * hcache
Definition: private.h:241
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:326
char * imap_fix_path(char delim, const char *mailbox, char *path, size_t plen)
Fix up the imap path.
Definition: util.c:820
struct ImapAccountData * imap_adata_get(struct Mailbox *m)
Get the Account data for this mailbox.
Definition: util.c:114
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
void mutt_hcache_free_raw(struct HeaderCache *hc, void **data)
Multiplexor for StoreOps::free.
Definition: hcache.c:512
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
struct HeaderCache * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for StoreOps::open.
Definition: hcache.c:320
IMAP MSN helper functions.
static const char * imap_get_field(enum ConnAccountField field, void *gf_data)
Get connection login credentials - Implements ConnAccount::get_field()
Definition: util.c:342
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:1062
void imap_error(const char *where, const char *msg)
show an error and abort
Definition: util.c:798
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
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
unsigned char seqid
tag sequence prefix
Definition: private.h:187
void imap_get_parent(const char *mbox, char delim, char *buf, size_t buflen)
Get an IMAP folder&#39;s parent.
Definition: util.c:258
struct ImapMboxData * imap_mdata_get(struct Mailbox *m)
Get the Mailbox data for this mailbox.
Definition: util.c:244
struct BodyCache * bcache
Definition: private.h:239
char host[128]
Server to login to.
Definition: connaccount.h:53
void imap_msn_free(struct MSN *msn)
Free the cache.
Definition: msn.c:59
WHERE char * Username
User&#39;s login name.
Definition: mutt_globals.h:52
Manage IMAP messages.
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:618
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:379
Header cache multiplexor.
void imap_cachepath(char delim, const char *mailbox, struct Buffer *dest)
Generate a cache path for a mailbox.
Definition: util.c:850
struct Email * imap_msn_get(const struct MSN *msn, size_t idx)
Return the Email associated with an msn.
Definition: msn.c:80
char * C_ImapDelimChars
Config: (imap) Characters that denote separators in IMAP folders.
Definition: config.c:45
#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:1150
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:548
int imap_hcache_store_uid_seqset(struct ImapMboxData *mdata)
Store a UID Sequence Set in the header cache.
Definition: util.c:551
unsigned int range_end
Definition: private.h:254
int imap_hcache_del(struct ImapMboxData *mdata, unsigned int uid)
Delete an item from the header cache.
Definition: util.c:534
struct Buffer cmdbuf
Definition: private.h:204
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:61
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
unsigned long long modseq
Definition: private.h:231
Body Caching - local copies of email bodies.
int imap_wait_keepalive(pid_t pid)
Wait for a process to change state.
Definition: util.c:1102
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
struct HashTable * uid_hash
Definition: private.h:237
#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)
Free the private Account data - Implements Account::adata_free()
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:435
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:1178
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:54
struct Account * account
Parent Account.
Definition: private.h:209
#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:1163
struct ListHead flags
Definition: private.h:228
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:56
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:971
int mutt_hcache_delete_record(struct HeaderCache *hc, const char *key, size_t keylen)
Multiplexor for StoreOps::delete_record.
Definition: hcache.c:602
unsigned char type
Connection type, e.g. MUTT_ACCT_TYPE_IMAP.
Definition: connaccount.h:58
char * name
Mailbox name.
Definition: private.h:219
int mutt_str_atoui(const char *str, unsigned int *dst)
Convert ASCII string to an unsigned integer.
Definition: string.c:282
int mutt_hcache_store(struct HeaderCache *hc, const char *key, size_t keylen, struct Email *e, uint32_t uidvalidity)
Multiplexor for StoreOps::store.
Definition: hcache.c:525
char * imap_get_qualifier(char *buf)
Get the qualifier from a tagged response.
Definition: util.c:906
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:587
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:189
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:221
short C_ImapKeepalive
Config: (imap) Time to wait before polling an open IMAP connection.
Definition: config.c:49
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:593
char * substr_cur
Definition: private.h:255
void mutt_hcache_close(struct HeaderCache *hc)
Multiplexor for StoreOps::close.
Definition: hcache.c:417
#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:516
size_t imap_msn_highest(const struct MSN *msn)
Return the highest MSN in use.
Definition: msn.c:69
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
int imap_check_mailbox(struct Mailbox *m, bool force)
use the NOOP or IDLE command to poll for new mail
Definition: imap.c:1091
int imap_get_literal_count(const char *buf, unsigned int *bytes)
write number of bytes in an IMAP literal into bytes
Definition: util.c:879
IMAP-specific Account data -.
Definition: private.h:170
unsigned int uid_next
Definition: private.h:230
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:131
int imap_mxcmp(const char *mx1, const char *mx2)
Compare mailbox names, giving priority to INBOX.
Definition: util.c:689
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:716
IMAP-specific Mailbox data -.
Definition: private.h:217
char * buf
Definition: private.h:190
int imap_hcache_clear_uid_seqset(struct ImapMboxData *mdata)
Delete a UID Sequence Set from the header cache.
Definition: util.c:573
#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:1209
Connection Library.
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
#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:1079
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
struct HCacheEntry mutt_hcache_fetch(struct HeaderCache *hc, const char *key, size_t keylen, uint32_t uidvalidity)
Multiplexor for StoreOps::fetch.
Definition: hcache.c:436
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:1045
int mutt_seqset_iterator_next(struct SeqsetIterator *iter, unsigned int *next)
Get the next UID from a Sequence Set.
Definition: util.c:1230
void imap_qualify_path(char *buf, size_t buflen, struct ConnAccount *cac, char *path)
Make an absolute IMAP folder target.
Definition: util.c:954
Hundreds of global variables to back the user variables.
Handling of global boolean variables.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_hcache_store_raw(struct HeaderCache *hc, const char *key, size_t keylen, void *data, size_t dlen)
store a key / data pair
Definition: hcache.c:582
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:787
struct Email * email
Retrieved email.
Definition: lib.h:100
static void imap_msn_index_to_uid_seqset(struct Buffer *buf, struct ImapMboxData *mdata)
Convert MSN index of UIDs to Seqset.
Definition: util.c:369
Login name.
Definition: connaccount.h:34
void * mutt_hcache_fetch_raw(struct HeaderCache *hc, const char *key, size_t keylen, size_t *dlen)
Fetch a message&#39;s header from the cache.
Definition: hcache.c:494
void mutt_seqset_iterator_free(struct SeqsetIterator **ptr)
Free a Sequence Set Iterator.
Definition: util.c:1289
Convenience wrapper for the library headers.
char * substr_end
Definition: private.h:256
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:220
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
char * full_seqset
Definition: private.h:249
char * C_ImapPass
Config: (imap) Password for the IMAP server.
Definition: config.c:53
unsigned int range_cur
Definition: private.h:253
void mutt_bcache_close(struct BodyCache **bcache)
Close an Email-Body Cache.
Definition: bcache.c:164
Log at debug level 3.
Definition: logging.h:42
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:193
UID Sequence Set Iterator.
Definition: private.h:247
#define U_PATH
Definition: url.h:48
char * imap_next_word(char *s)
Find where the next IMAP word begins.
Definition: util.c:923
Server name.
Definition: connaccount.h:33
char * C_ImapLogin
Config: (imap) Login name for the IMAP server (defaults to $imap_user)
Definition: config.c:51
MuttAccountFlags flags
Which fields are initialised, e.g. MUTT_ACCT_USER.
Definition: connaccount.h:59
struct Connection * conn
Definition: private.h:172
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234