NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
muttlib.h File Reference
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "format_flags.h"
#include "mutt_attach.h"
+ Include dependency graph for muttlib.h:

Go to the source code of this file.

Macros

#define mutt_mktemp(buf, buflen)   mutt_mktemp_pfx_sfx(buf, buflen, "neomutt", NULL)
 
#define mutt_mktemp_pfx_sfx(buf, buflen, prefix, suffix)   mutt_mktemp_full(buf, buflen, prefix, suffix, __FILE__, __LINE__)
 
#define mutt_buffer_mktemp(buf)   mutt_buffer_mktemp_pfx_sfx(buf, "neomutt", NULL)
 
#define mutt_buffer_mktemp_pfx_sfx(buf, prefix, suffix)   mutt_buffer_mktemp_full(buf, prefix, suffix, __FILE__, __LINE__)
 

Functions

void mutt_adv_mktemp (struct Buffer *buf)
 Create a temporary file. More...
 
void mutt_buffer_mktemp_full (struct Buffer *buf, const char *prefix, const char *suffix, const char *src, int line)
 Create a temporary file. More...
 
void mutt_buffer_expand_path (struct Buffer *buf)
 Create the canonical path. More...
 
void mutt_buffer_expand_path_regex (struct Buffer *buf, bool regex)
 Create the canonical path (with regex char escaping) More...
 
void mutt_buffer_pretty_mailbox (struct Buffer *s)
 Shorten a mailbox path using '~' or '='. More...
 
void mutt_buffer_sanitize_filename (struct Buffer *buf, const char *path, short slash)
 Replace unsafe characters in a filename. More...
 
void mutt_buffer_save_path (struct Buffer *dest, const struct Address *a)
 Make a safe filename from an email address. More...
 
int mutt_check_overwrite (const char *attname, const char *path, struct Buffer *fname, enum SaveAttach *opt, char **directory)
 Ask the user if overwriting is necessary. More...
 
void mutt_encode_path (struct Buffer *buf, const char *src)
 Convert a path to 'us-ascii'. More...
 
void mutt_expando_format (char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
 Expand expandos (x) in a string. More...
 
char * mutt_expand_path (char *s, size_t slen)
 Create the canonical path. More...
 
char * mutt_expand_path_regex (char *buf, size_t buflen, bool regex)
 Create the canonical path (with regex char escaping) More...
 
char * mutt_gecos_name (char *dest, size_t destlen, struct passwd *pw)
 Lookup a user's real name in /etc/passwd. More...
 
void mutt_get_parent_path (const char *path, char *buf, size_t buflen)
 Find the parent of a path (or mailbox) More...
 
int mutt_inbox_cmp (const char *a, const char *b)
 do two folders share the same path and one is an inbox More...
 
bool mutt_is_text_part (struct Body *b)
 Is this part of an email in plain text? More...
 
const char * mutt_make_version (void)
 Generate the NeoMutt version string. More...
 
void mutt_mktemp_full (char *s, size_t slen, const char *prefix, const char *suffix, const char *src, int line)
 Create a temporary filename. More...
 
bool mutt_needs_mailcap (struct Body *m)
 Does this type need a mailcap entry do display. More...
 
FILE * mutt_open_read (const char *path, pid_t *thepid)
 Run a command to read from. More...
 
void mutt_pretty_mailbox (char *buf, size_t buflen)
 Shorten a mailbox path using '~' or '='. More...
 
void mutt_safe_path (struct Buffer *dest, const struct Address *a)
 Make a safe filename from an email address. More...
 
int mutt_save_confirm (const char *s, struct stat *st)
 Ask the user to save. More...
 
void mutt_save_path (char *d, size_t dsize, const struct Address *a)
 Turn an email address into a filename (for saving) More...
 
void mutt_sleep (short s)
 Sleep for a while. More...
 
void mutt_str_pretty_size (char *buf, size_t buflen, size_t num)
 Display an abbreviated size, like 3.4K. More...
 
void add_to_stailq (struct ListHead *head, const char *str)
 Add a string to a list. More...
 
void remove_from_stailq (struct ListHead *head, const char *str)
 Remove an item, matching a string, from a List. More...
 

Variables

struct RegexC_GecosMask
 Config: Regex for parsing GECOS field of /etc/passwd. More...
 

Detailed Description

Some miscellaneous functions

Authors
  • Richard Russon
  • Pietro Cerutti

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 muttlib.h.

Macro Definition Documentation

◆ mutt_mktemp

#define mutt_mktemp (   buf,
  buflen 
)    mutt_mktemp_pfx_sfx(buf, buflen, "neomutt", NULL)

Definition at line 74 of file muttlib.h.

◆ mutt_mktemp_pfx_sfx

#define mutt_mktemp_pfx_sfx (   buf,
  buflen,
  prefix,
  suffix 
)    mutt_mktemp_full(buf, buflen, prefix, suffix, __FILE__, __LINE__)

Definition at line 75 of file muttlib.h.

◆ mutt_buffer_mktemp

#define mutt_buffer_mktemp (   buf)    mutt_buffer_mktemp_pfx_sfx(buf, "neomutt", NULL)

Definition at line 77 of file muttlib.h.

◆ mutt_buffer_mktemp_pfx_sfx

#define mutt_buffer_mktemp_pfx_sfx (   buf,
  prefix,
  suffix 
)    mutt_buffer_mktemp_full(buf, prefix, suffix, __FILE__, __LINE__)

Definition at line 78 of file muttlib.h.

Function Documentation

◆ mutt_adv_mktemp()

void mutt_adv_mktemp ( struct Buffer buf)

Create a temporary file.

Parameters
bufBuffer for the name

Accept a "suggestion" for file name. If that file exists, then construct one with unique name but keep any extension. This might fail, I guess.

Definition at line 90 of file muttlib.c.

91 {
92  if (!(buf->data && (buf->data[0] != '\0')))
93  {
94  mutt_buffer_mktemp(buf);
95  }
96  else
97  {
98  struct Buffer *prefix = mutt_buffer_pool_get();
99  mutt_buffer_strcpy(prefix, buf->data);
100  mutt_file_sanitize_filename(prefix->data, true);
101  mutt_buffer_printf(buf, "%s/%s", NONULL(C_Tmpdir), mutt_buffer_string(prefix));
102 
103  struct stat sb;
104  if ((lstat(mutt_buffer_string(buf), &sb) == -1) && (errno == ENOENT))
105  goto out;
106 
107  char *suffix = strchr(prefix->data, '.');
108  if (suffix)
109  {
110  *suffix = '\0';
111  suffix++;
112  }
113  mutt_buffer_mktemp_pfx_sfx(buf, prefix->data, suffix);
114 
115  out:
116  mutt_buffer_pool_release(&prefix);
117  }
118 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_mktemp_full()

void mutt_buffer_mktemp_full ( struct Buffer buf,
const char *  prefix,
const char *  suffix,
const char *  src,
int  line 
)

Create a temporary file.

Parameters
bufBuffer for result
prefixPrefix for filename
suffixSuffix for filename
srcSource file of caller
lineSource line number of caller

Definition at line 467 of file muttlib.c.

469 {
470  mutt_buffer_printf(buf, "%s/%s-%s-%d-%d-%" PRIu64 "%s%s", NONULL(C_Tmpdir),
471  NONULL(prefix), NONULL(ShortHostname), (int) getuid(),
472  (int) getpid(), mutt_rand64(), suffix ? "." : "", NONULL(suffix));
473 
474  mutt_debug(LL_DEBUG3, "%s:%d: mutt_mktemp returns \"%s\"\n", src, line,
475  mutt_buffer_string(buf));
476  if (unlink(mutt_buffer_string(buf)) && (errno != ENOENT))
477  {
478  mutt_debug(LL_DEBUG1, "%s:%d: ERROR: unlink(\"%s\"): %s (errno %d)\n", src,
479  line, mutt_buffer_string(buf), strerror(errno), errno);
480  }
481 }
+ Here is the call graph for this function:

◆ mutt_buffer_expand_path()

void mutt_buffer_expand_path ( struct Buffer buf)

Create the canonical path.

Parameters
bufBuffer with path
Note
The path is expanded in-place

Definition at line 323 of file muttlib.c.

324 {
325  mutt_buffer_expand_path_regex(buf, false);
326 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_expand_path_regex()

void mutt_buffer_expand_path_regex ( struct Buffer buf,
bool  regex 
)

Create the canonical path (with regex char escaping)

Parameters
bufBuffer with path
regexIf true, escape any regex characters
Note
The path is expanded in-place

Definition at line 140 of file muttlib.c.

141 {
142  const char *s = NULL;
143  const char *tail = "";
144 
145  bool recurse = false;
146 
147  struct Buffer *p = mutt_buffer_pool_get();
148  struct Buffer *q = mutt_buffer_pool_get();
149  struct Buffer *tmp = mutt_buffer_pool_get();
150 
151  do
152  {
153  recurse = false;
154  s = mutt_buffer_string(buf);
155 
156  switch (*s)
157  {
158  case '~':
159  {
160  if ((s[1] == '/') || (s[1] == '\0'))
161  {
163  tail = s + 1;
164  }
165  else
166  {
167  char *t = strchr(s + 1, '/');
168  if (t)
169  *t = '\0';
170 
171  struct passwd *pw = getpwnam(s + 1);
172  if (pw)
173  {
174  mutt_buffer_strcpy(p, pw->pw_dir);
175  if (t)
176  {
177  *t = '/';
178  tail = t;
179  }
180  else
181  tail = "";
182  }
183  else
184  {
185  /* user not found! */
186  if (t)
187  *t = '/';
189  tail = s;
190  }
191  }
192  break;
193  }
194 
195  case '=':
196  case '+':
197  {
198  enum MailboxType mb_type = mx_path_probe(C_Folder);
199 
200  /* if folder = {host} or imap[s]://host/: don't append slash */
201  if ((mb_type == MUTT_IMAP) && ((C_Folder[strlen(C_Folder) - 1] == '}') ||
202  (C_Folder[strlen(C_Folder) - 1] == '/')))
203  {
205  }
206  else if (mb_type == MUTT_NOTMUCH)
208  else if (C_Folder && (C_Folder[strlen(C_Folder) - 1] == '/'))
210  else
211  mutt_buffer_printf(p, "%s/", NONULL(C_Folder));
212 
213  tail = s + 1;
214  break;
215  }
216 
217  /* elm compatibility, @ expands alias to user name */
218 
219  case '@':
220  {
221  struct AddressList *al = alias_lookup(s + 1);
222  if (al && !TAILQ_EMPTY(al))
223  {
224  struct Email *e = email_new();
225  e->env = mutt_env_new();
226  mutt_addrlist_copy(&e->env->from, al, false);
227  mutt_addrlist_copy(&e->env->to, al, false);
228 
229  /* TODO: fix mutt_default_save() to use Buffer */
231  mutt_default_save(p->data, p->dsize, e);
233 
234  email_free(&e);
235  /* Avoid infinite recursion if the resulting folder starts with '@' */
236  if (*p->data != '@')
237  recurse = true;
238 
239  tail = "";
240  }
241  break;
242  }
243 
244  case '>':
245  {
247  tail = s + 1;
248  break;
249  }
250 
251  case '<':
252  {
254  tail = s + 1;
255  break;
256  }
257 
258  case '!':
259  {
260  if (s[1] == '!')
261  {
263  tail = s + 2;
264  }
265  else
266  {
268  tail = s + 1;
269  }
270  break;
271  }
272 
273  case '-':
274  {
276  tail = s + 1;
277  break;
278  }
279 
280  case '^':
281  {
283  tail = s + 1;
284  break;
285  }
286 
287  default:
288  {
290  tail = s;
291  }
292  }
293 
294  if (regex && *(mutt_buffer_string(p)) && !recurse)
295  {
297  mutt_buffer_printf(tmp, "%s%s", mutt_buffer_string(q), tail);
298  }
299  else
300  mutt_buffer_printf(tmp, "%s%s", mutt_buffer_string(p), tail);
301 
302  mutt_buffer_copy(buf, tmp);
303  } while (recurse);
304 
308 
309 #ifdef USE_IMAP
310  /* Rewrite IMAP path in canonical form - aids in string comparisons of
311  * folders. May possibly fail, in which case buf should be the same. */
312  if (imap_path_probe(mutt_buffer_string(buf), NULL) == MUTT_IMAP)
313  imap_expand_path(buf);
314 #endif
315 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_pretty_mailbox()

void mutt_buffer_pretty_mailbox ( struct Buffer buf)

Shorten a mailbox path using '~' or '='.

Parameters
bufBuffer containing Mailbox name

Definition at line 599 of file muttlib.c.

600 {
601  if (!buf || !buf->data)
602  return;
603  /* This reduces the size of the Buffer, so we can pass it through.
604  * We adjust the size just to make sure buf->data is not NULL though */
606  mutt_pretty_mailbox(buf->data, buf->dsize);
608 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_sanitize_filename()

void mutt_buffer_sanitize_filename ( struct Buffer buf,
const char *  path,
short  slash 
)

Replace unsafe characters in a filename.

Parameters
bufBuffer for the result
pathFilename to make safe
slashReplace '/' characters too

Definition at line 1641 of file muttlib.c.

1642 {
1643  if (!buf || !path)
1644  return;
1645 
1646  mutt_buffer_reset(buf);
1647 
1648  for (; *path; path++)
1649  {
1650  if ((slash && (*path == '/')) || !strchr(filename_safe_chars, *path))
1651  mutt_buffer_addch(buf, '_');
1652  else
1653  mutt_buffer_addch(buf, *path);
1654  }
1655 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_buffer_save_path()

void mutt_buffer_save_path ( struct Buffer dest,
const struct Address a 
)

Make a safe filename from an email address.

Parameters
destBuffer for the result
aAddress to use

Definition at line 728 of file muttlib.c.

729 {
730  if (a && a->mailbox)
731  {
732  mutt_buffer_strcpy(dest, a->mailbox);
733  if (!C_SaveAddress)
734  {
735  char *p = strpbrk(dest->data, "%@");
736  if (p)
737  {
738  *p = '\0';
739  mutt_buffer_fix_dptr(dest);
740  }
741  }
742  mutt_str_lower(dest->data);
743  }
744  else
745  mutt_buffer_reset(dest);
746 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_check_overwrite()

int mutt_check_overwrite ( const char *  attname,
const char *  path,
struct Buffer fname,
enum SaveAttach opt,
char **  directory 
)

Ask the user if overwriting is necessary.

Parameters
[in]attnameAttachment name
[in]pathPath to save the file
[out]fnameBuffer for filename
[out]optSave option, see SaveAttach
[out]directoryDirectory to save under (OPTIONAL)
Return values
0Success
-1Abort
1Error

Definition at line 621 of file muttlib.c.

623 {
624  struct stat st;
625 
626  mutt_buffer_strcpy(fname, path);
627  if (access(mutt_buffer_string(fname), F_OK) != 0)
628  return 0;
629  if (stat(mutt_buffer_string(fname), &st) != 0)
630  return -1;
631  if (S_ISDIR(st.st_mode))
632  {
633  enum QuadOption ans = MUTT_NO;
634  if (directory)
635  {
636  switch (mutt_multi_choice
637  /* L10N: Means "The path you specified as the destination file is a directory."
638  See the msgid "Save to file: " (alias.c, recvattach.c)
639  These three letters correspond to the choices in the string. */
640  (_("File is a directory, save under it: (y)es, (n)o, (a)ll?"), _("yna")))
641  {
642  case 3: /* all */
643  mutt_str_replace(directory, mutt_buffer_string(fname));
644  break;
645  case 1: /* yes */
646  FREE(directory);
647  break;
648  case -1: /* abort */
649  FREE(directory);
650  return -1;
651  case 2: /* no */
652  FREE(directory);
653  return 1;
654  }
655  }
656  /* L10N: Means "The path you specified as the destination file is a directory."
657  See the msgid "Save to file: " (alias.c, recvattach.c) */
658  else if ((ans = mutt_yesorno(_("File is a directory, save under it?"), MUTT_YES)) != MUTT_YES)
659  return (ans == MUTT_NO) ? 1 : -1;
660 
661  struct Buffer *tmp = mutt_buffer_pool_get();
663  if ((mutt_buffer_get_field(_("File under directory: "), tmp, MUTT_FILE | MUTT_CLEAR,
664  false, NULL, NULL, NULL) != 0) ||
666  {
668  return (-1);
669  }
670  mutt_buffer_concat_path(fname, path, mutt_buffer_string(tmp));
672  }
673 
674  if ((*opt == MUTT_SAVE_NO_FLAGS) && (access(mutt_buffer_string(fname), F_OK) == 0))
675  {
676  switch (
677  mutt_multi_choice(_("File exists, (o)verwrite, (a)ppend, or (c)ancel?"),
678  // L10N: Options for: File exists, (o)verwrite, (a)ppend, or (c)ancel?
679  _("oac")))
680  {
681  case -1: /* abort */
682  return -1;
683  case 3: /* cancel */
684  return 1;
685 
686  case 2: /* append */
687  *opt = MUTT_SAVE_APPEND;
688  break;
689  case 1: /* overwrite */
690  *opt = MUTT_SAVE_OVERWRITE;
691  break;
692  }
693  }
694  return 0;
695 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_encode_path()

void mutt_encode_path ( struct Buffer buf,
const char *  src 
)

Convert a path to 'us-ascii'.

Parameters
bufBuffer for the result
srcPath to convert (OPTIONAL)

If src is NULL, the path in buf will be converted in-place.

Definition at line 1476 of file muttlib.c.

1477 {
1478  char *p = mutt_str_dup(src);
1479  int rc = mutt_ch_convert_string(&p, C_Charset, "us-ascii", MUTT_ICONV_NO_FLAGS);
1480  size_t len = mutt_buffer_strcpy(buf, (rc == 0) ? NONULL(p) : NONULL(src));
1481 
1482  /* convert the path to POSIX "Portable Filename Character Set" */
1483  for (size_t i = 0; i < len; i++)
1484  {
1485  if (!isalnum(buf->data[i]) && !strchr("/.-_", buf->data[i]))
1486  {
1487  buf->data[i] = '_';
1488  }
1489  }
1490  FREE(&p);
1491 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_expando_format()

void mutt_expando_format ( char *  buf,
size_t  buflen,
size_t  col,
int  cols,
const char *  src,
format_t  callback,
intptr_t  data,
MuttFormatFlags  flags 
)

Expand expandos (x) in a string.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]colStarting column
[in]colsNumber of screen columns
[in]srcPrintf-like format string
[in]callbackCallback - Implements format_t
[in]dataCallback data
[in]flagsCallback flags

Definition at line 774 of file muttlib.c.

776 {
777  char prefix[128], tmp[1024];
778  char *cp = NULL, *wptr = buf;
779  char ch;
780  char if_str[128], else_str[128];
781  size_t wlen, count, len, wid;
782  FILE *fp_filter = NULL;
783  char *recycler = NULL;
784 
785  char src2[256];
786  mutt_str_copy(src2, src, mutt_str_len(src) + 1);
787  src = src2;
788 
789  prefix[0] = '\0';
790  buflen--; /* save room for the terminal \0 */
791  wlen = ((flags & MUTT_FORMAT_ARROWCURSOR) && C_ArrowCursor) ?
793  0;
794  col += wlen;
795 
796  if ((flags & MUTT_FORMAT_NOFILTER) == 0)
797  {
798  int off = -1;
799 
800  /* Do not consider filters if no pipe at end */
801  int n = mutt_str_len(src);
802  if ((n > 1) && (src[n - 1] == '|'))
803  {
804  /* Scan backwards for backslashes */
805  off = n;
806  while ((off > 0) && (src[off - 2] == '\\'))
807  off--;
808  }
809 
810  /* If number of backslashes is even, the pipe is real. */
811  /* n-off is the number of backslashes. */
812  if ((off > 0) && (((n - off) % 2) == 0))
813  {
814  char srccopy[1024];
815  int i = 0;
816 
817  mutt_debug(LL_DEBUG3, "fmtpipe = %s\n", src);
818 
819  strncpy(srccopy, src, n);
820  srccopy[n - 1] = '\0';
821 
822  /* prepare Buffers */
823  struct Buffer srcbuf = mutt_buffer_make(0);
824  mutt_buffer_addstr(&srcbuf, srccopy);
825  /* note: we are resetting dptr and *reading* from the buffer, so we don't
826  * want to use mutt_buffer_reset(). */
827  mutt_buffer_seek(&srcbuf, 0);
828  struct Buffer word = mutt_buffer_make(0);
829  struct Buffer cmd = mutt_buffer_make(0);
830 
831  /* Iterate expansions across successive arguments */
832  do
833  {
834  /* Extract the command name and copy to command line */
835  mutt_debug(LL_DEBUG3, "fmtpipe +++: %s\n", srcbuf.dptr);
836  if (word.data)
837  *word.data = '\0';
838  mutt_extract_token(&word, &srcbuf, MUTT_TOKEN_NO_FLAGS);
839  mutt_debug(LL_DEBUG3, "fmtpipe %2d: %s\n", i++, word.data);
840  mutt_buffer_addch(&cmd, '\'');
841  mutt_expando_format(tmp, sizeof(tmp), 0, cols, word.data, callback,
842  data, flags | MUTT_FORMAT_NOFILTER);
843  for (char *p = tmp; p && (*p != '\0'); p++)
844  {
845  if (*p == '\'')
846  {
847  /* shell quoting doesn't permit escaping a single quote within
848  * single-quoted material. double-quoting instead will lead
849  * shell variable expansions, so break out of the single-quoted
850  * span, insert a double-quoted single quote, and resume. */
851  mutt_buffer_addstr(&cmd, "'\"'\"'");
852  }
853  else
854  mutt_buffer_addch(&cmd, *p);
855  }
856  mutt_buffer_addch(&cmd, '\'');
857  mutt_buffer_addch(&cmd, ' ');
858  } while (MoreArgs(&srcbuf));
859 
860  mutt_debug(LL_DEBUG3, "fmtpipe > %s\n", cmd.data);
861 
862  col -= wlen; /* reset to passed in value */
863  wptr = buf; /* reset write ptr */
864  pid_t pid = filter_create(cmd.data, NULL, &fp_filter, NULL);
865  if (pid != -1)
866  {
867  int rc;
868 
869  n = fread(buf, 1, buflen /* already decremented */, fp_filter);
870  mutt_file_fclose(&fp_filter);
871  rc = filter_wait(pid);
872  if (rc != 0)
873  mutt_debug(LL_DEBUG1, "format pipe cmd exited code %d\n", rc);
874  if (n > 0)
875  {
876  buf[n] = '\0';
877  while ((n > 0) && ((buf[n - 1] == '\n') || (buf[n - 1] == '\r')))
878  buf[--n] = '\0';
879  mutt_debug(LL_DEBUG5, "fmtpipe < %s\n", buf);
880 
881  /* If the result ends with '%', this indicates that the filter
882  * generated %-tokens that neomutt can expand. Eliminate the '%'
883  * marker and recycle the string through mutt_expando_format().
884  * To literally end with "%", use "%%". */
885  if ((n > 0) && (buf[n - 1] == '%'))
886  {
887  n--;
888  buf[n] = '\0'; /* remove '%' */
889  if ((n > 0) && (buf[n - 1] != '%'))
890  {
891  recycler = mutt_str_dup(buf);
892  if (recycler)
893  {
894  /* buflen is decremented at the start of this function
895  * to save space for the terminal nul char. We can add
896  * it back for the recursive call since the expansion of
897  * format pipes does not try to append a nul itself. */
898  mutt_expando_format(buf, buflen + 1, col, cols, recycler,
899  callback, data, flags);
900  FREE(&recycler);
901  }
902  }
903  }
904  }
905  else
906  {
907  /* read error */
908  mutt_debug(LL_DEBUG1, "error reading from fmtpipe: %s (errno=%d)\n",
909  strerror(errno), errno);
910  *wptr = '\0';
911  }
912  }
913  else
914  {
915  /* Filter failed; erase write buffer */
916  *wptr = '\0';
917  }
918 
919  mutt_buffer_dealloc(&cmd);
920  mutt_buffer_dealloc(&srcbuf);
921  mutt_buffer_dealloc(&word);
922  return;
923  }
924  }
925 
926  while (*src && (wlen < buflen))
927  {
928  if (*src == '%')
929  {
930  if (*++src == '%')
931  {
932  *wptr++ = '%';
933  wlen++;
934  col++;
935  src++;
936  continue;
937  }
938 
939  if (*src == '?')
940  {
941  /* change original %? to new %< notation */
942  /* %?x?y&z? to %<x?y&z> where y and z are nestable */
943  char *p = (char *) src;
944  *p = '<';
945  /* skip over "x" */
946  for (; *p && (*p != '?'); p++)
947  ; // do nothing
948 
949  /* nothing */
950  if (*p == '?')
951  p++;
952  /* fix up the "y&z" section */
953  for (; *p && (*p != '?'); p++)
954  {
955  /* escape '<' and '>' to work inside nested-if */
956  if ((*p == '<') || (*p == '>'))
957  {
958  memmove(p + 2, p, mutt_str_len(p) + 1);
959  *p++ = '\\';
960  *p++ = '\\';
961  }
962  }
963  if (*p == '?')
964  *p = '>';
965  }
966 
967  if (*src == '<')
968  {
969  flags |= MUTT_FORMAT_OPTIONAL;
970  ch = *(++src); /* save the character to switch on */
971  src++;
972  cp = prefix;
973  count = 0;
974  while ((count < sizeof(prefix)) && (*src != '?'))
975  {
976  *cp++ = *src++;
977  count++;
978  }
979  *cp = '\0';
980  }
981  else
982  {
983  flags &= ~MUTT_FORMAT_OPTIONAL;
984 
985  /* eat the format string */
986  cp = prefix;
987  count = 0;
988  while ((count < sizeof(prefix)) && (isdigit((unsigned char) *src) || (*src == '.') ||
989  (*src == '-') || (*src == '=')))
990  {
991  *cp++ = *src++;
992  count++;
993  }
994  *cp = '\0';
995 
996  if (*src == '\0')
997  break; /* bad format */
998 
999  ch = *src++; /* save the character to switch on */
1000  }
1001 
1002  if (flags & MUTT_FORMAT_OPTIONAL)
1003  {
1004  int lrbalance;
1005 
1006  if (*src != '?')
1007  break; /* bad format */
1008  src++;
1009 
1010  /* eat the 'if' part of the string */
1011  cp = if_str;
1012  count = 0;
1013  lrbalance = 1;
1014  while ((lrbalance > 0) && (count < sizeof(if_str)) && *src)
1015  {
1016  if ((src[0] == '%') && (src[1] == '>'))
1017  {
1018  /* This is a padding expando; copy two chars and carry on */
1019  *cp++ = *src++;
1020  *cp++ = *src++;
1021  count += 2;
1022  continue;
1023  }
1024 
1025  if (*src == '\\')
1026  {
1027  src++;
1028  *cp++ = *src++;
1029  }
1030  else if ((src[0] == '%') && (src[1] == '<'))
1031  {
1032  lrbalance++;
1033  }
1034  else if (src[0] == '>')
1035  {
1036  lrbalance--;
1037  }
1038  if (lrbalance == 0)
1039  break;
1040  if ((lrbalance == 1) && (src[0] == '&'))
1041  break;
1042  *cp++ = *src++;
1043  count++;
1044  }
1045  *cp = '\0';
1046 
1047  /* eat the 'else' part of the string (optional) */
1048  if (*src == '&')
1049  src++; /* skip the & */
1050  cp = else_str;
1051  count = 0;
1052  while ((lrbalance > 0) && (count < sizeof(else_str)) && (*src != '\0'))
1053  {
1054  if ((src[0] == '%') && (src[1] == '>'))
1055  {
1056  /* This is a padding expando; copy two chars and carry on */
1057  *cp++ = *src++;
1058  *cp++ = *src++;
1059  count += 2;
1060  continue;
1061  }
1062 
1063  if (*src == '\\')
1064  {
1065  src++;
1066  *cp++ = *src++;
1067  }
1068  else if ((src[0] == '%') && (src[1] == '<'))
1069  {
1070  lrbalance++;
1071  }
1072  else if (src[0] == '>')
1073  {
1074  lrbalance--;
1075  }
1076  if (lrbalance == 0)
1077  break;
1078  if ((lrbalance == 1) && (src[0] == '&'))
1079  break;
1080  *cp++ = *src++;
1081  count++;
1082  }
1083  *cp = '\0';
1084 
1085  if ((*src == '\0'))
1086  break; /* bad format */
1087 
1088  src++; /* move past the trailing '>' (formerly '?') */
1089  }
1090 
1091  /* handle generic cases first */
1092  if ((ch == '>') || (ch == '*'))
1093  {
1094  /* %>X: right justify to EOL, left takes precedence
1095  * %*X: right justify to EOL, right takes precedence */
1096  int soft = ch == '*';
1097  int pl, pw;
1098  pl = mutt_mb_charlen(src, &pw);
1099  if (pl <= 0)
1100  {
1101  pl = 1;
1102  pw = 1;
1103  }
1104 
1105  /* see if there's room to add content, else ignore */
1106  if (((col < cols) && (wlen < buflen)) || soft)
1107  {
1108  int pad;
1109 
1110  /* get contents after padding */
1111  mutt_expando_format(tmp, sizeof(tmp), 0, cols, src + pl, callback, data, flags);
1112  len = mutt_str_len(tmp);
1113  wid = mutt_strwidth(tmp);
1114 
1115  pad = (cols - col - wid) / pw;
1116  if (pad >= 0)
1117  {
1118  /* try to consume as many columns as we can, if we don't have
1119  * memory for that, use as much memory as possible */
1120  if (wlen + (pad * pl) + len > buflen)
1121  pad = (buflen > (wlen + len)) ? ((buflen - wlen - len) / pl) : 0;
1122  else
1123  {
1124  /* Add pre-spacing to make multi-column pad characters and
1125  * the contents after padding line up */
1126  while (((col + (pad * pw) + wid) < cols) && ((wlen + (pad * pl) + len) < buflen))
1127  {
1128  *wptr++ = ' ';
1129  wlen++;
1130  col++;
1131  }
1132  }
1133  while (pad-- > 0)
1134  {
1135  memcpy(wptr, src, pl);
1136  wptr += pl;
1137  wlen += pl;
1138  col += pw;
1139  }
1140  }
1141  else if (soft)
1142  {
1143  int offset = ((flags & MUTT_FORMAT_ARROWCURSOR) && C_ArrowCursor) ?
1145  0;
1146  int avail_cols = (cols > offset) ? (cols - offset) : 0;
1147  /* \0-terminate buf for length computation in mutt_wstr_trunc() */
1148  *wptr = '\0';
1149  /* make sure right part is at most as wide as display */
1150  len = mutt_wstr_trunc(tmp, buflen, avail_cols, &wid);
1151  /* truncate left so that right part fits completely in */
1152  wlen = mutt_wstr_trunc(buf, buflen - len, avail_cols - wid, &col);
1153  wptr = buf + wlen;
1154  /* Multi-column characters may be truncated in the middle.
1155  * Add spacing so the right hand side lines up. */
1156  while (((col + wid) < avail_cols) && ((wlen + len) < buflen))
1157  {
1158  *wptr++ = ' ';
1159  wlen++;
1160  col++;
1161  }
1162  }
1163  if ((len + wlen) > buflen)
1164  len = mutt_wstr_trunc(tmp, buflen - wlen, cols - col, NULL);
1165  memcpy(wptr, tmp, len);
1166  wptr += len;
1167  }
1168  break; /* skip rest of input */
1169  }
1170  else if (ch == '|')
1171  {
1172  /* pad to EOL */
1173  int pl, pw;
1174  pl = mutt_mb_charlen(src, &pw);
1175  if (pl <= 0)
1176  {
1177  pl = 1;
1178  pw = 1;
1179  }
1180 
1181  /* see if there's room to add content, else ignore */
1182  if ((col < cols) && (wlen < buflen))
1183  {
1184  int c = (cols - col) / pw;
1185  if ((c > 0) && ((wlen + (c * pl)) > buflen))
1186  c = ((signed) (buflen - wlen)) / pl;
1187  while (c > 0)
1188  {
1189  memcpy(wptr, src, pl);
1190  wptr += pl;
1191  wlen += pl;
1192  col += pw;
1193  c--;
1194  }
1195  }
1196  break; /* skip rest of input */
1197  }
1198  else
1199  {
1200  bool to_lower = false;
1201  bool no_dots = false;
1202 
1203  while ((ch == '_') || (ch == ':'))
1204  {
1205  if (ch == '_')
1206  to_lower = true;
1207  else if (ch == ':')
1208  no_dots = true;
1209 
1210  ch = *src++;
1211  }
1212 
1213  /* use callback function to handle this case */
1214  *tmp = '\0';
1215  src = callback(tmp, sizeof(tmp), col, cols, ch, src, prefix, if_str,
1216  else_str, data, flags);
1217 
1218  if (to_lower)
1219  mutt_str_lower(tmp);
1220  if (no_dots)
1221  {
1222  char *p = tmp;
1223  for (; *p; p++)
1224  if (*p == '.')
1225  *p = '_';
1226  }
1227 
1228  len = mutt_str_len(tmp);
1229  if ((len + wlen) > buflen)
1230  len = mutt_wstr_trunc(tmp, buflen - wlen, cols - col, NULL);
1231 
1232  memcpy(wptr, tmp, len);
1233  wptr += len;
1234  wlen += len;
1235  col += mutt_strwidth(tmp);
1236  }
1237  }
1238  else if (*src == '\\')
1239  {
1240  if (!*++src)
1241  break;
1242  switch (*src)
1243  {
1244  case 'f':
1245  *wptr = '\f';
1246  break;
1247  case 'n':
1248  *wptr = '\n';
1249  break;
1250  case 'r':
1251  *wptr = '\r';
1252  break;
1253  case 't':
1254  *wptr = '\t';
1255  break;
1256  case 'v':
1257  *wptr = '\v';
1258  break;
1259  default:
1260  *wptr = *src;
1261  break;
1262  }
1263  src++;
1264  wptr++;
1265  wlen++;
1266  col++;
1267  }
1268  else
1269  {
1270  int bytes, width;
1271  /* in case of error, simply copy byte */
1272  bytes = mutt_mb_charlen(src, &width);
1273  if (bytes < 0)
1274  {
1275  bytes = 1;
1276  width = 1;
1277  }
1278  if ((bytes > 0) && ((wlen + bytes) < buflen))
1279  {
1280  memcpy(wptr, src, bytes);
1281  wptr += bytes;
1282  src += bytes;
1283  wlen += bytes;
1284  col += width;
1285  }
1286  else
1287  {
1288  src += buflen - wlen;
1289  wlen = buflen;
1290  }
1291  }
1292  }
1293  *wptr = '\0';
1294 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_expand_path()

char* mutt_expand_path ( char *  buf,
size_t  buflen 
)

Create the canonical path.

Parameters
bufBuffer with path
buflenLength of buffer
Return values
ptrThe expanded string
Note
The path is expanded in-place

Definition at line 128 of file muttlib.c.

129 {
130  return mutt_expand_path_regex(buf, buflen, false);
131 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_expand_path_regex()

char* mutt_expand_path_regex ( char *  buf,
size_t  buflen,
bool  regex 
)

Create the canonical path (with regex char escaping)

Parameters
bufBuffer with path
buflenLength of buffer
regexIf true, escape any regex characters
Return values
ptrThe expanded string
Note
The path is expanded in-place

Definition at line 337 of file muttlib.c.

338 {
339  struct Buffer *tmp = mutt_buffer_pool_get();
340 
341  mutt_buffer_addstr(tmp, NONULL(buf));
342  mutt_buffer_expand_path_regex(tmp, regex);
343  mutt_str_copy(buf, mutt_buffer_string(tmp), buflen);
344 
346 
347  return buf;
348 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_gecos_name()

char* mutt_gecos_name ( char *  dest,
size_t  destlen,
struct passwd *  pw 
)

Lookup a user's real name in /etc/passwd.

Parameters
destBuffer for the result
destlenLength of buffer
pwPasswd entry
Return values
ptrResult buffer on success

Extract the real name from /etc/passwd's GECOS field. When set, honor the regular expression in $gecos_mask, otherwise assume that the GECOS field is a comma-separated list. Replace "&" by a capitalized version of the user's login name.

Definition at line 362 of file muttlib.c.

363 {
364  regmatch_t pat_match[1];
365  size_t pwnl;
366  char *p = NULL;
367 
368  if (!pw || !pw->pw_gecos)
369  return NULL;
370 
371  memset(dest, 0, destlen);
372 
373  if (mutt_regex_capture(C_GecosMask, pw->pw_gecos, 1, pat_match))
374  {
375  mutt_str_copy(dest, pw->pw_gecos + pat_match[0].rm_so,
376  MIN(pat_match[0].rm_eo - pat_match[0].rm_so + 1, destlen));
377  }
378  else if ((p = strchr(pw->pw_gecos, ',')))
379  mutt_str_copy(dest, pw->pw_gecos, MIN(destlen, p - pw->pw_gecos + 1));
380  else
381  mutt_str_copy(dest, pw->pw_gecos, destlen);
382 
383  pwnl = strlen(pw->pw_name);
384 
385  for (int idx = 0; dest[idx]; idx++)
386  {
387  if (dest[idx] == '&')
388  {
389  memmove(&dest[idx + pwnl], &dest[idx + 1],
390  MAX((ssize_t)(destlen - idx - pwnl - 1), 0));
391  memcpy(&dest[idx], pw->pw_name, MIN(destlen - idx - 1, pwnl));
392  dest[idx] = toupper((unsigned char) dest[idx]);
393  }
394  }
395 
396  return dest;
397 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_get_parent_path()

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

Find the parent of a path (or mailbox)

Parameters
pathPath to use
bufBuffer for the result
buflenLength of buffer

Definition at line 1540 of file muttlib.c.

1541 {
1542  enum MailboxType mb_type = mx_path_probe(path);
1543 
1544  if (mb_type == MUTT_IMAP)
1545  imap_get_parent_path(path, buf, buflen);
1546  else if (mb_type == MUTT_NOTMUCH)
1547  mutt_str_copy(buf, C_Folder, buflen);
1548  else
1549  {
1550  mutt_str_copy(buf, path, buflen);
1551  int n = mutt_str_len(buf);
1552  if (n == 0)
1553  return;
1554 
1555  /* remove any final trailing '/' */
1556  if (buf[n - 1] == '/')
1557  buf[n - 1] = '\0';
1558 
1559  /* Remove everything until the next slash */
1560  for (n--; ((n >= 0) && (buf[n] != '/')); n--)
1561  ; // do nothing
1562 
1563  if (n > 0)
1564  buf[n] = '\0';
1565  else
1566  {
1567  buf[0] = '/';
1568  buf[1] = '\0';
1569  }
1570  }
1571 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_inbox_cmp()

int mutt_inbox_cmp ( const char *  a,
const char *  b 
)

do two folders share the same path and one is an inbox

Parameters
aFirst path
bSecond path
Return values
-1if a is INBOX of b
0if none is INBOX
1if b is INBOX for a

This function compares two folder paths. It first looks for the position of the last common '/' character. If a valid position is found and it's not the last character in any of the two paths, the remaining parts of the paths are compared (case insensitively) with the string "INBOX". If one of the two paths matches, it's reported as being less than the other and the function returns -1 (a < b) or 1 (a > b). If no paths match the requirements, the two paths are considered equivalent and this function returns 0.

Examples:

  • mutt_inbox_cmp("/foo/bar", "/foo/baz") --> 0
  • mutt_inbox_cmp("/foo/bar/", "/foo/bar/inbox") --> 0
  • mutt_inbox_cmp("/foo/bar/sent", "/foo/bar/inbox") --> 1
  • mutt_inbox_cmp("=INBOX", "=Drafts") --> -1

Definition at line 1595 of file muttlib.c.

1596 {
1597  /* fast-track in case the paths have been mutt_pretty_mailbox'ified */
1598  if ((a[0] == '+') && (b[0] == '+'))
1599  {
1600  return mutt_istr_equal(a + 1, "inbox") ? -1 :
1601  mutt_istr_equal(b + 1, "inbox") ? 1 :
1602  0;
1603  }
1604 
1605  const char *a_end = strrchr(a, '/');
1606  const char *b_end = strrchr(b, '/');
1607 
1608  /* If one path contains a '/', but not the other */
1609  if ((!a_end) ^ (!b_end))
1610  return 0;
1611 
1612  /* If neither path contains a '/' */
1613  if (!a_end)
1614  return 0;
1615 
1616  /* Compare the subpaths */
1617  size_t a_len = a_end - a;
1618  size_t b_len = b_end - b;
1619  size_t min = MIN(a_len, b_len);
1620  int same = (a[min] == '/') && (b[min] == '/') && (a[min + 1] != '\0') &&
1621  (b[min + 1] != '\0') && mutt_istrn_equal(a, b, min);
1622 
1623  if (!same)
1624  return 0;
1625 
1626  if (mutt_istr_equal(&a[min + 1], "inbox"))
1627  return -1;
1628 
1629  if (mutt_istr_equal(&b[min + 1], "inbox"))
1630  return 1;
1631 
1632  return 0;
1633 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_text_part()

bool mutt_is_text_part ( struct Body b)

Is this part of an email in plain text?

Parameters
bPart of an email
Return values
trueIf part is in plain text

Definition at line 433 of file muttlib.c.

434 {
435  int t = b->type;
436  char *s = b->subtype;
437 
439  return false;
440 
441  if (t == TYPE_TEXT)
442  return true;
443 
444  if (t == TYPE_MESSAGE)
445  {
446  if (mutt_istr_equal("delivery-status", s))
447  return true;
448  }
449 
450  if (((WithCrypto & APPLICATION_PGP) != 0) && (t == TYPE_APPLICATION))
451  {
452  if (mutt_istr_equal("pgp-keys", s))
453  return true;
454  }
455 
456  return false;
457 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_make_version()

const char* mutt_make_version ( void  )

Generate the NeoMutt version string.

Return values
ptrVersion string
Note
This returns a pointer to a static buffer

Definition at line 1462 of file muttlib.c.

1463 {
1464  static char vstring[256];
1465  snprintf(vstring, sizeof(vstring), "NeoMutt %s%s", PACKAGE_VERSION, GitVer);
1466  return vstring;
1467 }

◆ mutt_mktemp_full()

void mutt_mktemp_full ( char *  buf,
size_t  buflen,
const char *  prefix,
const char *  suffix,
const char *  src,
int  line 
)

Create a temporary filename.

Parameters
bufBuffer for result
buflenLength of buffer
prefixPrefix for filename
suffixSuffix for filename
srcSource file of caller
lineSource line number of caller
Note
This doesn't create the file, only the name

Definition at line 494 of file muttlib.c.

496 {
497  size_t n =
498  snprintf(buf, buflen, "%s/%s-%s-%d-%d-%" PRIu64 "%s%s", NONULL(C_Tmpdir),
499  NONULL(prefix), NONULL(ShortHostname), (int) getuid(),
500  (int) getpid(), mutt_rand64(), suffix ? "." : "", NONULL(suffix));
501  if (n >= buflen)
502  {
504  "%s:%d: ERROR: insufficient buffer space to hold temporary "
505  "filename! buflen=%zu but need %zu\n",
506  src, line, buflen, n);
507  }
508  mutt_debug(LL_DEBUG3, "%s:%d: mutt_mktemp returns \"%s\"\n", src, line, buf);
509  if ((unlink(buf) != 0) && (errno != ENOENT))
510  {
511  mutt_debug(LL_DEBUG1, "%s:%d: ERROR: unlink(\"%s\"): %s (errno %d)\n", src,
512  line, buf, strerror(errno), errno);
513  }
514 }
+ Here is the call graph for this function:

◆ mutt_needs_mailcap()

bool mutt_needs_mailcap ( struct Body m)

Does this type need a mailcap entry do display.

Parameters
mAttachment body to be displayed
Return values
trueNeoMutt requires a mailcap entry to display
falseotherwise

Definition at line 405 of file muttlib.c.

406 {
407  switch (m->type)
408  {
409  case TYPE_TEXT:
410  if (mutt_istr_equal("plain", m->subtype))
411  return false;
412  break;
413  case TYPE_APPLICATION:
415  return false;
417  return false;
418  break;
419 
420  case TYPE_MULTIPART:
421  case TYPE_MESSAGE:
422  return false;
423  }
424 
425  return true;
426 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_open_read()

FILE* mutt_open_read ( const char *  path,
pid_t *  thepid 
)

Run a command to read from.

Parameters
[in]pathPath to command
[out]thepidPID of the command
Return values
ptrFile containing output of command

This function allows the user to specify a command to read stdout from in place of a normal file. If the last character in the string is a pipe (|), then we assume it is a command to run instead of a normal file.

Definition at line 1306 of file muttlib.c.

1307 {
1308  FILE *fp = NULL;
1309  struct stat s;
1310 
1311  size_t len = mutt_str_len(path);
1312  if (len == 0)
1313  {
1314  return NULL;
1315  }
1316 
1317  if (path[len - 1] == '|')
1318  {
1319  /* read from a pipe */
1320 
1321  char *p = mutt_str_dup(path);
1322 
1323  p[len - 1] = 0;
1324  mutt_endwin();
1325  *thepid = filter_create(p, NULL, &fp, NULL);
1326  FREE(&p);
1327  }
1328  else
1329  {
1330  if (stat(path, &s) < 0)
1331  return NULL;
1332  if (S_ISDIR(s.st_mode))
1333  {
1334  errno = EINVAL;
1335  return NULL;
1336  }
1337  fp = fopen(path, "r");
1338  *thepid = -1;
1339  }
1340  return fp;
1341 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_pretty_mailbox()

void mutt_pretty_mailbox ( char *  buf,
size_t  buflen 
)

Shorten a mailbox path using '~' or '='.

Parameters
bufBuffer containing string to shorten
buflenLength of buffer

Collapse the pathname using ~ or = when possible

Definition at line 523 of file muttlib.c.

524 {
525  if (!buf)
526  return;
527 
528  char *p = buf, *q = buf;
529  size_t len;
530  enum UrlScheme scheme;
531  char tmp[PATH_MAX];
532 
533  scheme = url_check_scheme(buf);
534 
535  if ((scheme == U_IMAP) || (scheme == U_IMAPS))
536  {
537  imap_pretty_mailbox(buf, buflen, C_Folder);
538  return;
539  }
540 
541  if (scheme == U_NOTMUCH)
542  return;
543 
544  /* if buf is an url, only collapse path component */
545  if (scheme != U_UNKNOWN)
546  {
547  p = strchr(buf, ':') + 1;
548  if (mutt_strn_equal(p, "//", 2))
549  q = strchr(p + 2, '/');
550  if (!q)
551  q = strchr(p, '\0');
552  p = q;
553  }
554 
555  /* cleanup path */
556  if (strstr(p, "//") || strstr(p, "/./"))
557  {
558  /* first attempt to collapse the pathname, this is more
559  * lightweight than realpath() and doesn't resolve links */
560  while (*p)
561  {
562  if ((p[0] == '/') && (p[1] == '/'))
563  {
564  *q++ = '/';
565  p += 2;
566  }
567  else if ((p[0] == '/') && (p[1] == '.') && (p[2] == '/'))
568  {
569  *q++ = '/';
570  p += 3;
571  }
572  else
573  *q++ = *p++;
574  }
575  *q = '\0';
576  }
577  else if (strstr(p, "..") && ((scheme == U_UNKNOWN) || (scheme == U_FILE)) &&
578  realpath(p, tmp))
579  {
580  mutt_str_copy(p, tmp, buflen - (p - buf));
581  }
582 
583  if ((len = mutt_str_startswith(buf, C_Folder)) && (buf[len] == '/'))
584  {
585  *buf++ = '=';
586  memmove(buf, buf + len, mutt_str_len(buf + len) + 1);
587  }
588  else if ((len = mutt_str_startswith(buf, HomeDir)) && (buf[len] == '/'))
589  {
590  *buf++ = '~';
591  memmove(buf, buf + len - 1, mutt_str_len(buf + len - 1) + 1);
592  }
593 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_safe_path()

void mutt_safe_path ( struct Buffer dest,
const struct Address a 
)

Make a safe filename from an email address.

Parameters
destBuffer for the result
aAddress to use

The filename will be stripped of '/', space, etc to make it safe.

Definition at line 755 of file muttlib.c.

756 {
757  mutt_buffer_save_path(dest, a);
758  for (char *p = dest->data; *p; p++)
759  if ((*p == '/') || IS_SPACE(*p) || !IsPrint((unsigned char) *p))
760  *p = '_';
761 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_confirm()

int mutt_save_confirm ( const char *  s,
struct stat *  st 
)

Ask the user to save.

Parameters
sSave location
stTimestamp
Return values
0if OK to proceed
-1to abort
1to retry

Definition at line 1351 of file muttlib.c.

1352 {
1353  int ret = 0;
1354 
1355  enum MailboxType type = mx_path_probe(s);
1356 
1357 #ifdef USE_POP
1358  if (type == MUTT_POP)
1359  {
1360  mutt_error(_("Can't save message to POP mailbox"));
1361  return 1;
1362  }
1363 #endif
1364 
1365  if ((type != MUTT_MAILBOX_ERROR) && (type != MUTT_UNKNOWN) && (mx_access(s, W_OK) == 0))
1366  {
1367  if (C_ConfirmAppend)
1368  {
1369  struct Buffer *tmp = mutt_buffer_pool_get();
1370  mutt_buffer_printf(tmp, _("Append messages to %s?"), s);
1372  if (ans == MUTT_NO)
1373  ret = 1;
1374  else if (ans == MUTT_ABORT)
1375  ret = -1;
1377  }
1378  }
1379 
1380 #ifdef USE_NNTP
1381  if (type == MUTT_NNTP)
1382  {
1383  mutt_error(_("Can't save message to news server"));
1384  return 0;
1385  }
1386 #endif
1387 
1388  if (stat(s, st) != -1)
1389  {
1390  if (type == MUTT_MAILBOX_ERROR)
1391  {
1392  mutt_error(_("%s is not a mailbox"), s);
1393  return 1;
1394  }
1395  }
1396  else if (type != MUTT_IMAP)
1397  {
1398  st->st_mtime = 0;
1399  st->st_atime = 0;
1400 
1401  /* pathname does not exist */
1402  if (errno == ENOENT)
1403  {
1404  if (C_ConfirmCreate)
1405  {
1406  struct Buffer *tmp = mutt_buffer_pool_get();
1407  mutt_buffer_printf(tmp, _("Create %s?"), s);
1409  if (ans == MUTT_NO)
1410  ret = 1;
1411  else if (ans == MUTT_ABORT)
1412  ret = -1;
1414  }
1415 
1416  /* user confirmed with MUTT_YES or set `$confirm_create` */
1417  if (ret == 0)
1418  {
1419  /* create dir recursively */
1420  char *tmp_path = mutt_path_dirname(s);
1421  if (mutt_file_mkdir(tmp_path, S_IRWXU) == -1)
1422  {
1423  /* report failure & abort */
1424  mutt_perror(s);
1425  FREE(&tmp_path);
1426  return 1;
1427  }
1428  FREE(&tmp_path);
1429  }
1430  }
1431  else
1432  {
1433  mutt_perror(s);
1434  return 1;
1435  }
1436  }
1437 
1439  return ret;
1440 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_save_path()

void mutt_save_path ( char *  buf,
size_t  buflen,
const struct Address addr 
)

Turn an email address into a filename (for saving)

Parameters
bufBuffer for the result
buflenLength of buffer
addrEmail address to use

If the user hasn't set $save_address the name will be truncated to the '@' character.

Definition at line 706 of file muttlib.c.

707 {
708  if (addr && addr->mailbox)
709  {
710  mutt_str_copy(buf, addr->mailbox, buflen);
711  if (!C_SaveAddress)
712  {
713  char *p = strpbrk(buf, "%@");
714  if (p)
715  *p = '\0';
716  }
717  mutt_str_lower(buf);
718  }
719  else
720  *buf = '\0';
721 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sleep()

void mutt_sleep ( short  s)

Sleep for a while.

Parameters
sNumber of seconds to sleep

If the user config '$sleep_time' is larger, sleep that long instead.

Definition at line 1448 of file muttlib.c.

1449 {
1450  if (C_SleepTime > s)
1451  sleep(C_SleepTime);
1452  else if (s)
1453  sleep(s);
1454 }
+ Here is the caller graph for this function:

◆ mutt_str_pretty_size()

void mutt_str_pretty_size ( char *  buf,
size_t  buflen,
size_t  num 
)

Display an abbreviated size, like 3.4K.

Parameters
bufBuffer for the result
buflenLength of the buffer
numNumber to abbreviate

Definition at line 1663 of file muttlib.c.

1664 {
1665  if (!buf || (buflen == 0))
1666  return;
1667 
1668  if (C_SizeShowBytes && (num < 1024))
1669  {
1670  snprintf(buf, buflen, "%d", (int) num);
1671  }
1672  else if (num == 0)
1673  {
1674  mutt_str_copy(buf, C_SizeUnitsOnLeft ? "K0" : "0K", buflen);
1675  }
1676  else if (C_SizeShowFractions && (num < 10189)) /* 0.1K - 9.9K */
1677  {
1678  snprintf(buf, buflen, C_SizeUnitsOnLeft ? "K%3.1f" : "%3.1fK",
1679  (num < 103) ? 0.1 : (num / 1024.0));
1680  }
1681  else if (!C_SizeShowMb || (num < 1023949)) /* 10K - 999K */
1682  {
1683  /* 51 is magic which causes 10189/10240 to be rounded up to 10 */
1684  snprintf(buf, buflen, C_SizeUnitsOnLeft ? ("K%zu") : ("%zuK"), (num + 51) / 1024);
1685  }
1686  else if (C_SizeShowFractions && (num < 10433332)) /* 1.0M - 9.9M */
1687  {
1688  snprintf(buf, buflen, C_SizeUnitsOnLeft ? "M%3.1f" : "%3.1fM", num / 1048576.0);
1689  }
1690  else /* 10M+ */
1691  {
1692  /* (10433332 + 52428) / 1048576 = 10 */
1693  snprintf(buf, buflen, C_SizeUnitsOnLeft ? ("M%zu") : ("%zuM"), (num + 52428) / 1048576);
1694  }
1695 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_to_stailq()

void add_to_stailq ( struct ListHead *  head,
const char *  str 
)

Add a string to a list.

Parameters
headString list
strString to add
Note
Duplicate or empty strings will not be added

Definition at line 1704 of file muttlib.c.

1705 {
1706  /* don't add a NULL or empty string to the list */
1707  if (!str || (*str == '\0'))
1708  return;
1709 
1710  /* check to make sure the item is not already on this list */
1711  struct ListNode *np = NULL;
1712  STAILQ_FOREACH(np, head, entries)
1713  {
1714  if (mutt_istr_equal(str, np->data))
1715  {
1716  return;
1717  }
1718  }
1719  mutt_list_insert_tail(head, mutt_str_dup(str));
1720 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_from_stailq()

void remove_from_stailq ( struct ListHead *  head,
const char *  str 
)

Remove an item, matching a string, from a List.

Parameters
headHead of the List
strString to match
Note
The string comparison is case-insensitive

Definition at line 1729 of file muttlib.c.

1730 {
1731  if (mutt_str_equal("*", str))
1732  mutt_list_free(head); /* "unCMD *" means delete all current entries */
1733  else
1734  {
1735  struct ListNode *np = NULL, *tmp = NULL;
1736  STAILQ_FOREACH_SAFE(np, head, entries, tmp)
1737  {
1738  if (mutt_istr_equal(str, np->data))
1739  {
1740  STAILQ_REMOVE(head, np, ListNode, entries);
1741  FREE(&np->data);
1742  FREE(&np);
1743  break;
1744  }
1745  }
1746  }
1747 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_GecosMask

struct Regex* C_GecosMask

Config: Regex for parsing GECOS field of /etc/passwd.

Definition at line 70 of file muttlib.c.

mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
QuadOption
QuadOption
Possible values for a quad-option.
Definition: quad.h:36
mx_access
int mx_access(const char *path, int flags)
Wrapper for access, checks permissions on a given mailbox.
Definition: mx.c:189
U_IMAP
@ U_IMAP
Url is imap://.
Definition: url.h:38
pad
static int pad(FILE *fp, int col, int i)
Write some padding to a file.
Definition: help.c:198
MessageWindow
struct MuttWindow * MessageWindow
Message Window, ":set", etc.
Definition: mutt_window.c:47
C_SizeUnitsOnLeft
WHERE bool C_SizeUnitsOnLeft
Config: Show the units as a prefix to the size.
Definition: mutt_globals.h:163
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
imap_pretty_mailbox
void imap_pretty_mailbox(char *path, size_t pathlen, const char *folder)
Prettify an IMAP mailbox name.
Definition: util.c:590
APPLICATION_SMIME
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
mutt_strn_equal
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:593
MoreArgs
#define MoreArgs(buf)
Definition: buffer.h:40
ListNode
A List node for strings.
Definition: list.h:34
Buffer
String manipulation buffer.
Definition: buffer.h:33
LL_DEBUG3
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
mutt_file_sanitize_filename
void mutt_file_sanitize_filename(char *path, bool slash)
Replace unsafe characters in a filename.
Definition: file.c:618
mutt_buffer_seek
void mutt_buffer_seek(struct Buffer *buf, size_t offset)
set current read/write position to offset from beginning
Definition: buffer.c:466
STAILQ_REMOVE
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:399
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
mutt_buffer_dealloc
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
url_check_scheme
enum UrlScheme url_check_scheme(const char *str)
Check the protocol of a URL.
Definition: url.c:221
C_SleepTime
WHERE short C_SleepTime
Config: Time to pause after certain info messages.
Definition: mutt_globals.h:114
MUTT_FORMAT_ARROWCURSOR
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
MUTT_ICONV_NO_FLAGS
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:73
mutt_window_clearline
void mutt_window_clearline(struct MuttWindow *win, int row)
Clear a row of a Window.
Definition: mutt_window.c:232
UrlScheme
UrlScheme
All recognised Url types.
Definition: url.h:32
U_UNKNOWN
@ U_UNKNOWN
Url wasn't recognised.
Definition: url.h:34
MUTT_POP
@ MUTT_POP
'POP3' Mailbox type
Definition: mailbox.h:55
mutt_file_sanitize_regex
int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
Escape any regex-magic characters in a string.
Definition: file.c:637
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
mutt_multi_choice
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:937
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
mutt_strwidth
int mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:1363
FREE
#define FREE(x)
Definition: memory.h:40
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
mutt_buffer_mktemp_pfx_sfx
#define mutt_buffer_mktemp_pfx_sfx(buf, prefix, suffix)
Definition: muttlib.h:78
MUTT_TOKEN_NO_FLAGS
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:70
U_FILE
@ U_FILE
Url is file://.
Definition: url.h:35
Buffer::dptr
char * dptr
Current read/write position.
Definition: buffer.h:36
Email::path
char * path
Path of Email (for local Mailboxes)
Definition: email.h:92
MUTT_MAILBOX_ERROR
@ MUTT_MAILBOX_ERROR
Error occurred examining Mailbox.
Definition: mailbox.h:46
Buffer::dsize
size_t dsize
Length of data.
Definition: buffer.h:37
mutt_regex_capture
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
match a regex against a string, with provided options
Definition: regex.c:595
LL_DEBUG5
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
PATH_MAX
#define PATH_MAX
Definition: mutt.h:44
MUTT_ABORT
@ MUTT_ABORT
User aborted the question (with Ctrl-G)
Definition: quad.h:38
mutt_ch_convert_string
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:754
mutt_buffer_reset
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
mutt_expand_path_regex
char * mutt_expand_path_regex(char *buf, size_t buflen, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:337
mx_path_probe
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1335
email_new
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
Body::subtype
char * subtype
content-type subtype
Definition: body.h:37
mutt_list_insert_tail
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
filename_safe_chars
const char filename_safe_chars[]
Definition: file.c:61
mutt_buffer_alloc
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
imap_get_parent_path
void imap_get_parent_path(const char *path, char *buf, size_t buflen)
Get the path of the parent folder.
Definition: util.c:163
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_str_equal
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
C_SaveAddress
WHERE bool C_SaveAddress
Config: Use sender's full address as a default save folder.
Definition: mutt_globals.h:157
mutt_buffer_expand_path_regex
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:140
MUTT_FILE
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
mutt_extract_token
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:393
filter_create
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
mutt_buffer_addch
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
mutt_path_basename
const char * mutt_path_basename(const char *f)
Find the last component for a pathname.
Definition: path.c:329
mutt_is_application_pgp
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:554
mutt_buffer_save_path
void mutt_buffer_save_path(struct Buffer *dest, const struct Address *a)
Make a safe filename from an email address.
Definition: muttlib.c:728
MUTT_NNTP
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:52
mutt_buffer_copy
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:445
C_Folder
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: mutt_globals.h:96
APPLICATION_PGP
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
LastFolder
WHERE char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:55
C_SizeShowMb
WHERE bool C_SizeShowMb
Config: Show sizes in megabytes for sizes greater than 1 megabyte.
Definition: mutt_globals.h:162
MUTT_UNKNOWN
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:47
MAX
#define MAX(a, b)
Definition: memory.h:30
U_IMAPS
@ U_IMAPS
Url is imaps://.
Definition: url.h:39
C_ArrowCursor
WHERE bool C_ArrowCursor
Config: Use an arrow '->' instead of highlighting in the index.
Definition: mutt_globals.h:131
MUTT_NOTMUCH
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:54
MUTT_IMAP
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:53
mutt_default_save
void mutt_default_save(char *path, size_t pathlen, struct Email *e)
Find the default save path for an email.
Definition: hook.c:655
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
TYPE_MESSAGE
@ TYPE_MESSAGE
Type: 'message/*'.
Definition: mime.h:35
mutt_buffer_concat_path
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
MUTT_SAVE_APPEND
@ MUTT_SAVE_APPEND
Append to existing file.
Definition: mutt_attach.h:57
mutt_rand64
uint64_t mutt_rand64(void)
Create a 64-bit random number.
Definition: random.c:129
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
MUTT_NO
@ MUTT_NO
User answered 'No', or assume 'No'.
Definition: quad.h:39
C_Tmpdir
char * C_Tmpdir
Config: Directory for temporary files.
Definition: file.c:56
C_SizeShowFractions
WHERE bool C_SizeShowFractions
Config: Show size fractions with a single decimal place.
Definition: mutt_globals.h:161
mutt_buffer_get_field
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:260
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
STAILQ_FOREACH_SAFE
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:359
C_GecosMask
struct Regex * C_GecosMask
Config: Regex for parsing GECOS field of /etc/passwd.
Definition: muttlib.c:70
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
mutt_str_lower
char * mutt_str_lower(char *str)
Convert all characters in the string to lowercase.
Definition: string.c:504
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
filter_wait
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
MUTT_FORMAT_OPTIONAL
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
WithCrypto
#define WithCrypto
Definition: lib.h:123
IsPrint
#define IsPrint(ch)
Definition: mbyte.h:39
C_Record
WHERE char * C_Record
Config: Folder to save 'sent' messages.
Definition: mutt_globals.h:98
C_SizeShowBytes
WHERE bool C_SizeShowBytes
Config: Show smaller sizes in bytes.
Definition: mutt_globals.h:160
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
mutt_file_mkdir
int mutt_file_mkdir(const char *path, mode_t mode)
Recursively create directories.
Definition: file.c:875
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
TYPE_APPLICATION
@ TYPE_APPLICATION
Type: 'application/*'.
Definition: mime.h:33
HomeDir
char * HomeDir
User's home directory.
Definition: mutt_globals.h:49
mutt_expando_format
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:774
mutt_wstr_trunc
size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
Work out how to truncate a widechar string.
Definition: curs_lib.c:1313
mutt_mb_charlen
int mutt_mb_charlen(const char *s, int *width)
Count the bytes in a (multibyte) character.
Definition: mbyte.c:55
ShortHostname
WHERE char * ShortHostname
Short version of the hostname.
Definition: mutt_globals.h:50
TYPE_TEXT
@ TYPE_TEXT
Type: 'text/*'.
Definition: mime.h:38
alias_lookup
struct AddressList * alias_lookup(const char *name)
Find an Alias.
Definition: alias.c:276
MUTT_SAVE_NO_FLAGS
@ MUTT_SAVE_NO_FLAGS
No flags set.
Definition: mutt_attach.h:56
mutt_buffer_fix_dptr
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
C_SpoolFile
WHERE char * C_SpoolFile
Config: Inbox.
Definition: mutt_globals.h:108
Body::type
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
C_Mbox
WHERE char * C_Mbox
Config: Folder that receives read emails (see Move)
Definition: mutt_globals.h:94
imap_path_probe
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2372
U_NOTMUCH
@ U_NOTMUCH
Url is notmuch://.
Definition: url.h:45
ListNode::data
char * data
String.
Definition: list.h:36
MailboxType
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
MUTT_CLEAR
#define MUTT_CLEAR
Clear input if printable character is pressed.
Definition: mutt.h:62
CurrentFolder
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
C_ArrowString
WHERE char * C_ArrowString
Config: Use an custom string for arrow_cursor.
Definition: mutt_globals.h:132
email_free
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:43
mutt_buffer_addstr
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
mutt_istrn_equal
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:621
GitVer
const char * GitVer
MUTT_SAVE_OVERWRITE
@ MUTT_SAVE_OVERWRITE
Overwrite existing file.
Definition: mutt_attach.h:58
C_Charset
char * C_Charset
Config: Default character set for displaying text on screen.
Definition: charset.c:53
mutt_yesorno
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:380
Buffer::data
char * data
Pointer to data.
Definition: buffer.h:35
IS_SPACE
#define IS_SPACE(ch)
Definition: string2.h:38
TYPE_MULTIPART
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
Email
The envelope/body of an email.
Definition: email.h:37
mutt_str_startswith
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:160
mutt_buffer_printf
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
MUTT_FORMAT_NOFILTER
#define MUTT_FORMAT_NOFILTER
Do not allow filtering on this pass.
Definition: format_flags.h:37
mutt_addrlist_copy
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
C_ConfirmAppend
WHERE bool C_ConfirmAppend
Config: Confirm before appending emails to a mailbox.
Definition: mutt_globals.h:141
mutt_buffer_make
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
mutt_list_free
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
C_ConfirmCreate
WHERE bool C_ConfirmCreate
Config: Confirm before creating a new mailbox.
Definition: mutt_globals.h:142
mutt_buffer_strcpy
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
mutt_is_application_smime
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:612
mutt_pretty_mailbox
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:523
imap_expand_path
int imap_expand_path(struct Buffer *buf)
Buffer wrapper around imap_path_canon()
Definition: imap.c:2412
idx
size_t idx
Definition: mailbox.c:234
MIN
#define MIN(a, b)
Definition: memory.h:31
mutt_error
#define mutt_error(...)
Definition: logging.h:84
mutt_path_dirname
char * mutt_path_dirname(const char *path)
Return a path up to, but not including, the final '/'.
Definition: path.c:376
mutt_str_copy
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